Scene nodes now persist their order.

Implemented error handling and insertion logic for KRContext::createNode
Refactored KRNode::m_childNodes to be a std::list rather than a std::set
Added stub function, KRNode::createNode, which accepts a KrCreateNodeInfo structure
This commit is contained in:
2022-09-22 22:32:17 -07:00
parent 6c8bf9fa2c
commit ec65e788e0
8 changed files with 131 additions and 32 deletions

View File

@@ -753,19 +753,71 @@ KrResult KRContext::deleteNodeChildren(const KrDeleteNodeChildrenInfo* pDeleteNo
KrResult KRContext::createNode(const KrCreateNodeInfo* pCreateNodeInfo) KrResult KRContext::createNode(const KrCreateNodeInfo* pCreateNodeInfo)
{ {
if (pCreateNodeInfo->sceneHandle < 0 || pCreateNodeInfo->sceneHandle >= m_resourceMapSize) {
return KR_ERROR_OUT_OF_BOUNDS;
}
KRResource* sceneResource = m_resourceMap[pCreateNodeInfo->sceneHandle];
if (sceneResource == nullptr) {
return KR_ERROR_NOT_MAPPED;
}
KRScene* scene = dynamic_cast<KRScene*>(sceneResource);
if (scene == nullptr) {
return KR_ERROR_INCORRECT_TYPE;
}
if (pCreateNodeInfo->newNodeHandle < 0 || pCreateNodeInfo->newNodeHandle >= m_nodeMapSize) { if (pCreateNodeInfo->newNodeHandle < 0 || pCreateNodeInfo->newNodeHandle >= m_nodeMapSize) {
return KR_ERROR_OUT_OF_BOUNDS; return KR_ERROR_OUT_OF_BOUNDS;
} }
if (pCreateNodeInfo->relativeNodeHandle < 0 || pCreateNodeInfo->relativeNodeHandle >= m_nodeMapSize) { if (pCreateNodeInfo->relativeNodeHandle < 0 || pCreateNodeInfo->relativeNodeHandle >= m_nodeMapSize) {
return KR_ERROR_OUT_OF_BOUNDS; return KR_ERROR_OUT_OF_BOUNDS;
} }
if (pCreateNodeInfo->location < 0 || pCreateNodeInfo->location >= KR_SCENE_NODE_INSERT_MAX_ENUM) {
return KR_ERROR_OUT_OF_BOUNDS;
}
KRNode* relativeNode = nullptr; KRNode* relativeNode = nullptr;
if (pCreateNodeInfo->relativeNodeHandle != KR_NULL_HANDLE) { if (pCreateNodeInfo->relativeNodeHandle == KR_NULL_HANDLE) {
relativeNode = scene->getRootNode();
} else {
// TODO - Handle node deletions by deleting nodes from m_nodeMap // TODO - Handle node deletions by deleting nodes from m_nodeMap
relativeNode = m_nodeMap[pCreateNodeInfo->relativeNodeHandle]; relativeNode = m_nodeMap[pCreateNodeInfo->relativeNodeHandle];
if (relativeNode == nullptr) {
return KR_ERROR_NOT_FOUND;
}
} }
return KR_ERROR_NOT_IMPLEMENTED; if (pCreateNodeInfo->location == KR_SCENE_NODE_INSERT_BEFORE ||
pCreateNodeInfo->location == KR_SCENE_NODE_INSERT_AFTER) {
// There can only be one root node
if (relativeNode->getParent() == nullptr) {
return KR_ERROR_UNEXPECTED;
}
}
KRNode* newNode = nullptr;
KrResult res = KRNode::createNode(pCreateNodeInfo, &newNode);
if (res != KR_SUCCESS) {
return res;
}
if (relativeNode) {
switch (pCreateNodeInfo->location) {
case KR_SCENE_NODE_INSERT_BEFORE:
relativeNode->insertBefore(newNode);
break;
case KR_SCENE_NODE_INSERT_AFTER:
relativeNode->insertAfter(newNode);
break;
case KR_SCENE_NODE_PREPEND_CHILD:
relativeNode->prependChild(newNode);
break;
case KR_SCENE_NODE_APPEND_CHILD:
relativeNode->appendChild(newNode);
break;
default:
assert(false);
return KR_ERROR_NOT_IMPLEMENTED;
}
}
return KR_SUCCESS;
} }
KrResult KRContext::updateNode(const KrUpdateNodeInfo* pUpdateNodeInfo) KrResult KRContext::updateNode(const KrUpdateNodeInfo* pUpdateNodeInfo)

View File

@@ -75,7 +75,7 @@ void KRLODSet::updateLODVisibility(const KRViewport& viewport)
*/ */
// Upgrade and downgrade LOD groups as needed // Upgrade and downgrade LOD groups as needed
for (std::set<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { for (std::list<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRLODGroup* lod_group = dynamic_cast<KRLODGroup*>(*itr); KRLODGroup* lod_group = dynamic_cast<KRLODGroup*>(*itr);
assert(lod_group != NULL); assert(lod_group != NULL);
LodVisibility group_lod_visibility = KRMIN(lod_group->calcLODVisibility(viewport), m_lod_visible); LodVisibility group_lod_visibility = KRMIN(lod_group->calcLODVisibility(viewport), m_lod_visible);
@@ -101,7 +101,7 @@ void KRLODSet::updateLODVisibility(const KRViewport& viewport)
if (streamer_ready) { if (streamer_ready) {
// Upgrade and downgrade LOD groups as needed // Upgrade and downgrade LOD groups as needed
for (std::set<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { for (std::list<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRLODGroup* lod_group = dynamic_cast<KRLODGroup*>(*itr); KRLODGroup* lod_group = dynamic_cast<KRLODGroup*>(*itr);
assert(lod_group != NULL); assert(lod_group != NULL);
LodVisibility group_lod_visibility = KRMIN(lod_group->calcLODVisibility(viewport), m_lod_visible); LodVisibility group_lod_visibility = KRMIN(lod_group->calcLODVisibility(viewport), m_lod_visible);
@@ -131,7 +131,7 @@ kraken_stream_level KRLODSet::getStreamLevel(const KRViewport& viewport)
KRLODGroup* new_active_lod_group = NULL; KRLODGroup* new_active_lod_group = NULL;
// Upgrade and downgrade LOD groups as needed // Upgrade and downgrade LOD groups as needed
for (std::set<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { for (std::list<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRLODGroup* lod_group = dynamic_cast<KRLODGroup*>(*itr); KRLODGroup* lod_group = dynamic_cast<KRLODGroup*>(*itr);
assert(lod_group != NULL); assert(lod_group != NULL);
if (lod_group->calcLODVisibility(viewport) == LOD_VISIBILITY_VISIBLE) { if (lod_group->calcLODVisibility(viewport) == LOD_VISIBILITY_VISIBLE) {

View File

@@ -145,16 +145,52 @@ bool KRNode::getScaleCompensation()
void KRNode::childDeleted(KRNode* child_node) void KRNode::childDeleted(KRNode* child_node)
{ {
m_childNodes.erase(child_node); // TODO - We should give KRNode's linked list pointers directly and eliminate m_childNodes so that we don't need
// to perform slow std::find operations like this one.
// TODO - FIXME - This is a slow operation...
std::list<KRNode*>::iterator itr = std::find(m_childNodes.begin(), m_childNodes.end(), child_node);
if (itr != m_childNodes.end()) {
m_childNodes.erase(itr);
}
invalidateBounds(); invalidateBounds();
getScene().notify_sceneGraphModify(this); getScene().notify_sceneGraphModify(this);
} }
void KRNode::addChild(KRNode* child) void KRNode::appendChild(KRNode* child)
{ {
assert(child->m_parentNode == NULL); assert(child->m_parentNode == NULL);
child->m_parentNode = this; child->m_parentNode = this;
m_childNodes.insert(child); m_childNodes.push_back(child);
child->setLODVisibility(m_lod_visible); // Child node inherits LOD visibility status from parent
}
void KRNode::prependChild(KRNode* child)
{
assert(child->m_parentNode == NULL);
child->m_parentNode = this;
m_childNodes.push_front(child);
child->setLODVisibility(m_lod_visible); // Child node inherits LOD visibility status from parent
}
void KRNode::insertBefore(KRNode* child)
{
assert(m_parentNode != NULL); // There can only be one root node
assert(child->m_parentNode == NULL);
child->m_parentNode = m_parentNode;
std::list<KRNode*>::iterator itr = std::find(m_parentNode->m_childNodes.begin(), m_parentNode->m_childNodes.end(), this);
assert(itr != m_parentNode->m_childNodes.end());
m_parentNode->m_childNodes.insert(itr, child);
child->setLODVisibility(m_lod_visible); // Child node inherits LOD visibility status from parent
}
void KRNode::insertAfter(KRNode* child)
{
assert(m_parentNode != NULL); // There can only be one root node
assert(child->m_parentNode == NULL);
child->m_parentNode = m_parentNode;
std::list<KRNode*>::iterator itr = std::find(m_parentNode->m_childNodes.begin(), m_parentNode->m_childNodes.end(), this);
assert(itr != m_parentNode->m_childNodes.end());
itr++;
m_parentNode->m_childNodes.insert(itr, child);
child->setLODVisibility(m_lod_visible); // Child node inherits LOD visibility status from parent child->setLODVisibility(m_lod_visible); // Child node inherits LOD visibility status from parent
} }
@@ -174,13 +210,18 @@ tinyxml2::XMLElement* KRNode::saveXML(tinyxml2::XMLNode* parent)
kraken::setXMLAttribute("pre_rotate", e, (m_preRotation * (180.0f / (float)M_PI)), Vector3::Zero()); kraken::setXMLAttribute("pre_rotate", e, (m_preRotation * (180.0f / (float)M_PI)), Vector3::Zero());
kraken::setXMLAttribute("post_rotate", e, (m_postRotation * (180.0f / (float)M_PI)), Vector3::Zero()); kraken::setXMLAttribute("post_rotate", e, (m_postRotation * (180.0f / (float)M_PI)), Vector3::Zero());
for (std::set<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { for (std::list<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRNode* child = (*itr); KRNode* child = (*itr);
child->saveXML(n); child->saveXML(n);
} }
return e; return e;
} }
KrResult KRNode::createNode(const KrCreateNodeInfo* pCreateNodeInfo, KRNode** node)
{
return KR_ERROR_NOT_IMPLEMENTED;
}
void KRNode::loadXML(tinyxml2::XMLElement* e) void KRNode::loadXML(tinyxml2::XMLElement* e)
{ {
m_name = e->Attribute("name"); m_name = e->Attribute("name");
@@ -227,7 +268,7 @@ void KRNode::loadXML(tinyxml2::XMLElement* e)
KRNode* child_node = KRNode::LoadXML(getScene(), child_element); KRNode* child_node = KRNode::LoadXML(getScene(), child_element);
if (child_node) { if (child_node) {
addChild(child_node); appendChild(child_node);
} }
} }
} }
@@ -515,7 +556,7 @@ void KRNode::render(const RenderInfo& ri)
m_lastRenderFrame = getContext().getCurrentFrame(); m_lastRenderFrame = getContext().getCurrentFrame();
} }
const std::set<KRNode*>& KRNode::getChildren() const std::list<KRNode*>& KRNode::getChildren()
{ {
return m_childNodes; return m_childNodes;
} }
@@ -541,7 +582,7 @@ AABB KRNode::getBounds()
AABB bounds = AABB::Zero(); AABB bounds = AABB::Zero();
bool first_child = true; bool first_child = true;
for (std::set<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { for (std::list<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRNode* child = (*itr); KRNode* child = (*itr);
if (child->getBounds() != AABB::Zero()) { if (child->getBounds() != AABB::Zero()) {
if (first_child) { if (first_child) {
@@ -564,7 +605,7 @@ void KRNode::invalidateModelMatrix()
m_modelMatrixValid = false; m_modelMatrixValid = false;
m_activePoseMatrixValid = false; m_activePoseMatrixValid = false;
m_inverseModelMatrixValid = false; m_inverseModelMatrixValid = false;
for (std::set<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { for (std::list<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRNode* child = (*itr); KRNode* child = (*itr);
child->invalidateModelMatrix(); child->invalidateModelMatrix();
} }
@@ -577,7 +618,7 @@ void KRNode::invalidateBindPoseMatrix()
{ {
m_bindPoseMatrixValid = false; m_bindPoseMatrixValid = false;
m_inverseBindPoseMatrixValid = false; m_inverseBindPoseMatrixValid = false;
for (std::set<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { for (std::list<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRNode* child = (*itr); KRNode* child = (*itr);
child->invalidateBindPoseMatrix(); child->invalidateBindPoseMatrix();
} }
@@ -956,7 +997,7 @@ void KRNode::addToOctreeNode(KROctreeNode* octree_node)
void KRNode::updateLODVisibility(const KRViewport& viewport) void KRNode::updateLODVisibility(const KRViewport& viewport)
{ {
if (m_lod_visible >= LOD_VISIBILITY_PRESTREAM) { if (m_lod_visible >= LOD_VISIBILITY_PRESTREAM) {
for (std::set<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { for (std::list<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
(*itr)->updateLODVisibility(viewport); (*itr)->updateLODVisibility(viewport);
} }
} }
@@ -973,7 +1014,7 @@ void KRNode::setLODVisibility(KRNode::LodVisibility lod_visibility)
m_lod_visible = lod_visibility; m_lod_visible = lod_visibility;
for (std::set<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { for (std::list<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
(*itr)->setLODVisibility(lod_visibility); (*itr)->setLODVisibility(lod_visibility);
} }
} }
@@ -1010,7 +1051,7 @@ kraken_stream_level KRNode::getStreamLevel(const KRViewport& viewport)
{ {
kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ; kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ;
for (std::set<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { for (std::list<KRNode*>::iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
stream_level = KRMIN(stream_level, (*itr)->getStreamLevel(viewport)); stream_level = KRMIN(stream_level, (*itr)->getStreamLevel(viewport));
} }

View File

@@ -115,13 +115,17 @@ public:
virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent); virtual tinyxml2::XMLElement* saveXML(tinyxml2::XMLNode* parent);
static KRNode* LoadXML(KRScene& scene, tinyxml2::XMLElement* e); static KRNode* LoadXML(KRScene& scene, tinyxml2::XMLElement* e);
static KrResult createNode(const KrCreateNodeInfo* pCreateNodeInfo, KRNode** node);
virtual void loadXML(tinyxml2::XMLElement* e); virtual void loadXML(tinyxml2::XMLElement* e);
virtual std::string getElementName(); virtual std::string getElementName();
const std::string& getName() const; const std::string& getName() const;
void addChild(KRNode* child); void appendChild(KRNode* child);
const std::set<KRNode*>& getChildren(); void prependChild(KRNode* child);
void insertBefore(KRNode* child);
void insertAfter(KRNode* child);
const std::list<KRNode*>& getChildren();
KRNode* getParent(); KRNode* getParent();
void setLocalTranslation(const Vector3& v, bool set_original = false); void setLocalTranslation(const Vector3& v, bool set_original = false);
@@ -262,7 +266,7 @@ protected:
LodVisibility m_lod_visible; LodVisibility m_lod_visible;
KRNode* m_parentNode; KRNode* m_parentNode;
std::set<KRNode*> m_childNodes; std::list<KRNode*> m_childNodes;
bool m_animation_mask[KRENGINE_NODE_ATTRIBUTE_COUNT]; bool m_animation_mask[KRENGINE_NODE_ATTRIBUTE_COUNT];
@@ -319,7 +323,7 @@ public:
return match; return match;
} }
for (std::set<KRNode*>::const_iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { for (std::list<KRNode*>::const_iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
match = (*itr)->find<T>(); match = (*itr)->find<T>();
if (match) { if (match) {
return match; return match;
@@ -338,7 +342,7 @@ public:
} }
} }
for (std::set<KRNode*>::const_iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { for (std::list<KRNode*>::const_iterator itr = m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
match = (*itr)->find<T>(name); match = (*itr)->find<T>(name);
if (match) { if (match) {
return match; return match;

View File

@@ -966,7 +966,7 @@ void LoadNode(FbxScene* pFbxScene, KRNode* parent_node, FbxGeometryConverter* pG
} }
KRLODSet* lod_set = new KRLODSet(parent_node->getScene(), name); KRLODSet* lod_set = new KRLODSet(parent_node->getScene(), name);
parent_node->addChild(lod_set); parent_node->appendChild(lod_set);
AABB reference_bounds; AABB reference_bounds;
// Create a lod_group node for each fbx child node // Create a lod_group node for each fbx child node
@@ -1026,7 +1026,7 @@ void LoadNode(FbxScene* pFbxScene, KRNode* parent_node, FbxGeometryConverter* pG
new_node->setPostRotation(node_post_rotation); new_node->setPostRotation(node_post_rotation);
new_node->setUseWorldUnits(use_world_space_units); new_node->setUseWorldUnits(use_world_space_units);
lod_set->addChild(new_node); lod_set->appendChild(new_node);
LoadNode(pFbxScene, new_node, pGeometryConverter, pNode->GetChild(i)); LoadNode(pFbxScene, new_node, pGeometryConverter, pNode->GetChild(i));
@@ -1087,7 +1087,7 @@ void LoadNode(FbxScene* pFbxScene, KRNode* parent_node, FbxGeometryConverter* pG
new_node->setScalingPivot(node_scaling_pivot); new_node->setScalingPivot(node_scaling_pivot);
new_node->setPreRotation(node_pre_rotation); new_node->setPreRotation(node_pre_rotation);
new_node->setPostRotation(node_post_rotation); new_node->setPostRotation(node_post_rotation);
parent_node->addChild(new_node); parent_node->appendChild(new_node);
// Load child nodes // Load child nodes
for (int i = 0; i < pNode->GetChildCount(); i++) { for (int i = 0; i < pNode->GetChildCount(); i++) {

View File

@@ -62,7 +62,7 @@ void KRScene::renderFrame(VkCommandBuffer& commandBuffer, KRSurface& surface, fl
if (camera == NULL) { if (camera == NULL) {
// Add a default camera if none are present // Add a default camera if none are present
camera = new KRCamera(*this, "default_camera"); camera = new KRCamera(*this, "default_camera");
m_pRootNode->addChild(camera); m_pRootNode->appendChild(camera);
} }
// FINDME - This should be moved to de-couple Siren from the Rendering pipeline // FINDME - This should be moved to de-couple Siren from the Rendering pipeline
@@ -409,7 +409,7 @@ KRScene* KRScene::Load(KRContext& context, const std::string& name, KRDataBlock*
KRNode* n = KRNode::LoadXML(*new_scene, scene_element->FirstChildElement()); KRNode* n = KRNode::LoadXML(*new_scene, scene_element->FirstChildElement());
if (n) { if (n) {
new_scene->getRootNode()->addChild(n); new_scene->getRootNode()->appendChild(n);
} }
@@ -554,7 +554,7 @@ void KRScene::addDefaultLights()
KRDirectionalLight* light1 = new KRDirectionalLight(*this, "default_light1"); KRDirectionalLight* light1 = new KRDirectionalLight(*this, "default_light1");
light1->setLocalRotation((Quaternion::Create(Vector3::Create(0.0f, (float)M_PI * 0.10f, 0.0f)) * Quaternion::Create(Vector3::Create(0.0f, 0.0f, (float)-M_PI * 0.15f))).eulerXYZ()); light1->setLocalRotation((Quaternion::Create(Vector3::Create(0.0f, (float)M_PI * 0.10f, 0.0f)) * Quaternion::Create(Vector3::Create(0.0f, 0.0f, (float)-M_PI * 0.15f))).eulerXYZ());
m_pRootNode->addChild(light1); m_pRootNode->appendChild(light1);
} }
AABB KRScene::getRootOctreeBounds() AABB KRScene::getRootOctreeBounds()

View File

@@ -109,10 +109,11 @@ typedef enum
typedef enum typedef enum
{ {
KR_SCENE_NODE_INSERT_BEFORE, KR_SCENE_NODE_INSERT_BEFORE = 0,
KR_SCENE_NODE_INSERT_AFTER, KR_SCENE_NODE_INSERT_AFTER,
KR_SCENE_NODE_INSERT_FIRST_CHILD, KR_SCENE_NODE_PREPEND_CHILD,
KR_SCENE_NODE_INSERT_LAST_CHILD, KR_SCENE_NODE_APPEND_CHILD,
KR_SCENE_NODE_INSERT_MAX_ENUM
} KrSceneNodeInsertLocation; } KrSceneNodeInsertLocation;
typedef int KrResourceMapIndex; typedef int KrResourceMapIndex;

View File

@@ -65,7 +65,8 @@ void smoke_load()
KrCreateNodeInfo create_camera_info = { KR_STRUCTURE_TYPE_CREATE_NODE }; KrCreateNodeInfo create_camera_info = { KR_STRUCTURE_TYPE_CREATE_NODE };
res = KrInitNodeInfo(&create_camera_info.node, KR_STRUCTURE_TYPE_NODE_CAMERA); res = KrInitNodeInfo(&create_camera_info.node, KR_STRUCTURE_TYPE_NODE_CAMERA);
assert(res == KR_SUCCESS); assert(res == KR_SUCCESS);
create_camera_info.relativeNodeHandle = -1; create_camera_info.relativeNodeHandle = KR_NULL_HANDLE;
create_camera_info.location = KR_SCENE_NODE_APPEND_CHILD;
create_camera_info.newNodeHandle = kCameraNodeHandle; create_camera_info.newNodeHandle = kCameraNodeHandle;
create_camera_info.sceneHandle = kSceneResourceHandle; create_camera_info.sceneHandle = kSceneResourceHandle;
create_camera_info.node.pName = "my_camera"; create_camera_info.node.pName = "my_camera";