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); }
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); } }