예제 #1
0
 public GrimMat4x3(GrimVec3 baseX, GrimVec3 baseY, GrimVec3 baseZ, GrimVec3 translation)
 {
     BaseX       = baseX;
     BaseY       = baseY;
     BaseZ       = baseZ;
     Translation = translation;
 }
예제 #2
0
 public GrimModelMeshEntity(GrimModelMeshData meshData, GrimModelBone[] bones, GrimVec3 emissiveColor, bool castShadow)
 {
     MeshData      = meshData;
     Bones         = bones;
     EmissiveColor = emissiveColor;
     CastShadow    = castShadow;
 }
예제 #3
0
 public override void ResetToDefaultParameters()
 {
     BaseX       = new GrimVec3();
     BaseY       = new GrimVec3();
     BaseZ       = new GrimVec3();
     Translation = new GrimVec3();
 }
예제 #4
0
 protected override void DoRead(System.IO.BinaryReader reader)
 {
     BaseX       = new GrimVec3(reader);
     BaseY       = new GrimVec3(reader);
     BaseZ       = new GrimVec3(reader);
     Translation = new GrimVec3(reader);
 }
예제 #5
0
        public void putVertexDataAsVec3Array(GrimVec3[] data)
        {
            if (data == null)
            {
                return;
            }

            DataType      = DataTypeFloat;
            Dim           = 3;
            Stride        = 4 * Dim;
            RawVertexData = new byte[Stride * data.Length];

            MemoryStream memoryStream = new MemoryStream(RawVertexData);
            BinaryWriter binaryWriter = new BinaryWriter(memoryStream);

            for (int i = 0; i < data.Length; i++)
            {
                if (data[i] == null)
                {
                    data[i] = new GrimVec3();
                    //throw new Exception("GrimModelVertexArray: Provided Vec3 array contains a null value.");
                }

                data[i].Write(binaryWriter);
            }
        }
예제 #6
0
 public override void ResetToDefaultParameters()
 {
     MeshData      = null;
     Bones         = null;
     EmissiveColor = new GrimVec3();
     CastShadow    = false;
 }
예제 #7
0
        public static GrimVec3 Cross(GrimVec3 left, GrimVec3 right)
        {
            GrimVec3 returnValue = new GrimVec3();

            returnValue.X = left.Y * right.Z - left.Z * right.Y;
            returnValue.Y = left.Z * right.X - left.X * right.Z;
            returnValue.Z = left.X * right.Y - left.Y * right.X;
            return(returnValue);
        }
예제 #8
0
        protected override void DoRead(System.IO.BinaryReader reader)
        {
            Magic       = new GrimFourCC(reader);
            Version     = reader.ReadInt32();
            NumVertices = reader.ReadInt32();

            if (!Magic.Value.Equals("MESH"))
            {
                throw new Exception("GrimModelMeshData: Invalid FourCC");
            }

            if (NumVertices > 0)
            {
                for (int i = 0; i < VertexArrays.Length; i++)
                {
                    VertexArrays[i] = new GrimModelVertexArray(this, reader);
                }
            }

            int NumIndices = reader.ReadInt32();

            Indices = new UInt32[NumIndices];

            for (int i = 0; i < NumIndices; i++)
            {
                Indices[i] = reader.ReadUInt32();
            }

            int NumSegments = reader.ReadInt32();

            Segments = new GrimModelMeshSegment[NumSegments];

            for (int i = 0; i < NumSegments; i++)
            {
                GrimModelMeshSegment segment = new GrimModelMeshSegment(reader);

                if ((segment.TriCount * 3) > NumIndices)
                {
                    Logger.Instance.Warning("GrimModelMeshData: Too many triangles in this segment, capping to the number of triangles in the mesh.");
                    segment.TriCount = (NumIndices - segment.FirstIndex) / 3;
                }

                Segments[i] = segment;
            }

            BoundCenter = new GrimVec3(reader);
            BoundRadius = reader.ReadSingle();
            BoundMin    = new GrimVec3(reader);
            BoundMax    = new GrimVec3(reader);
        }
예제 #9
0
        protected override void DoRead(System.IO.BinaryReader reader)
        {
            MeshData = new GrimModelMeshData(reader);
            int NumBones = reader.ReadInt32();

            Bones = new GrimModelBone[NumBones];

            for (int i = 0; i < NumBones; i++)
            {
                Bones[i] = new GrimModelBone(reader);
            }

            EmissiveColor = new GrimVec3(reader);
            CastShadow    = (reader.ReadByte() > 0);
        }
예제 #10
0
        public override void ResetToDefaultParameters()
        {
            Magic        = new GrimFourCC("MESH");
            Version      = 2;
            NumVertices  = 0;
            VertexArrays = new GrimModelVertexArray[15];
            Indices      = null;
            Segments     = null;
            BoundCenter  = new GrimVec3();
            BoundRadius  = 0.0f;
            BoundMin     = new GrimVec3();
            BoundMax     = new GrimVec3();

            for (int i = 0; i < VertexArrays.Length; i++)
            {
                VertexArrays[i] = new GrimModelVertexArray(this);
            }
        }
예제 #11
0
        public GrimVec3[] getVertexDataAsVec3Array()
        {
            if (DataType != DataTypeFloat || Dim != 3)
            {
                return(null);
            }

            MemoryStream memoryStream = new MemoryStream(RawVertexData);
            BinaryReader binaryReader = new BinaryReader(memoryStream);

            GrimVec3[] result = new GrimVec3[ParentMeshData.NumVertices];

            for (int i = 0; i < ParentMeshData.NumVertices; i++)
            {
                result[i] = new GrimVec3(binaryReader);
            }

            return(result);
        }
예제 #12
0
 public static float Dot(GrimVec3 left, GrimVec3 right)
 {
     return((left.X * right.X) + (left.Y * right.Y) + (left.Z * right.Z));
 }
예제 #13
0
        /// <summary>
        /// Calculate tangents and bitangents for each vertex in order using the method described at
        /// http://www.terathon.com/code/tangent.html
        /// </summary>
        public void CalculateTangentsAndBitangents()
        {
            GrimModelVertexArray vertexArray = VertexArrays[VERTEX_ARRAY_POSITION];
            GrimModelVertexArray texArray    = VertexArrays[VERTEX_ARRAY_TEXCOORD0];
            GrimModelVertexArray normalArray = VertexArrays[VERTEX_ARRAY_NORMAL];

            float[][]  vertexData = vertexArray.getVertexDataAsFloatArray();
            float[][]  texData    = texArray.getVertexDataAsFloatArray();
            GrimVec3[] normalData = normalArray.getVertexDataAsVec3Array();

            if (vertexData == null || texData == null || normalData == null)
            {
                Logger.Instance.Error("Need position, normal and texture data in existing mesh to calculate tangents.");
                return;
            }

            List <GrimVec3>[] vertexTangents   = new List <GrimVec3> [vertexData.Length];
            List <GrimVec3>[] vertexBitangents = new List <GrimVec3> [vertexData.Length];
            GrimVec3[]        tangentData      = new GrimVec3[vertexData.Length];
            GrimVec3[]        bitangentData    = new GrimVec3[vertexData.Length];

            foreach (GrimModelMeshSegment segment in Segments)
            {
                // Reset all of the values for this segment
                for (int i = 0; i < vertexData.Length; i++)
                {
                    vertexTangents[i]   = new List <GrimVec3>();
                    vertexBitangents[i] = new List <GrimVec3>();
                }

                // Calculate the range of indices we are working with
                int firstIndex = segment.FirstIndex;
                int lastIndex  = firstIndex + segment.TriCount * 3;

                // Go over each triangle in this segment and calculate tangent / bitangent data for the related vertices
                for (int i = firstIndex; i < lastIndex; i += 3)
                {
                    uint[]     triIndices = new uint[] { Indices[i], Indices[i + 1], Indices[i + 2] };
                    GrimVec3[] triVerts   = new GrimVec3[] { new GrimVec3(vertexData[triIndices[0]]), new GrimVec3(vertexData[triIndices[1]]), new GrimVec3(vertexData[triIndices[2]]) };
                    float[][]  triUVs     = new float[][] { texData[triIndices[0]], texData[triIndices[1]], texData[triIndices[2]] };

                    GrimVec3 side0 = triVerts[1] - triVerts[0];
                    GrimVec3 side1 = triVerts[2] - triVerts[0];

                    float dU0 = triUVs[1][0] - triUVs[0][0];
                    float dU1 = triUVs[2][0] - triUVs[0][0];
                    float dV0 = triUVs[1][1] - triUVs[0][1];
                    float dV1 = triUVs[2][1] - triUVs[0][1];

                    GrimVec3 tangent      = dV1 * side0 - dV0 * side1;
                    GrimVec3 bitangent    = dU1 * side0 - dU0 * side1;
                    GrimVec3 tangentCross = GrimVec3.Cross(tangent, bitangent);

                    // Normalize at the end now
                    // tangent.Normalize();
                    // bitangent.Normalize();

                    //wind the tangent into the other direction if necassary; means: if the UVs are mirrored
                    //http://www.opentk.com/node/2520

                    /*
                     * if (GrimVec3.Dot(surfaceNormal, tangentCross) < 0.0f)
                     * {
                     *  biTangent *= -1.0f;
                     *  tangent *= -1.0f;
                     * }
                     */

                    for (int j = 0; j < 3; j++)
                    {
                        vertexTangents[triIndices[j]].Add(tangent);
                        vertexBitangents[triIndices[j]].Add(bitangent);
                    }
                }

                // Go over each vertex, see if we have created 1+ tangents for that vertex and do some maths if yes.
                for (int i = 0; i < vertexData.Length; i++)
                {
                    List <GrimVec3> t = vertexTangents[i];
                    List <GrimVec3> b = vertexBitangents[i];

                    if (t.Count != b.Count || t.Count == 0)
                    {
                        continue;
                    }

                    tangentData[i]   = new GrimVec3();
                    bitangentData[i] = new GrimVec3();

                    for (int j = 0; j < t.Count; j++)
                    {
                        tangentData[i]   = tangentData[i] + t[j];
                        bitangentData[i] = bitangentData[i] + b[j];
                    }

                    tangentData[i]   = (tangentData[i] - (normalData[i] * GrimVec3.Dot(normalData[i], tangentData[i])));
                    bitangentData[i] = (bitangentData[i] - (normalData[i] * GrimVec3.Dot(normalData[i], bitangentData[i])));

                    tangentData[i].Normalize();
                    bitangentData[i].Normalize();
                }
            }

            VertexArrays[VERTEX_ARRAY_TANGENT].putVertexDataAsVec3Array(tangentData);
            VertexArrays[VERTEX_ARRAY_BITANGENT].putVertexDataAsVec3Array(bitangentData);
        }
예제 #14
0
        /// <summary>
        /// Destroy the normal data for this mesh and recalculate them using a simple vertex averaging system.
        /// </summary>
        public void CalculateAverageVertexNormals(bool simpleWeighting = true)
        {
            GrimModelVertexArray vertexArray = VertexArrays[VERTEX_ARRAY_POSITION];

            float[][] vertexData = vertexArray.getVertexDataAsFloatArray();

            if (vertexData == null)
            {
                Logger.Instance.Error("No position vertex data in existing mesh.");
                return;
            }

            List <GrimVec3>[] vertexValues = new List <GrimVec3> [vertexData.Length];
            float[][]         normalData   = new float[vertexData.Length][];

            // Initialise all of the normals incase we don't compute any (the data needs to be the right size)
            for (int i = 0; i < vertexData.Length; i++)
            {
                normalData[i] = new float[3];
            }

            // Calculate the normal for each triangle and store that value for each vertex of that face (some vertices will have multiple values in a list).
            // We set each Normal Pt index to the same index as the vertex, as we are making these normals from scratch - we might as well make them parallel.
            foreach (GrimModelMeshSegment segment in Segments)
            {
                // Reset all of the values for this segment
                for (int i = 0; i < vertexData.Length; i++)
                {
                    vertexValues[i] = new List <GrimVec3>();
                }

                // Calculate the range of indices we are working with
                int firstIndex = segment.FirstIndex;
                int lastIndex  = firstIndex + segment.TriCount * 3;

                // Iterate over each vertex and calculate a normal at that point for each face it is used in
                for (int i = firstIndex; i < lastIndex; i += 3)
                {
                    uint[]     triIndices = new uint[] { Indices[i], Indices[i + 1], Indices[i + 2] };
                    GrimVec3[] verts      = new GrimVec3[] { new GrimVec3(vertexData[triIndices[0]]), new GrimVec3(vertexData[triIndices[1]]), new GrimVec3(vertexData[triIndices[2]]) };
                    GrimVec3   normal     = GrimVec3.Cross((verts[1] - verts[0]), (verts[2] - verts[0]));

                    // Apply Weighting
                    if (simpleWeighting)
                    {
                        for (int j = 0; j < 3; j++)
                        {
                            GrimVec3 a      = verts[(j + 1) % 3] - verts[j];
                            GrimVec3 b      = verts[(j + 2) % 3] - verts[j];
                            float    weight = (float)Math.Acos(GrimVec3.Dot(a, b) / (a.Length() * b.Length()));
                            normal *= weight;
                        }
                    }

                    vertexValues[triIndices[0]].Add(normal);
                    vertexValues[triIndices[1]].Add(normal);
                    vertexValues[triIndices[2]].Add(normal);
                }

                for (int i = 0; i < vertexValues.Length; i++)
                {
                    List <GrimVec3> vertexNormals = vertexValues[i];

                    if (vertexNormals.Count == 0)
                    {
                        continue;
                    }

                    GrimVec3 normal = new GrimVec3();

                    for (int j = 0; j < vertexNormals.Count; j++)
                    {
                        normal = normal + vertexNormals[j];
                    }

                    normal.Normalize();
                    normalData[i] = normal.ToFloatArray();
                }
            }

            VertexArrays[VERTEX_ARRAY_NORMAL].putVertexDataAsFloatArray(normalData);
        }
예제 #15
0
 protected override void DoRead(System.IO.BinaryReader reader)
 {
     Position = new GrimVec3(reader);
     Rotation = new GrimQuaternion(reader);
     Scale    = new GrimVec3(reader);
 }
예제 #16
0
 public override void ResetToDefaultParameters()
 {
     Position = new GrimVec3();
     Rotation = new GrimQuaternion();
     Scale    = new GrimVec3();
 }
예제 #17
0
 public GrimAnimationKeyFrame(GrimVec3 pos, GrimQuaternion rot, GrimVec3 scale)
 {
     Position = pos;
     Rotation = rot;
     Scale    = scale;
 }