void Update() { // Find and add/remove paged node children int addedCount = 0, removedCount = 0; System.IntPtr sys = GlobalOsgInterface.takeNewlyAddedNodes(rootNodeID, ref addedCount); System.IntPtr sys2 = GlobalOsgInterface.takeNewlyRemovedNodes(rootNodeID, ref removedCount); GameObject parentObj = null; if (addedCount > 0) { int[] addedNodes = new int[addedCount * 2]; Marshal.Copy(sys, addedNodes, 0, addedCount * 2); for (int i = 0; i < addedNodes.Length; i += 2) { bool ok = GlobalOsgInterface.beginReadPagedNode(addedNodes[i], addedNodes[i + 1]); if (ok) { GameObject childObj = new GameObject("PagedLevel_" + addedNodes[i + 1]); if (pagedNodeMap.TryGetValue(addedNodes[i], out parentObj)) { childObj.transform.SetParent(parentObj.transform, false); } IterateNodeData(childObj, 0); GlobalOsgInterface.endReadNode(eraseLowLevelGeometry); PagedChildID pagedID = childObj.AddComponent <PagedChildID>(); pagedID.parentID = addedNodes[i]; pagedID.location = addedNodes[i + 1]; } else { Debug.LogWarning("[MeshLoader] Failed to read paged node data " + addedNodes[i] + ":" + addedNodes[i + 1]); } } } if (removedCount > 0) { int[] removedNodes = new int[removedCount * 2]; Marshal.Copy(sys2, removedNodes, 0, removedCount * 2); for (int i = 0; i < removedNodes.Length; i += 2) { if (pagedNodeMap.TryGetValue(removedNodes[i], out parentObj)) { foreach (Transform child in parentObj.transform) { PagedChildID pagedID = child.GetComponent <PagedChildID>(); if (pagedID != null && pagedID.location == removedNodes[i + 1]) { // Clear child pagedNodeMap DestroyChildPagedNodes(child, ref pagedNodeMap); // Remove me MeshFilter[] filters = child.GetComponentsInChildren <MeshFilter>(); if (filters.Length > 0) { foreach (MeshFilter mf in filters) { Destroy(mf.sharedMesh); } } Destroy(child.gameObject); } } } else { Debug.LogWarning("[MeshLoader] Failed to remove unregistered paged data: " + removedNodes[i] + ":" + removedNodes[i + 1]); } } } // Traverse all paged nodes and update their LOD stats List <int> nodeToRemove = new List <int>(); foreach (KeyValuePair <int, GameObject> entry in pagedNodeMap) { int locationCount = 0; GameObject pagedNode = entry.Value; System.IntPtr sysState = GlobalOsgInterface.updatePagedNodeState(entry.Key, ref locationCount); if (sysState == System.IntPtr.Zero || locationCount == 0) { continue; } else if (locationCount == -2) { nodeToRemove.Add(entry.Key); continue; } else if (locationCount == -1) { Debug.LogWarning("Unable to get paged information from " + pagedNode.name); continue; } int[] locArray = new int[locationCount]; Marshal.Copy(sysState, locArray, 0, locationCount); List <int> locations = new List <int>(locArray); foreach (Transform child in pagedNode.transform) { PagedChildID idObj = child.GetComponent <PagedChildID>(); if (idObj != null && locations.Contains(idObj.location)) { child.gameObject.SetActive(true); } else { child.gameObject.SetActive(false); } } } foreach (int key in nodeToRemove) { pagedNodeMap.Remove(key); } }
private void IterateNodeData(GameObject obj, int subID) { if (useHierarchicalTransforms) { float[] pos = new float[3], quat = new float[4], scale = new float[3]; GlobalOsgInterface.readNodeLocalTransformDecomposition(subID, posToCopy, quatToCopy, scaleToCopy); Marshal.Copy(posToCopy, pos, 0, 3); Marshal.Copy(quatToCopy, quat, 0, 4); Marshal.Copy(scaleToCopy, scale, 0, 3); obj.transform.localPosition = new Vector3(pos[0], pos[1], -pos[2]); // RH to LH obj.transform.localRotation = new Quaternion(quat[0], quat[1], -quat[2], -quat[3]); // RH to LH obj.transform.localScale = new Vector3(scale[0], scale[1], scale[2]); } GlobalOsgInterface.NodeType type = GlobalOsgInterface.NodeType.InvalidNode; string nodeName = Marshal.PtrToStringAnsi(GlobalOsgInterface.readNodeNameAndType(subID, ref type)); if (nodeName != null && nodeName.Length > 0) { obj.name = nodeName; } switch (type) { case GlobalOsgInterface.NodeType.GeometryNode: { int meshCount = 0; System.IntPtr sys2 = GlobalOsgInterface.readMeshes(subID, ref meshCount); int[] meshes = new int[meshCount]; Marshal.Copy(sys2, meshes, 0, meshCount); if (meshCount == 0) { break; } List <Material> materials = new List <Material>(); Dictionary <string, int> materialSharedMap = new Dictionary <string, int>(); CombineInstance[] meshDataList = new CombineInstance[meshCount]; for (int i = 0; i < meshCount; ++i) { // Create new mesh and find assoicated texture name string texName = ""; meshDataList[i].mesh = CreateMesh(meshes[i], ref texName); // Use existing texture index if meet the same filename if (materialSharedMap.ContainsKey(texName)) { meshDataList[i].subMeshIndex = materialSharedMap[texName]; } else { // Create a new material for new texture Material newMat = new Material(standardMaterial); newMat.mainTexture = CreateTexture(meshes[i], texName); // Add the new index to the shared map meshDataList[i].subMeshIndex = materials.Count; materialSharedMap[texName] = materials.Count; materials.Add(newMat); } } #if false // TODO: combining mesh is of no use here... Mesh totalGeometry = (meshCount > 1) ? new Mesh() : meshDataList[0].mesh; if (meshCount > 1) { totalGeometry.name = "Mesh_" + subID; totalGeometry.CombineMeshes(meshDataList, true, false); } AttachMeshRenderer(obj, totalGeometry, ref materials); #else if (meshCount > 1) { foreach (CombineInstance ci in meshDataList) { GameObject meshObj = new GameObject("SubMesh_" + ci.subMeshIndex); meshObj.transform.SetParent(obj.transform, false); List <Material> subMaterials = new List <Material>(); subMaterials.Add(materials[ci.subMeshIndex]); AttachMeshRenderer(meshObj, ci.mesh, ref subMaterials); } } else if (meshCount == 1) { AttachMeshRenderer(obj, meshDataList[0].mesh, ref materials); } #endif } break; case GlobalOsgInterface.NodeType.GroupNode: case GlobalOsgInterface.NodeType.PagedLodNode: { int childrenCount = 0, globalID = GlobalOsgInterface.readNodeGlobalID(subID); if (globalID > 0) { pagedNodeMap[globalID] = obj; } System.IntPtr sys2 = GlobalOsgInterface.readNodeChildren(subID, ref childrenCount); int[] children = new int[childrenCount]; Marshal.Copy(sys2, children, 0, childrenCount); for (int i = 0; i < childrenCount; ++i) { GameObject childObj = new GameObject( type == GlobalOsgInterface.NodeType.PagedLodNode ? "RoughLevel_" + i : "Node_" + i); childObj.transform.SetParent(obj.transform, false); IterateNodeData(childObj, children[i]); if (type == GlobalOsgInterface.NodeType.PagedLodNode) { PagedChildID pagedID = childObj.AddComponent <PagedChildID>(); pagedID.parentID = globalID; pagedID.location = i; } } } break; default: Debug.LogWarning("[MeshLoader] Unsupported node type " + type); break; } }