Exemplo n.º 1
0
        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);
            }
        }
Exemplo n.º 2
0
        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;
            }
        }