Exemple #1
0
    private static void CalcNodeBoundingBox(RSM.Node node, Mat4 _matrix)
    {
        var   v = new Vector3();
        var   box = node.box;
        var   nodes = node.model.nodes;
        var   vertices = node.vertices;
        float x, y, z;

        //find position
        node.matrix = _matrix.Clone();

        Mat4.Translate(node.matrix, node.matrix, node.pos);

        //dynamic or static model
        if (node.rotKeyframes.Count == 0)
        {
            Mat4.Rotate(node.matrix, node.matrix, node.rotAngle, node.rotAxis);
        }

        Mat4.Scale(node.matrix, node.matrix, node.scale);

        Mat4 matrix = node.matrix.Clone();

        if (!node.isOnly)
        {
            Mat4.Translate(matrix, matrix, node.offset);
        }

        Mat4.Multiply(matrix, matrix, Mat4.FromMat3(node.mat3, null));

        for (int i = 0, count = vertices.Count; i < count; i++)
        {
            x = vertices[i][0];
            y = vertices[i][1];
            z = vertices[i][2];

            v[0] = matrix[0] * x + matrix[4] * y + matrix[8] * z + matrix[12];
            v[1] = matrix[1] * x + matrix[5] * y + matrix[9] * z + matrix[13];
            v[2] = matrix[2] * x + matrix[6] * y + matrix[10] * z + matrix[14];

            for (int j = 0; j < 3; j++)
            {
                box.min[j] = Math.Min(v[j], box.min[j]);
                box.max[j] = Math.Max(v[j], box.max[j]);
            }
        }

        for (int i = 0; i < 3; i++)
        {
            box.offset[i] = (box.max[i] + box.min[i]) / 2.0f;
            box.range[i]  = (box.max[i] - box.min[i]) / 2.0f;
            box.center[i] = box.min[i] + box.range[i];
        }

        for (int i = 0, count = nodes.Length; i < count; i++)
        {
            if (string.Equals(nodes[i].parentName, node.name) && !string.Equals(node.name, node.parentName))
            {
                nodes[i].parent = node;
                node.children.Add(nodes[i]);
                CalcNodeBoundingBox(nodes[i], node.matrix);
            }
        }
    }
Exemple #2
0
    private static RSM.Node LoadNode(RSM rsm, BinaryReader data, double version)
    {
        RSM.Node node = new RSM.Node();

        node.model  = rsm;
        node.isOnly = rsm.nodes.Length == 1;

        node.name       = data.ReadBinaryString(40);
        node.parentName = data.ReadBinaryString(40);

        //read textures
        int textureCount = data.ReadLong();

        node.textures = new long[textureCount];

        for (int i = 0; i < textureCount; i++)
        {
            node.textures[i] = data.ReadLong();
        }

        //read options
        node.mat3 = new Vector3[] {
            new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat()),
            new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat()),
            new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat())
        };

        node.offset   = new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat());
        node.pos      = new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat());
        node.rotAngle = data.ReadFloat();
        node.rotAxis  = new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat());
        node.scale    = new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat());

        //read vertices
        int verticeCount = data.ReadLong();

        node.vertices = new List <Vector3>();
        for (int i = 0; i < verticeCount; i++)
        {
            node.vertices.Add(new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat()));
        }

        //read textures vertices
        int tverticeCount = data.ReadLong();

        node.tVertices = new float[tverticeCount * 6];
        for (int i = 0; i < tverticeCount; i++)
        {
            if (version >= 1.2)
            {
                node.tVertices[(i * 6) + 0] = data.ReadUByte() / 255f;
                node.tVertices[(i * 6) + 1] = data.ReadUByte() / 255f;
                node.tVertices[(i * 6) + 2] = data.ReadUByte() / 255f;
                node.tVertices[(i * 6) + 3] = data.ReadUByte() / 255f;
            }
            node.tVertices[(i * 6) + 4] = data.ReadFloat() * 0.98f + 0.01f;
            node.tVertices[(i * 6) + 5] = data.ReadFloat() * 0.98f + 0.01f;
        }

        //read faces
        int faceCount = data.ReadLong();

        node.faces = new RSM.Face[faceCount];
        for (int i = 0; i < faceCount; i++)
        {
            node.faces[i] = new RSM.Face()
            {
                vertidx     = new Vector3Int(data.ReadUShort(), data.ReadUShort(), data.ReadUShort()),
                tvertidx    = new Vector3Int(data.ReadUShort(), data.ReadUShort(), data.ReadUShort()),
                texid       = data.ReadUShort(),
                padding     = data.ReadUShort(),
                twoSided    = data.ReadLong(),
                smoothGroup = version >= 1.2 ? data.ReadLong() : 0
            };
        }

        //read position keyframes
        if (version >= 1.5)
        {
            int pkfCount = data.ReadLong();
            for (int i = 0; i < pkfCount; i++)
            {
                node.posKeyframes.Add(data.ReadLong(), new Vector3(data.ReadFloat(), data.ReadFloat(), data.ReadFloat()));
            }
        }

        //read rotation keyframes
        int rkfCount = data.ReadLong();

        for (int i = 0; i < rkfCount; i++)
        {
            int        time = data.ReadLong();
            Quaternion quat = new Quaternion(data.ReadFloat(), data.ReadFloat(), data.ReadFloat(), data.ReadFloat());

            if (!node.rotKeyframes.ContainsKey(time))
            {
                //some models have multiple keyframes with the
                //same timestamp, here we just keep the first one
                //and throw out the rest.
                node.rotKeyframes.Add(time, quat);
            }
        }

        node.box = new RSM.Box();

        return(node);
    }
Exemple #3
0
    public void BuildMeshes()
    {
        GameObject parent = new GameObject("_Models");

        parent.transform.parent = MapRenderer.mapParent.transform;
        Dictionary <int, AnimProperties> anims = new Dictionary <int, AnimProperties>();
        int nodeId = 0;

        foreach (RSM.CompiledModel model in models)
        {
            GameObject modelObj = new GameObject(model.rsm.name);
            modelObj.transform.parent = parent.transform;

            foreach (var nodeData in model.nodesData)
            {
                foreach (var meshesByTexture in nodeData)
                {
                    long             textureId = meshesByTexture.Key;
                    RSM.NodeMeshData meshData  = meshesByTexture.Value;
                    RSM.Node         node      = meshData.node;

                    if (meshesByTexture.Value.vertices.Count == 0)
                    {
                        continue;
                    }

                    for (int i = 0; i < meshData.vertices.Count; i += 3)
                    {
                        meshData.triangles.AddRange(new int[] {
                            i + 0, i + 1, i + 2
                        });
                    }

                    //create node unity mesh
                    Mesh mesh = new Mesh();
                    mesh.vertices  = meshData.vertices.ToArray();
                    mesh.triangles = meshData.triangles.ToArray();
                    //mesh.normals = meshData.normals.ToArray();
                    mesh.uv = meshData.uv.ToArray();

                    GameObject nodeObj = new GameObject(node.name);
                    nodeObj.transform.parent = modelObj.transform;

                    string textureFile = model.rsm.textures[textureId];

                    var mf = nodeObj.AddComponent <MeshFilter>();
                    mf.mesh = mesh;
                    var mr = nodeObj.AddComponent <MeshRenderer>();
                    if (meshData.twoSided)
                    {
                        mr.material = material2s;
                        if (textureFile.EndsWith("tga"))
                        {
                            mr.material.shader       = Resources.Load("2SidedAlpha") as Shader;
                            mr.material.renderQueue += 1;
                        }
                    }
                    else
                    {
                        mr.material = material;
                        if (textureFile.EndsWith("tga"))
                        {
                            mr.material.shader       = Resources.Load("ModelShaderAlpha") as Shader;
                            mr.material.renderQueue += 1;
                        }
                    }

                    mr.material.mainTexture = FileManager.Load("data/texture/" + textureFile) as Texture2D;

                    if (model.rsm.shadeType == RSM.SHADING.SMOOTH)
                    {
                        NormalSolver.RecalculateNormals(mf.mesh, 60);
                    }
                    else
                    {
                        mf.mesh.RecalculateNormals();
                    }

                    var matrix = node.GetPositionMatrix();
                    nodeObj.transform.position = matrix.ExtractPosition();
                    var rotation = matrix.ExtractRotation();
                    nodeObj.transform.rotation   = rotation;
                    nodeObj.transform.localScale = matrix.ExtractScale();

                    var properties = nodeObj.AddComponent <NodeProperties>();
                    properties.nodeId     = nodeId;
                    properties.mainName   = model.rsm.mainNode.name;
                    properties.parentName = node.parentName;

                    if (node.posKeyframes.Count > 0 || node.rotKeyframes.Count > 0)
                    {
                        nodeObj.AddComponent <NodeAnimation>().nodeId = nodeId;
                        anims.Add(nodeId, new AnimProperties()
                        {
                            posKeyframes = node.posKeyframes,
                            rotKeyframes = node.rotKeyframes,
                            animLen      = model.rsm.animLen,
                            baseRotation = rotation,
                            isChild      = properties.isChild
                        });
                    }

                    nodeId++;
                }
            }

            modelObj.SetActive(false);

            //instantiate model
            for (int i = 0; i < model.rsm.instances.Count; i++)
            {
                GameObject instanceObj;
                if (i == model.rsm.instances.Count - 1)
                {
                    //last instance
                    instanceObj = modelObj;
                }
                else
                {
                    instanceObj = UnityEngine.Object.Instantiate(modelObj);
                }

                instanceObj.transform.parent = parent.transform;
                instanceObj.name            += "[" + i + "]";

                RSW.ModelDescriptor descriptor = model.rsm.instances[i];

                instanceObj.transform.Rotate(Vector3.forward, -descriptor.rotation[2]);
                instanceObj.transform.Rotate(Vector3.right, -descriptor.rotation[0]);
                instanceObj.transform.Rotate(Vector3.up, descriptor.rotation[1]);

                Vector3 scale = new Vector3(descriptor.scale[0], -descriptor.scale[1], descriptor.scale[2]);
                instanceObj.transform.localScale = scale;

                //avoid z fighting between models
                float xRandom = UnityEngine.Random.Range(-0.002f, 0.002f);
                float yRandom = UnityEngine.Random.Range(-0.002f, 0.002f);
                float zRandom = UnityEngine.Random.Range(-0.002f, 0.002f);

                Vector3 position = new Vector3(descriptor.position[0] + xRandom, descriptor.position[1] + yRandom, descriptor.position[2] + zRandom);
                position.x += MapRenderer.width;
                position.y *= -1;
                position.z += MapRenderer.height;
                instanceObj.transform.position = position;

                //setup hierarchy
                var propertiesComponents = instanceObj.GetComponentsInChildren <NodeProperties>();
                foreach (var properties in propertiesComponents)
                {
                    if (properties.isChild)
                    {
                        var nodeParent = instanceObj.transform.FindRecursive(properties.parentName);
                        properties.transform.parent = nodeParent;
                    }
                }

                //setup animations
                var animComponents = instanceObj.GetComponentsInChildren <NodeAnimation>();
                foreach (var animComponent in animComponents)
                {
                    var properties = anims[animComponent.nodeId];
                    animComponent.Initialize(properties);
                }

                instanceObj.SetActive(true);
            }
        }

        anims.Clear();
    }