Beispiel #1
0
        private void testSection(Section section)
        {
            Assert.IsInstanceOf(typeof(RWClump), section);
            RWClump clump = (RWClump)section;

            Assert.AreEqual(SectionId.Clump, section.sectionId);
            Assert.AreEqual(null, section.parent);
            Assert.AreEqual(0, clump.atomicCount);
            Assert.AreEqual(0, clump.camCount);
            Assert.AreEqual(0, clump.lightCount);
            Assert.AreEqual(3, clump.children.Count);


            Assert.IsInstanceOf(typeof(RWFrameList), clump.children[0]);
            RWFrameList frameList = (RWFrameList)clump.children[0];

            Assert.AreSame(clump, frameList.parent);
            Assert.AreEqual(SectionId.FrameList, frameList.sectionId);
            Assert.AreEqual(0, frameList.children.Count);
            Assert.AreEqual(1, frameList.frames.Length);
            Frame frame = frameList.frames[0];

            Assert.AreEqual(0, frame.creationFlags);
            Assert.AreEqual(0xffffffff, frame.frameIndex);
            Assert.AreEqual(new float[] {
                1.0f, 0.0f, 0.0f,
                0.0f, 1.0f, 0.0f,
                0.0f, 0.0f, 1.0f
            }, frame.rotMatrix);
            Assert.AreEqual(0.0f, frame.position.X);
            Assert.AreEqual(0.0f, frame.position.Y);
            Assert.AreEqual(0.0f, frame.position.Z);

            Assert.IsInstanceOf(typeof(RWExtension), clump.children[1]);
            RWExtension extension = (RWExtension)clump.children[1];

            Assert.AreSame(clump, extension.parent);
            Assert.AreEqual(0, extension.children.Count);

            Assert.IsInstanceOf(typeof(RWGeometryList), clump.children[2]);
            RWGeometryList geoList = (RWGeometryList)clump.children[2];

            Assert.AreSame(clump, geoList.parent);
            Assert.AreEqual(SectionId.GeometryList, geoList.sectionId);
            Assert.AreEqual(0, geoList.children.Count);
            Assert.AreEqual(0, geoList.geometryCount);
        }
Beispiel #2
0
        public ClumpBuffers(ITagContainer diContainer, RWClump clump)
        {
            var device       = diContainer.GetTag <GraphicsDevice>();
            var atomic       = clump.FindChildById(SectionId.Atomic, recursive: false) as RWAtomic;
            var geometry     = clump.FindChildById(SectionId.Geometry, true) as RWGeometry;
            var materialList = geometry?.FindChildById(SectionId.MaterialList, false) as RWMaterialList;
            var materials    = materialList?.children.Where(s => s is RWMaterial).Cast <RWMaterial>().ToArray();
            var morphTarget  = geometry?.morphTargets[0]; // TODO: morph support for the one model that uses it?

            if (geometry == null || morphTarget == null || materials == null || atomic == null)
            {
                throw new InvalidDataException("Could not find valid section structure in clump");
            }
            RWGeometry    = geometry;
            BSphereCenter = morphTarget.bsphereCenter;
            BSphereRadius = morphTarget.bsphereRadius;
            IsSolid       = atomic.flags.HasFlag(AtomicFlags.CollisionTest);

            var vertices = new ModelStandardVertex[morphTarget.vertices.Length];
            var bounds   = new Box(morphTarget.vertices.First(), Vector3.Zero);

            for (int i = 0; i < vertices.Length; i++)
            {
                vertices[i].pos   = morphTarget.vertices[i];
                vertices[i].color = geometry.colors.Length > 0 ? geometry.colors[i] : new IColor(255);
                vertices[i].tex   = geometry.texCoords.Length > 0 ? geometry.texCoords[0][i] : Vector2.Zero;
                bounds            = bounds.Union(vertices[i].pos);
            }
            Bounds       = bounds;
            vertexBuffer = device.ResourceFactory.CreateBuffer(new BufferDescription((uint)vertices.Length * ModelStandardVertex.Stride, BufferUsage.VertexBuffer));
            device.UpdateBuffer(vertexBuffer, 0, vertices);

            // TODO: might have to correlate to the materialIndices member of materialList
            var trianglesByMatIdx = geometry.triangles.GroupBy(t => t.m).Where(g => g.Count() > 0);
            var indices           = trianglesByMatIdx.SelectMany(
                g => g.SelectMany(t => new[] { t.v1, t.v2, t.v3 })
                ).ToArray();

            subMeshes = new SubMesh[trianglesByMatIdx.Count()];
            int nextIndexPtr = 0;

            foreach (var(group, idx) in trianglesByMatIdx.Indexed())
            {
                subMeshes[idx] = new SubMesh(nextIndexPtr, group.Count() * 3, materials[group.Key]);
                nextIndexPtr  += subMeshes[idx].IndexCount;
            }
            indexBuffer = device.ResourceFactory.CreateBuffer(new BufferDescription((uint)indices.Length * 2, BufferUsage.IndexBuffer));
            device.UpdateBuffer(indexBuffer, 0, indices);

            Skin = clump.FindChildById(SectionId.SkinPLG, true) as RWSkinPLG;
            if (Skin != null)
            {
                if (vertices.Length != Skin.vertexWeights.GetLength(0))
                {
                    throw new InvalidDataException("Vertex count in skin is not equal to geometry");
                }
                var skinVertices = new SkinVertex[vertices.Length];
                for (int i = 0; i < skinVertices.Length; i++)
                {
                    skinVertices[i].bone0     = Skin.vertexIndices[i, 0];
                    skinVertices[i].bone1     = Skin.vertexIndices[i, 1];
                    skinVertices[i].bone2     = Skin.vertexIndices[i, 2];
                    skinVertices[i].bone3     = Skin.vertexIndices[i, 3];
                    skinVertices[i].weights.X = Skin.vertexWeights[i, 0];
                    skinVertices[i].weights.Y = Skin.vertexWeights[i, 1];
                    skinVertices[i].weights.Z = Skin.vertexWeights[i, 2];
                    skinVertices[i].weights.W = Skin.vertexWeights[i, 3];
                }
                skinBuffer = device.ResourceFactory.CreateBuffer(new BufferDescription((uint)skinVertices.Length * SkinVertex.Stride, BufferUsage.VertexBuffer));
                device.UpdateBuffer(skinBuffer, 0, skinVertices);
            }
        }