public static void ComputeTangent(ref VertexPNTTB srcVert, VertexPNTTB vert1, VertexPNTTB vert2)
        {
            Vector4 d0 = vert1.Position - srcVert.Position;
            Vector4 d1 = vert2.Position - srcVert.Position;

            Vector2 s = vert1.Texcoord - srcVert.Texcoord;
            Vector2 t = vert2.Texcoord - srcVert.Texcoord;

            float r = 1.0F / (t.X * s.Y - t.Y * s.X);
            Vector3 tangent = new Vector3(s.Y * d1.X - t.Y * d0.X, s.Y * d1.Y - t.Y * d0.Y, s.Y * d1.Z - t.Y * d0.Z) * r;
            srcVert.Tangent = Vector3.Normalize(tangent - srcVert.Normal * Vector3.Dot(srcVert.Normal, tangent));
        }
Beispiel #2
0
        void ParseSMDTriangles(StreamReader file)
        {
            if (this.modelGroups != null)
                return;

            SortedList<string, List<VertexPNTTB>> vertexLists = new SortedList<string, List<VertexPNTTB>>();
            SortedList<string, List<ushort>> indicesList = new SortedList<string, List<ushort>>();
            while (!file.EndOfStream)
            {
                string text = file.ReadLine();
                if (text == "end")
                {
                    break;
                }

                string materialName = text.Split('.')[0];
                if (!vertexLists.ContainsKey(materialName))
                {
                    vertexLists.Add(materialName, new List<VertexPNTTB>());
                    indicesList.Add(materialName, new List<ushort>());
                }

                VertexPNTTB[] vertices = new VertexPNTTB[3];
                for (int i = 0; i < 3; i++)
                {
                    text = file.ReadLine();
                    string[] data = text.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    Vector4 bone = new Vector4(int.Parse(data[0]), 0, 0, 0);
                    Vector4 boneWeights = new Vector4(1.0f, 0, 0, 0);
                    Vector3 pos;
                    pos.X = float.Parse(data[1]);
                    pos.Y = float.Parse(data[2]);
                    pos.Z = float.Parse(data[3]);
                    Vector3 normal;
                    normal.X = float.Parse(data[4]);
                    normal.Y = float.Parse(data[5]);
                    normal.Z = float.Parse(data[6]);
                    normal.Normalize();
                    Vector2 texcoord;
                    texcoord.X = float.Parse(data[7]);
                    texcoord.Y = float.Parse(data[8]);
                    if (data.Length > 10) //Code for multiple blendweights
                    {
                        int boneBlendCount = int.Parse(data[9]);
                        for (int m = 0; m < boneBlendCount; m++)
                        {
                            int index = m * 2 + 10;
                            switch (m)
                            {
                                case 0:
                                    bone.Y = int.Parse(data[index]);
                                    boneWeights.Y = float.Parse(data[index + 1]);
                                    break;
                                case 1:
                                    bone.Z = int.Parse(data[index]);
                                    boneWeights.Z = float.Parse(data[index + 1]);
                                    break;
                                case 2:
                                    bone.W = int.Parse(data[index]);
                                    boneWeights.W = float.Parse(data[index + 1]);
                                    break;
                            }
                        }
                        float sum = Vector4.Dot(boneWeights, Vector4.One);
                        boneWeights.X = 1.0f - sum;
                    }
                    vertices[i] = new VertexPNTTB(pos, normal, texcoord, bone, boneWeights, Vector3.Zero);
                    indicesList[materialName].Add((ushort)(vertexLists[materialName].Count+i));
                }

                //Compute our tangent vectors
                MathUtils.ComputeTangent(ref vertices[0], vertices[1], vertices[2]);
                MathUtils.ComputeTangent(ref vertices[1], vertices[2], vertices[0]);
                MathUtils.ComputeTangent(ref vertices[2], vertices[0], vertices[1]);
                vertexLists[materialName].AddRange(vertices);
            }

            this.modelGroups = new ModelPart[vertexLists.Keys.Count];
            for (int i = 0; i < vertexLists.Keys.Count; i++)
            {
                string key = vertexLists.Keys[i];

                VertexBuffer vertexBuffer = new VertexBuffer(GFX.Device, vertexLists[key].Count * VertexPNTTB.SizeInBytes, BufferUsage.WriteOnly);
                vertexBuffer.SetData<VertexPNTTB>(vertexLists[key].ToArray());

                IndexBuffer indexBuffer = new IndexBuffer(GFX.Device, sizeof(ushort) * indicesList[key].Count, BufferUsage.WriteOnly, IndexElementSize.SixteenBits);
                indexBuffer.SetData<ushort>(indicesList[key].ToArray());

                Vector3 pos = new Vector3(vertexLists[key][0].Position.X, vertexLists[key][0].Position.Y, vertexLists[key][0].Position.Z);
                BoundingBox bounds = new BoundingBox(pos, pos);
                for (int j = 0; j < vertexLists[key].Count; j++)
                {
                    pos = new Vector3(vertexLists[key][j].Position.X, vertexLists[key][j].Position.Y, vertexLists[key][j].Position.Z);
                    bounds.Max = Vector3.Max(bounds.Max, pos);
                    bounds.Min = Vector3.Min(bounds.Min, pos);
                }

                modelGroups[i] = new ModelPart(key, vertexBuffer, indexBuffer, bounds);
            }
        }