| 4611 | } |
| 4612 | |
| 4613 | Result CloneNode(HScene scene, HNode node, HNode* out_node) |
| 4614 | { |
| 4615 | uint16_t index = AllocateNode(scene); |
| 4616 | if (index == scene->m_NodePool.Capacity()) |
| 4617 | { |
| 4618 | dmLogError("Could not create the node since the buffer is full (%d).", scene->m_NodePool.Capacity()); |
| 4619 | return RESULT_OUT_OF_RESOURCES; |
| 4620 | } |
| 4621 | uint16_t version = scene->m_NextVersionNumber; |
| 4622 | if (version == 0) |
| 4623 | { |
| 4624 | // We can't use zero in order to avoid a handle == 0 |
| 4625 | ++version; |
| 4626 | } |
| 4627 | *out_node = ((uint32_t) version) << 16 | index; |
| 4628 | InternalNode* out_n = &scene->m_Nodes[index]; |
| 4629 | memset(out_n, 0, sizeof(InternalNode)); |
| 4630 | |
| 4631 | // generate a name for the cloned node |
| 4632 | char name[18]; |
| 4633 | dmSnPrintf(name, 18, "__node%d", g_ClonedNodeCount++); |
| 4634 | |
| 4635 | InternalNode* n = GetNode(scene, node); |
| 4636 | out_n->m_Node = n->m_Node; |
| 4637 | out_n->m_Node.m_HasResetPoint = 0; |
| 4638 | out_n->m_Node.m_ResetPointProperties = 0; |
| 4639 | ResetTextLayout(&out_n->m_Node.m_TextLayout); |
| 4640 | if (n->m_Node.m_Text != 0x0) |
| 4641 | out_n->m_Node.m_Text = strdup(n->m_Node.m_Text); |
| 4642 | |
| 4643 | // Handle render constants - clone them if callback is available and source has them |
| 4644 | if (n->m_Node.m_RenderConstants && scene->m_CloneRenderConstantsCallback) |
| 4645 | { |
| 4646 | out_n->m_Node.m_RenderConstants = scene->m_CloneRenderConstantsCallback(n->m_Node.m_RenderConstants); |
| 4647 | out_n->m_Node.m_RenderConstantsHash = n->m_Node.m_RenderConstantsHash; |
| 4648 | } |
| 4649 | else |
| 4650 | { |
| 4651 | out_n->m_Node.m_RenderConstants = 0x0; |
| 4652 | out_n->m_Node.m_RenderConstantsHash = 0; |
| 4653 | } |
| 4654 | out_n->m_NameHash = dmHashString64(name); |
| 4655 | out_n->m_Version = version; |
| 4656 | out_n->m_Index = index; |
| 4657 | out_n->m_SceneTraversalCacheVersion = INVALID_INDEX; |
| 4658 | out_n->m_PrevIndex = INVALID_INDEX; |
| 4659 | out_n->m_NextIndex = INVALID_INDEX; |
| 4660 | out_n->m_ParentIndex = INVALID_INDEX; |
| 4661 | out_n->m_ChildHead = INVALID_INDEX; |
| 4662 | out_n->m_ChildTail = INVALID_INDEX; |
| 4663 | scene->m_NextVersionNumber = (version + 1) % ((1 << 16) - 1); |
| 4664 | |
| 4665 | if (n->m_Node.m_CustomType != 0) |
| 4666 | { |
| 4667 | void* src_custom_data = n->m_Node.m_CustomData; |
| 4668 | out_n->m_Node.m_CustomData = scene->m_CloneCustomNodeCallback(scene->m_CreateCustomNodeCallbackContext, scene, *out_node, n->m_Node.m_CustomType, src_custom_data); |
| 4669 | out_n->m_Node.m_CustomType = n->m_Node.m_CustomType; |
| 4670 | } |