//--------------------------------------------------------------- #endregion //--------------------------------------------------------------- //--------------------------------------------------------------- #region Properties //--------------------------------------------------------------- //--------------------------------------------------------------- #endregion //--------------------------------------------------------------- //--------------------------------------------------------------- #region Initialisation //--------------------------------------------------------------- /// <summary> /// Creates a sky box entity. /// </summary> /// <param name="size">Size of sky box.</param> /// <param name="format"><see cref="VertexFormat"/> to use for skybox.</param> public SkyBoxEntity(Vector3 size, VertexFormat format) { // create streams VertexUnit vertexUnit = new VertexUnit(format, 8); PositionStream position = (PositionStream)vertexUnit[typeof(PositionStream)]; //TextureStream texture = (TextureStream)vertexUnit[ typeof(TextureStream) ]; IndexStream index = new IndexStream16(24); // fill position data position[0] = new Vector3(-size.X, -size.Y, size.Z); position[1] = new Vector3(size.X, -size.Y, size.Z); position[2] = new Vector3(size.X, -size.Y, -size.Z); position[3] = new Vector3(-size.X, -size.Y, -size.Z); position[4] = new Vector3(-size.X, size.Y, size.Z); position[5] = new Vector3(size.X, size.Y, size.Z); position[6] = new Vector3(size.X, size.Y, -size.Z); position[7] = new Vector3(-size.X, size.Y, -size.Z); subSet = new SubSet(vertexUnit, index); }
//--------------------------------------------------------------- #endregion //--------------------------------------------------------------- //--------------------------------------------------------------- #region Methods //--------------------------------------------------------------- private void Bind() { BinormalStream.Bind(); BoneIndicesStream.Bind(); BoneWeightsStream.Bind(); SoftwareBoneIndicesStream.Bind(); SoftwareBoneWeightsStream.Bind(); ColorStream.Bind(); CompressedNormalStream.Bind(); FloatStream.Bind(); IndexStream16.Bind(); IndexStream32.Bind(); IntStream.Bind(); NormalStream.Bind(); PositionStream.Bind(); PositionStream2.Bind(); PositionStream4.Bind(); TangentStream.Bind(); TextureStream.Bind(); }
/// <summary> /// Loads the model. /// </summary> /// <param name="stream">Stream to load model from.</param> /// <returns>The loaded model.</returns> public Model LoadModel(Stream stream) { BlendMesh mesh; // get header and check if it is ok MD2_Header header = (MD2_Header)RawSerializer.Deserialize(stream, typeof(MD2_Header)); if (header.Ident != 844121161 || header.Version != 8) { return(null); } // Load skins MD2_Skin[] skinNames = (MD2_Skin[])RawSerializer.DeserializeArray(stream, typeof(MD2_Skin), header.NumSkins); // Load texture coordinates MD2_TextureCoordinate[] textureCoordinates = (MD2_TextureCoordinate[])RawSerializer.DeserializeArray(stream, typeof(MD2_TextureCoordinate), header.NumTextureCoordinates); // Load triangless MD2_Triangle[] triangles = (MD2_Triangle[])RawSerializer.DeserializeArray(stream, typeof(MD2_Triangle), header.NumTris); IndexStream indexStream = new IndexStream16(triangles.Length); for (int i = 0; i < triangles.Length; i++) { // indexStream[i] = triangles[i].VertexIndex[j; } mesh = new BlendMesh(header.NumFrames); // Load frames for (int i = 0; i < header.NumFrames; i++) { MD2_Frame frame = (MD2_Frame)RawSerializer.Deserialize(stream, typeof(MD2_Frame)); MD2_Vertex[] vertices = (MD2_Vertex[])RawSerializer.DeserializeArray(stream, typeof(MD2_Vertex), header.NumVertices); VertexUnit vu = new VertexUnit(VertexFormat.Position, vertices.Length); PositionStream ps = (PositionStream)vu[typeof(Purple.Graphics.VertexStreams.PositionStream)]; mesh.Meshes[i] = new Mesh(new SubSet(vu, indexStream)); } return(new Model(mesh, null)); }
private MD3Part LoadMD3(string part) { using (Stream stream = fileSystem.Open(path + part + ".md3")) { // get header and check if it is ok MD3_Header header = (MD3_Header)RawSerializer.Deserialize(stream, typeof(MD3_Header)); if (header.Id != 860898377 || header.Version != 15) { return(null); } // load bone frames MD3_Frame[] frames = (MD3_Frame[])RawSerializer.DeserializeArray(stream, typeof(MD3_Frame), header.NumFrames); // load tags SortedList links = GetLinks((MD3_Tag[])RawSerializer.DeserializeArray(stream, typeof(MD3_Tag), header.NumTags * header.NumFrames)); long meshOffset = stream.Position; // one mesh for every frame BlendMesh mesh = new BlendMesh(header.NumFrames); // load meshes for (int iMesh = 0; iMesh < header.NumMeshes; iMesh++) { stream.Position = meshOffset; MD3_MeshHeader meshHeader = (MD3_MeshHeader)RawSerializer.Deserialize(stream, typeof(MD3_MeshHeader)); MD3_Skin[] skins = (MD3_Skin[])RawSerializer.DeserializeArray(stream, typeof(MD3_Skin), meshHeader.NumSkins); stream.Position = meshOffset + meshHeader.TriangleOffset; MD3_Triangle[] triangles = (MD3_Triangle[])RawSerializer.DeserializeArray(stream, typeof(MD3_Triangle), meshHeader.NumTriangles); stream.Position = meshOffset + meshHeader.TexCoordOffset; MD3_TexCoord[] texCoords = (MD3_TexCoord[])RawSerializer.DeserializeArray(stream, typeof(MD3_TexCoord), meshHeader.NumVertices); stream.Position = meshOffset + meshHeader.VertexOffset; MD3_Vertex[] vertices = (MD3_Vertex[])RawSerializer.DeserializeArray(stream, typeof(MD3_Vertex), meshHeader.NumFrames * meshHeader.NumVertices); float scale = 64.0f; string name = StringHelper.Convert(meshHeader.Name); ITexture tx = (ITexture)textures[name]; Triangle[] tris = new Triangle[triangles.Length]; for (int i = 0; i < triangles.Length; i++) { tris[i].A = (triangles[i]).A; tris[i].B = (triangles[i]).B; tris[i].C = (triangles[i]).C; } IndexStream indexStream = IndexStream16.FromTriangles(tris); int vertCount = meshHeader.NumVertices; // *meshHeader.NumFrames; for (int iFrame = 0; iFrame < meshHeader.NumFrames; iFrame++) { VertexUnit vertexUnit = new VertexUnit(VertexFormat.PositionNormalTexture, vertCount); PositionStream pos = (PositionStream)vertexUnit[typeof(PositionStream)]; NormalStream normal = (NormalStream)vertexUnit[typeof(NormalStream)]; TextureStream tex = (TextureStream)vertexUnit[typeof(TextureStream)]; for (int i = 0; i < vertCount; i++) { int vertIndex = iFrame * meshHeader.NumVertices + i; pos[i] = new Vector3(vertices[vertIndex].X / scale, vertices[vertIndex].Z / scale, -vertices[vertIndex].Y / scale); int texIndex = i % meshHeader.NumVertices; tex[i] = new Vector2(texCoords[texIndex].U, texCoords[texIndex].V); //Normal vector int compressedNormal = ((MD3_Vertex)vertices[vertIndex]).Normal; float lng = (compressedNormal & 0xFF) * Math.Basic.PI / 128; float lat = ((compressedNormal >> 8) & 0xFF) * Math.Basic.PI / 128; normal[i] = new Vector3(Math.Trigonometry.Cos(lat) * Math.Trigonometry.Sin(lng), Math.Trigonometry.Cos(lng), -Math.Trigonometry.Sin(lat) * Math.Trigonometry.Sin(lng)); } if (mesh.Meshes[iFrame] == null) { mesh.Meshes[iFrame] = new Mesh(); } mesh.Meshes[iFrame].SubSets.Add(new SubSet(vertexUnit, indexStream)); mesh.Meshes[iFrame].Textures.Add(new Textures("color", tx)); } // Increase the offset into the file meshOffset += meshHeader.MeshSize; } return(new MD3Part(mesh, links)); } }
/// <summary> /// import a mesh from a stream /// </summary> /// <param name="stream">stream containing mesh data</param> public void Import(Stream stream) { model = null; skeleton = null; IndexStream indexStream = null; IVertexStream currentStream = null; ArrayList streams = new ArrayList(); StringDictionary attributes = new StringDictionary(); XmlTextReader reader = new XmlTextReader(stream); Matrix4[] jointArray = null; Joint[] joints = null; Hashtable jointTable = null; int index = 0; int currentJoint = 0; int vertexCount = 0; int binding = -1; ArrayList[] indicesList = null; ArrayList[] weightsList = null; while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { switch (reader.Name) { // <mesh> case "mesh": if (model != null) { throw new GraphicsException("Only one mesh allowed in mesh stream!"); } model = new Model(); break; // <subset> case "subset": string parentJoint = reader.GetAttribute("parentJoint"); if (parentJoint != null && parentJoint != "") { binding = (jointTable[parentJoint] as Joint).Index; } else { binding = -1; } break; // <attributes> case "attributes": break; case "attribute": // todo !!! attributes.Add(reader.GetAttribute("name"), reader.GetAttribute("value")); break; //<indexStream> case "indexStream": { index = 0; int size = int.Parse(reader.GetAttribute("size"), culture); indexStream = new IndexStream16(size); } break; //<triangle> case "triangle": { int a = int.Parse(reader.GetAttribute("a"), culture); int b = int.Parse(reader.GetAttribute("b"), culture); int c = int.Parse(reader.GetAttribute("c"), culture); indexStream[index++] = a; indexStream[index++] = b; indexStream[index++] = c; } break; //<positionStream> case "positionStream": { index = 0; vertexCount = int.Parse(reader.GetAttribute("size"), culture); currentStream = new PositionStream(vertexCount); streams.Add(currentStream); } break; //<vector3> case "vector3": { float x = float.Parse(reader.GetAttribute("x"), culture); float y = float.Parse(reader.GetAttribute("y"), culture); float z = float.Parse(reader.GetAttribute("z"), culture); (currentStream as PositionStream)[index++] = new Vector3(x, y, z); } break; //<normalStream> case "normalStream": { index = 0; int size = int.Parse(reader.GetAttribute("size"), culture); currentStream = new NormalStream(size); streams.Add(currentStream); } break; //<colorStream> case "colorStream": { index = 0; int size = int.Parse(reader.GetAttribute("size"), culture); currentStream = new ColorStream(size); streams.Add(currentStream); } break; //<color> case "color": { int r = (int)((float.Parse(reader.GetAttribute("r"), culture)) * 255.0f + 0.5f); int g = (int)((float.Parse(reader.GetAttribute("g"), culture)) * 255.0f + 0.5f); int b = (int)((float.Parse(reader.GetAttribute("b"), culture)) * 255.0f + 0.5f); (currentStream as ColorStream)[index++] = System.Drawing.Color.FromArgb(r, g, b).ToArgb(); } break; //<textureStream> case "textureStream": { index = 0; int size = int.Parse(reader.GetAttribute("size"), culture); currentStream = new TextureStream(size); streams.Add(currentStream); } break; //<vector2> case "vector2": { float x = float.Parse(reader.GetAttribute("x"), culture); float y = float.Parse(reader.GetAttribute("y"), culture); (currentStream as TextureStream)[index++] = new Vector2(x, y); } break; case "joints": { int size = int.Parse(reader.GetAttribute("size"), culture); jointArray = new Matrix4[size]; joints = new Joint[size]; jointTable = new Hashtable(); currentJoint = 0; } break; case "joint": { string jointName = reader.GetAttribute("name"); string parentName = reader.GetAttribute("parent"); Matrix4 m = new Matrix4(float.Parse(reader.GetAttribute("a1"), culture), float.Parse(reader.GetAttribute("a2"), culture), float.Parse(reader.GetAttribute("a3"), culture), float.Parse(reader.GetAttribute("a4"), culture), float.Parse(reader.GetAttribute("b1"), culture), float.Parse(reader.GetAttribute("b2"), culture), float.Parse(reader.GetAttribute("b3"), culture), float.Parse(reader.GetAttribute("b4"), culture), float.Parse(reader.GetAttribute("c1"), culture), float.Parse(reader.GetAttribute("c2"), culture), float.Parse(reader.GetAttribute("c3"), culture), float.Parse(reader.GetAttribute("c4"), culture), float.Parse(reader.GetAttribute("d1"), culture), float.Parse(reader.GetAttribute("d2"), culture), float.Parse(reader.GetAttribute("d3"), culture), float.Parse(reader.GetAttribute("d4"), culture)); jointArray[currentJoint] = m; //new Joint(jointName, m); Joint parent = null; if (parentName != null && jointTable.Contains(parentName)) { parent = (Joint)jointTable[parentName]; } joints[currentJoint] = new Joint(jointName, currentJoint, parent); jointTable[jointName] = joints[currentJoint]; currentJoint++; } break; case "weights": { index = 0; //vertexCount = int.Parse(reader.GetAttribute("size"), culture); indicesList = new ArrayList[vertexCount]; weightsList = new ArrayList[vertexCount]; for (int i = 0; i < vertexCount; i++) { indicesList[i] = new ArrayList(8); weightsList[i] = new ArrayList(8); } } break; case "weight": { int vertexIndex = int.Parse(reader.GetAttribute("vertexIndex")); byte jointIndex = byte.Parse(reader.GetAttribute("jointIndex")); float value = float.Parse(reader.GetAttribute("weight"), culture); indicesList[vertexIndex].Add(jointIndex); weightsList[vertexIndex].Add(value); } break; } } if (reader.NodeType == XmlNodeType.EndElement) { if (reader.Name.Equals("weights")) { IBoneIndicesStream bis = null; IBoneWeightsStream bws = null; if (HardwareSkinning) { bis = new BoneIndicesStream(vertexCount); bws = new BoneWeightsStream(vertexCount); } else { bis = new SoftwareBoneIndicesStream(vertexCount); bws = new SoftwareBoneWeightsStream(vertexCount); } for (int i = 0; i < vertexCount; i++) { bis.SetIndices(i, (byte[])indicesList[i].ToArray(typeof(byte))); bws.SetWeights(i, (float[])weightsList[i].ToArray(typeof(float))); } streams.Add(bis); streams.Add(bws); } else if (reader.Name.Equals("subset")) { VertexUnit vertexUnit = new VertexUnit(streams); if (binding == -1) { model.Mesh = new Mesh(new SubSet(vertexUnit, indexStream)); } else { model.AttachModel(new Model(new Mesh(new SubSet(vertexUnit, indexStream)), null), binding); } streams.Clear(); } } } ; reader.Close(); if (jointArray != null && joints != null) { skeleton = new Skeleton(jointArray, joints); } model.Skeleton = skeleton; }