Fixed crash on initialization of KRResourceBinding encapsulated in KRNodeProperty by changing default value to an empty string rather than nullptr. Implemented KRNODE_PROPERTY_ARRAY. KRModel meshes are now using KRNODE_PROPERTY_ARRAY
This commit is contained in:
@@ -71,5 +71,5 @@ private:
|
|||||||
KRNODE_PROPERTY(std::string, m_zone, "", "zone");
|
KRNODE_PROPERTY(std::string, m_zone, "", "zone");
|
||||||
KRNODE_PROPERTY(float, m_gradient_distance, 0.25f, "gradient");
|
KRNODE_PROPERTY(float, m_gradient_distance, 0.25f, "gradient");
|
||||||
KRNODE_PROPERTY(float, m_ambient_gain, 1.f, "gain");
|
KRNODE_PROPERTY(float, m_ambient_gain, 1.f, "gain");
|
||||||
KRNODE_PROPERTY(KRAudioSampleBinding, m_ambient, nullptr, "sample");
|
KRNODE_PROPERTY(KRAudioSampleBinding, m_ambient, "", "sample");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ private:
|
|||||||
int m_currentBufferFrame; // Siren Audio Engine frame number within current buffer
|
int m_currentBufferFrame; // Siren Audio Engine frame number within current buffer
|
||||||
void advanceBuffer();
|
void advanceBuffer();
|
||||||
|
|
||||||
KRNODE_PROPERTY(KRAudioSampleBinding, m_sample, nullptr, "sample");
|
KRNODE_PROPERTY(KRAudioSampleBinding, m_sample, "", "sample");
|
||||||
KRNODE_PROPERTY(float, m_gain, 1.f, "gain");
|
KRNODE_PROPERTY(float, m_gain, 1.f, "gain");
|
||||||
KRNODE_PROPERTY(float, m_pitch, 1.f, "pitch");
|
KRNODE_PROPERTY(float, m_pitch, 1.f, "pitch");
|
||||||
KRNODE_PROPERTY(bool, m_looping, false, "looping");
|
KRNODE_PROPERTY(bool, m_looping, false, "looping");
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public:
|
|||||||
void render(RenderInfo& ri) override;
|
void render(RenderInfo& ri) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
KRNODE_PROPERTY(KRMeshBinding, m_model, nullptr, "mesh");
|
KRNODE_PROPERTY(KRMeshBinding, m_model, "", "mesh");
|
||||||
KRNODE_PROPERTY(unsigned int, m_layer_mask, 0xffffffff, "layer_mask");
|
KRNODE_PROPERTY(unsigned int, m_layer_mask, 0xffffffff, "layer_mask");
|
||||||
KRNODE_PROPERTY(float, m_audio_occlusion, 1.f, "audio_occlusion");
|
KRNODE_PROPERTY(float, m_audio_occlusion, 1.f, "audio_occlusion");
|
||||||
|
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ KrResult KRModel::update(const KrNodeInfo* nodeInfo)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_meshes[lod].set(mesh);
|
m_meshes[lod].val.set(mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
return KR_SUCCESS;
|
return KR_SUCCESS;
|
||||||
@@ -128,13 +128,12 @@ void KRModel::loadXML(tinyxml2::XMLElement* e)
|
|||||||
m_receivesShadow.load(e);
|
m_receivesShadow.load(e);
|
||||||
m_rim_power.load(e);
|
m_rim_power.load(e);
|
||||||
m_rim_color.load(e);
|
m_rim_color.load(e);
|
||||||
std::string meshNames[KRModel::kMeshLODCount];
|
|
||||||
|
|
||||||
m_meshes[0].set(e->Attribute("mesh"));
|
m_meshes[0].load(e);
|
||||||
for (int lod = 1; lod < KRModel::kMeshLODCount; lod++) {
|
for (int lod = 1; lod < KRModel::kMeshLODCount; lod++) {
|
||||||
char attribName[8];
|
char attribName[8];
|
||||||
snprintf(attribName, 8, "mesh%i", lod);
|
snprintf(attribName, 8, "mesh%i", lod);
|
||||||
m_meshes[lod].set(e->Attribute(attribName));
|
m_meshes[lod].load(e, attribName);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_lightMap.load(e);
|
m_lightMap.load(e);
|
||||||
@@ -143,11 +142,11 @@ void KRModel::loadXML(tinyxml2::XMLElement* e)
|
|||||||
tinyxml2::XMLElement* KRModel::saveXML(tinyxml2::XMLNode* parent)
|
tinyxml2::XMLElement* KRModel::saveXML(tinyxml2::XMLNode* parent)
|
||||||
{
|
{
|
||||||
tinyxml2::XMLElement* e = KRNode::saveXML(parent);
|
tinyxml2::XMLElement* e = KRNode::saveXML(parent);
|
||||||
e->SetAttribute("mesh", m_meshes[0].getName().c_str());
|
m_meshes[0].load(e);
|
||||||
for (int lod = 1; lod < kMeshLODCount; lod++) {
|
for (int lod = 1; lod < kMeshLODCount; lod++) {
|
||||||
char attribName[8];
|
char attribName[8];
|
||||||
snprintf(attribName, 8, "mesh%i", lod);
|
snprintf(attribName, 8, "mesh%i", lod);
|
||||||
e->SetAttribute(attribName, m_meshes[lod].getName().c_str());
|
m_meshes[lod].load(e, attribName);
|
||||||
}
|
}
|
||||||
m_lightMap.save(e);
|
m_lightMap.save(e);
|
||||||
m_min_lod_coverage.save(e);
|
m_min_lod_coverage.save(e);
|
||||||
@@ -193,13 +192,13 @@ void KRModel::loadModel()
|
|||||||
bool meshChanged = false;
|
bool meshChanged = false;
|
||||||
for (int lod = 0; lod < kMeshLODCount; lod++) {
|
for (int lod = 0; lod < kMeshLODCount; lod++) {
|
||||||
KRMesh* prevMesh = nullptr;
|
KRMesh* prevMesh = nullptr;
|
||||||
prevMesh = m_meshes[lod].get();
|
prevMesh = m_meshes[lod].val.get();
|
||||||
m_meshes[lod].bind(&getContext());
|
m_meshes[lod].val.bind(&getContext());
|
||||||
if (m_meshes[lod].get() != prevMesh) {
|
if (m_meshes[lod].val.get() != prevMesh) {
|
||||||
meshChanged = true;
|
meshChanged = true;
|
||||||
}
|
}
|
||||||
if (m_meshes[lod].isBound()) {
|
if (m_meshes[lod].val.isBound()) {
|
||||||
KRMesh* model = m_meshes[lod].get();
|
KRMesh* model = m_meshes[lod].val.get();
|
||||||
std::vector<KRBone*> model_bones;
|
std::vector<KRBone*> model_bones;
|
||||||
int bone_count = model->getBoneCount();
|
int bone_count = model->getBoneCount();
|
||||||
bool all_bones_found = true;
|
bool all_bones_found = true;
|
||||||
@@ -262,8 +261,8 @@ void KRModel::render(KRNode::RenderInfo& ri)
|
|||||||
int bestLOD = -1;
|
int bestLOD = -1;
|
||||||
KRMesh* pModel = nullptr;
|
KRMesh* pModel = nullptr;
|
||||||
for (int lod = 0; lod < kMeshLODCount; lod++) {
|
for (int lod = 0; lod < kMeshLODCount; lod++) {
|
||||||
if (m_meshes[lod].isBound()) {
|
if (m_meshes[lod].val.isBound()) {
|
||||||
KRMesh* pLODModel = m_meshes[lod].get();
|
KRMesh* pLODModel = m_meshes[lod].val.get();
|
||||||
|
|
||||||
if ((float)pLODModel->getLODCoverage() / 100.0f > lod_coverage) {
|
if ((float)pLODModel->getLODCoverage() / 100.0f > lod_coverage) {
|
||||||
if(bestLOD == -1 || pLODModel->getLODCoverage() < pModel->getLODCoverage()) {
|
if(bestLOD == -1 || pLODModel->getLODCoverage() < pModel->getLODCoverage()) {
|
||||||
@@ -294,7 +293,7 @@ void KRModel::getResourceBindings(std::list<KRResourceBinding*>& bindings)
|
|||||||
KRNode::getResourceBindings(bindings);
|
KRNode::getResourceBindings(bindings);
|
||||||
|
|
||||||
for (int i = 0; i < kMeshLODCount; i++) {
|
for (int i = 0; i < kMeshLODCount; i++) {
|
||||||
bindings.push_back(&m_meshes[i]);
|
bindings.push_back(&m_meshes[i].val);
|
||||||
}
|
}
|
||||||
bindings.push_back(&m_lightMap.val);
|
bindings.push_back(&m_lightMap.val);
|
||||||
}
|
}
|
||||||
@@ -306,8 +305,8 @@ void KRModel::preStream(const KRViewport& viewport, std::list<KRResourceRequest>
|
|||||||
loadModel();
|
loadModel();
|
||||||
|
|
||||||
for (int i = 0; i < kMeshLODCount; i++) {
|
for (int i = 0; i < kMeshLODCount; i++) {
|
||||||
if (m_meshes[i].isBound()) {
|
if (m_meshes[i].val.isBound()) {
|
||||||
m_meshes[i].get()->preStream();
|
m_meshes[i].val.get()->preStream();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -319,8 +318,8 @@ kraken_stream_level KRModel::getStreamLevel(const KRViewport& viewport)
|
|||||||
loadModel();
|
loadModel();
|
||||||
|
|
||||||
for (int lod = 0; lod < kMeshLODCount; lod++) {
|
for (int lod = 0; lod < kMeshLODCount; lod++) {
|
||||||
if (m_meshes[lod].isBound()) {
|
if (m_meshes[lod].val.isBound()) {
|
||||||
stream_level = KRMIN(stream_level, m_meshes[lod].get()->getStreamLevel());
|
stream_level = KRMIN(stream_level, m_meshes[lod].val.get()->getStreamLevel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,10 +332,10 @@ AABB KRModel::getBounds()
|
|||||||
|
|
||||||
// Get the bounds of the lowest lod mesh
|
// Get the bounds of the lowest lod mesh
|
||||||
for(int lod=0; lod<kMeshLODCount; lod++) {
|
for(int lod=0; lod<kMeshLODCount; lod++) {
|
||||||
if (!m_meshes[lod].isBound()) {
|
if (!m_meshes[lod].val.isBound()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
KRMesh* mesh = m_meshes[lod].get();
|
KRMesh* mesh = m_meshes[lod].val.get();
|
||||||
if (m_faces_camera) {
|
if (m_faces_camera) {
|
||||||
AABB normal_bounds = AABB::Create(mesh->getMinPoint(), mesh->getMaxPoint(), getModelMatrix());
|
AABB normal_bounds = AABB::Create(mesh->getMinPoint(), mesh->getMaxPoint(), getModelMatrix());
|
||||||
float max_dimension = normal_bounds.longest_radius();
|
float max_dimension = normal_bounds.longest_radius();
|
||||||
|
|||||||
@@ -80,8 +80,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::array<KRMeshBinding, kMeshLODCount> m_meshes;
|
KRNODE_PROPERTY_ARRAY(KRMeshBinding, m_meshes, "", "mesh", kMeshLODCount);
|
||||||
|
|
||||||
KRNODE_PROPERTY(KRTextureBinding, m_lightMap, KRTexture::TEXTURE_USAGE_LIGHT_MAP, "light_map");
|
KRNODE_PROPERTY(KRTextureBinding, m_lightMap, KRTexture::TEXTURE_USAGE_LIGHT_MAP, "light_map");
|
||||||
KRNODE_PROPERTY(float, m_min_lod_coverage, 0.f, "min_lod_coverage");
|
KRNODE_PROPERTY(float, m_min_lod_coverage, 0.f, "min_lod_coverage");
|
||||||
KRNODE_PROPERTY(bool, m_receivesShadow, true, "receives_shadow");
|
KRNODE_PROPERTY(bool, m_receivesShadow, true, "receives_shadow");
|
||||||
|
|||||||
@@ -96,53 +96,63 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void save(tinyxml2::XMLElement* element) const
|
void save(tinyxml2::XMLElement* element) const
|
||||||
|
{
|
||||||
|
save(element, config::name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void save(tinyxml2::XMLElement* element, const char* attributeName) const
|
||||||
{
|
{
|
||||||
if constexpr (std::is_same<T, bool>::value) {
|
if constexpr (std::is_same<T, bool>::value) {
|
||||||
element->SetAttribute(config::name, val ? "true" : "false");
|
element->SetAttribute(attributeName, val ? "true" : "false");
|
||||||
} else if constexpr (std::is_same<T, hydra::Vector3>::value) {
|
} else if constexpr (std::is_same<T, hydra::Vector3>::value) {
|
||||||
kraken::setXMLAttribute(config::name, element, val, config::defaultVal);
|
kraken::setXMLAttribute(attributeName, element, val, config::defaultVal);
|
||||||
} else if constexpr (std::is_same<T, hydra::AABB>::value) {
|
} else if constexpr (std::is_same<T, hydra::AABB>::value) {
|
||||||
kraken::setXMLAttribute(config::name, element, val, config::defaultVal);
|
kraken::setXMLAttribute(attributeName, element, val, config::defaultVal);
|
||||||
} else if constexpr (std::is_same<T, std::string>::value) {
|
} else if constexpr (std::is_same<T, std::string>::value) {
|
||||||
element->SetAttribute(config::name, val.c_str());
|
element->SetAttribute(attributeName, val.c_str());
|
||||||
} else if constexpr (std::is_base_of<KRResourceBinding, T>::value) {
|
} else if constexpr (std::is_base_of<KRResourceBinding, T>::value) {
|
||||||
element->SetAttribute(config::name, val.getName().c_str());
|
element->SetAttribute(attributeName, val.getName().c_str());
|
||||||
} else {
|
} else {
|
||||||
element->SetAttribute(config::name, val);
|
element->SetAttribute(attributeName, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void load(tinyxml2::XMLElement* element)
|
void load(tinyxml2::XMLElement* element)
|
||||||
|
{
|
||||||
|
load(element, config::name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void load(tinyxml2::XMLElement* element, const char* attributeName)
|
||||||
{
|
{
|
||||||
if constexpr (std::is_same<T, int>::value) {
|
if constexpr (std::is_same<T, int>::value) {
|
||||||
if (element->QueryIntAttribute(config::name, &val) != tinyxml2::XML_SUCCESS) {
|
if (element->QueryIntAttribute(attributeName, &val) != tinyxml2::XML_SUCCESS) {
|
||||||
val = config::defaultVal;
|
val = config::defaultVal;
|
||||||
}
|
}
|
||||||
} else if constexpr (std::is_same<T, unsigned int>::value) {
|
} else if constexpr (std::is_same<T, unsigned int>::value) {
|
||||||
if (element->QueryUnsignedAttribute(config::name, &val) != tinyxml2::XML_SUCCESS) {
|
if (element->QueryUnsignedAttribute(attributeName, &val) != tinyxml2::XML_SUCCESS) {
|
||||||
val = config::defaultVal;
|
val = config::defaultVal;
|
||||||
}
|
}
|
||||||
} else if constexpr (std::is_same<T, float>::value) {
|
} else if constexpr (std::is_same<T, float>::value) {
|
||||||
if (element->QueryFloatAttribute(config::name, &val) != tinyxml2::XML_SUCCESS) {
|
if (element->QueryFloatAttribute(attributeName, &val) != tinyxml2::XML_SUCCESS) {
|
||||||
val = config::defaultVal;
|
val = config::defaultVal;
|
||||||
}
|
}
|
||||||
} else if constexpr (std::is_same<T, bool>::value) {
|
} else if constexpr (std::is_same<T, bool>::value) {
|
||||||
if (element->QueryBoolAttribute(config::name, &val) != tinyxml2::XML_SUCCESS) {
|
if (element->QueryBoolAttribute(attributeName, &val) != tinyxml2::XML_SUCCESS) {
|
||||||
val = config::defaultVal;
|
val = config::defaultVal;
|
||||||
}
|
}
|
||||||
} else if constexpr (std::is_same<T, hydra::Vector3>::value) {
|
} else if constexpr (std::is_same<T, hydra::Vector3>::value) {
|
||||||
val = kraken::getXMLAttribute(config::name, element, config::defaultVal);
|
val = kraken::getXMLAttribute(attributeName, element, config::defaultVal);
|
||||||
} else if constexpr (std::is_same<T, hydra::AABB>::value) {
|
} else if constexpr (std::is_same<T, hydra::AABB>::value) {
|
||||||
val = kraken::getXMLAttribute(config::name, element, config::defaultVal);
|
val = kraken::getXMLAttribute(attributeName, element, config::defaultVal);
|
||||||
} else if constexpr (std::is_same<T, std::string>::value) {
|
} else if constexpr (std::is_same<T, std::string>::value) {
|
||||||
const char* name = element->Attribute(config::name);
|
const char* name = element->Attribute(attributeName);
|
||||||
if (name) {
|
if (name) {
|
||||||
val = name;
|
val = name;
|
||||||
} else {
|
} else {
|
||||||
val = config::defaultVal;
|
val = config::defaultVal;
|
||||||
}
|
}
|
||||||
} else if constexpr (std::is_base_of<KRResourceBinding, T>::value) {
|
} else if constexpr (std::is_base_of<KRResourceBinding, T>::value) {
|
||||||
const char* name = element->Attribute(config::name);
|
const char* name = element->Attribute(attributeName);
|
||||||
if (name) {
|
if (name) {
|
||||||
val.set(name);
|
val.set(name);
|
||||||
} else {
|
} else {
|
||||||
@@ -163,6 +173,13 @@ public:
|
|||||||
}; \
|
}; \
|
||||||
KRNodeProperty<PROP_TYPE, VAR ## _config> VAR;
|
KRNodeProperty<PROP_TYPE, VAR ## _config> VAR;
|
||||||
|
|
||||||
|
#define KRNODE_PROPERTY_ARRAY(PROP_TYPE, VAR, PROP_DEFAULT, PROP_NAME, ARRAY_SIZE) \
|
||||||
|
struct VAR ## _config { \
|
||||||
|
static constexpr decltype(PROP_DEFAULT) defaultVal = PROP_DEFAULT; \
|
||||||
|
static constexpr const char* name = PROP_NAME; \
|
||||||
|
}; \
|
||||||
|
std::array<KRNodeProperty<PROP_TYPE, VAR ## _config>, ARRAY_SIZE> VAR;
|
||||||
|
|
||||||
class KRNode
|
class KRNode
|
||||||
: public KRContextObject
|
: public KRContextObject
|
||||||
, public KRReflectedObject
|
, public KRReflectedObject
|
||||||
|
|||||||
@@ -69,6 +69,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
KRNODE_PROPERTY(std::string, m_zone, "", "zone");
|
KRNODE_PROPERTY(std::string, m_zone, "", "zone");
|
||||||
KRNODE_PROPERTY(float, m_gradient_distance, 0.25f, "gradient");
|
KRNODE_PROPERTY(float, m_gradient_distance, 0.25f, "gradient");
|
||||||
KRNODE_PROPERTY(KRAudioSampleBinding, m_reverb, nullptr, "sample");
|
KRNODE_PROPERTY(KRAudioSampleBinding, m_reverb, "", "sample");
|
||||||
KRNODE_PROPERTY(float, m_reverb_gain, 1.f, "gain");
|
KRNODE_PROPERTY(float, m_reverb_gain, 1.f, "gain");
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user