private static void GenerateMeshChunks(float[, ][,] heightMaps, Color[, ][,] c, Transform map) { GameObject chunkPrefab = CreateEmptyMesh(); for (int x = 0; x < heightMaps.GetLength(0); x += MeshChunk.MaxSideLength) { for (int y = 0; y < heightMaps.GetLength(1); y += MeshChunk.MaxSideLength) { int chunkWidth = (x + MeshChunk.MaxSideLength <= heightMaps.GetLength(0)) ? MeshChunk.MaxSideLength : heightMaps.GetLength(0) - x; int chunkHeight = (y + MeshChunk.MaxSideLength <= heightMaps.GetLength(1)) ? MeshChunk.MaxSideLength : heightMaps.GetLength(1) - y; float[, ][,] chunk = new float[chunkWidth, chunkHeight][, ]; Color[, ][,] colors = new Color[chunkWidth, chunkHeight][, ]; for (int xi = 0; xi < chunkWidth; xi++) { for (int yi = 0; yi < chunkHeight; yi++) { chunk[xi, yi] = heightMaps[x + xi, y + yi]; colors[xi, yi] = c[x + xi, y + yi]; } } GameObject mapChunk = Object.Instantiate(chunkPrefab, map); mapChunk.GetComponent <MeshFilter>().mesh = MeshChunk.GenerateMeshChunk(chunk, colors, tileSize); mapChunk.transform.localPosition = new Vector3(x * tileSize, y * tileSize, 0); } } Object.DestroyImmediate(chunkPrefab); }
public Mesh(MeshChunk meshChunk, BitmapChunk bmpChunk) { _polys = meshChunk.Polygons; Identifier = meshChunk.Identifier; Resolve(bmpChunk); BoundingBox = GetBoundingBox(); }
protected virtual MeshChunk SurfaceNorth(Chunk c, int x, int y, int z, MeshChunk m) { m.AddVertex(new Vector3(x + 0.5f, y - 0.5f, z + 0.5f)); // 4 m.AddVertex(new Vector3(x + 0.5f, y + 0.5f, z + 0.5f)); // 5 m.AddVertex(new Vector3(x - 0.5f, y + 0.5f, z + 0.5f)); // 6 m.AddVertex(new Vector3(x - 0.5f, y - 0.5f, z + 0.5f)); // 7 m.AddSurface(); m.uv.AddRange(FaceUVs(Surface.NORTH)); return(m); }
protected virtual MeshChunk SurfaceSouth(Chunk c, int x, int y, int z, MeshChunk m) { m.AddVertex(new Vector3(x - 0.5f, y - 0.5f, z - 0.5f)); // 0 m.AddVertex(new Vector3(x - 0.5f, y + 0.5f, z - 0.5f)); // 1 m.AddVertex(new Vector3(x + 0.5f, y + 0.5f, z - 0.5f)); // 2 m.AddVertex(new Vector3(x + 0.5f, y - 0.5f, z - 0.5f)); // 3 m.AddSurface(); m.uv.AddRange(FaceUVs(Surface.SOUTH)); return(m); }
protected virtual MeshChunk SurfaceAbove(Chunk c, int x, int y, int z, MeshChunk m) { m.AddVertex(new Vector3(x - 0.5f, y + 0.5f, z + 0.5f)); // 6 m.AddVertex(new Vector3(x + 0.5f, y + 0.5f, z + 0.5f)); // 5 m.AddVertex(new Vector3(x + 0.5f, y + 0.5f, z - 0.5f)); // 2 m.AddVertex(new Vector3(x - 0.5f, y + 0.5f, z - 0.5f)); // 1 m.AddSurface(); m.uv.AddRange(FaceUVs(Surface.ABOVE)); return(m); }
protected virtual MeshChunk SurfaceBelow(Chunk c, int x, int y, int z, MeshChunk m) { m.AddVertex(new Vector3(x - 0.5f, y - 0.5f, z - 0.5f)); // 0 m.AddVertex(new Vector3(x + 0.5f, y - 0.5f, z - 0.5f)); // 3 m.AddVertex(new Vector3(x + 0.5f, y - 0.5f, z + 0.5f)); // 4 m.AddVertex(new Vector3(x - 0.5f, y - 0.5f, z + 0.5f)); // 7 m.AddSurface(); m.uv.AddRange(FaceUVs(Surface.BELOW)); return(m); }
// vertices for opposite sides have one inverted axis, and reversed vertex order // 6---------5 // // /| /| // // 1-+-------2 | // // | | | | // // | 7-------+-4 // // |/ |/ // // 0---------3 // protected virtual MeshChunk SurfaceWest(Chunk c, int x, int y, int z, MeshChunk m) { m.AddVertex(new Vector3(x - 0.5f, y - 0.5f, z + 0.5f)); // 7 m.AddVertex(new Vector3(x - 0.5f, y + 0.5f, z + 0.5f)); // 6 m.AddVertex(new Vector3(x - 0.5f, y + 0.5f, z - 0.5f)); // 1 m.AddVertex(new Vector3(x - 0.5f, y - 0.5f, z - 0.5f)); // 0 m.AddSurface(); m.uv.AddRange(FaceUVs(Surface.WEST)); return(m); }
protected virtual MeshChunk SurfaceEast(Chunk c, int x, int y, int z, MeshChunk m) { m.AddVertex(new Vector3(x + 0.5f, y - 0.5f, z - 0.5f)); // 3 m.AddVertex(new Vector3(x + 0.5f, y + 0.5f, z - 0.5f)); // 2 m.AddVertex(new Vector3(x + 0.5f, y + 0.5f, z + 0.5f)); // 5 m.AddVertex(new Vector3(x + 0.5f, y - 0.5f, z + 0.5f)); // 4 m.AddSurface(); m.uv.AddRange(FaceUVs(Surface.EAST)); return(m); }
// updates the chunk based on its contents void UpdateChunk() { MeshChunk m = new MeshChunk(); for (int x = 0; x < sizeChunk; x++) { for (int y = 0; y < sizeChunk; y++) { for (int z = 0; z < sizeChunk; z++) { m = blocks[x, y, z].MeshBlock(this, x, y, z, m); } } } RenderMesh(m); }
// retrieves mesh data public virtual MeshChunk MeshBlock(Chunk c, int x, int y, int z, MeshChunk m) { m.isShared = true; // uses same mesh for renderer and collider // check west-connected block if (!c.GetBlock(x - 1, y, z).IsSolid(Surface.EAST)) { m = SurfaceWest(c, x, y, z, m); } // check east-connected block if (!c.GetBlock(x + 1, y, z).IsSolid(Surface.WEST)) { m = SurfaceEast(c, x, y, z, m); } // check below-connected block if (!c.GetBlock(x, y - 1, z).IsSolid(Surface.ABOVE)) { m = SurfaceBelow(c, x, y, z, m); } // check above-connected block if (!c.GetBlock(x, y + 1, z).IsSolid(Surface.BELOW)) { m = SurfaceAbove(c, x, y, z, m); } // check south-connected block if (!c.GetBlock(x, y, z - 1).IsSolid(Surface.NORTH)) { m = SurfaceSouth(c, x, y, z, m); } // check north-connected block if (!c.GetBlock(x, y, z + 1).IsSolid(Surface.SOUTH)) { m = SurfaceNorth(c, x, y, z, m); } return(m); }
// sends calculated mesh data to renderer and collider void RenderMesh(MeshChunk m) { // renderer features mf.mesh.Clear(); mf.mesh.vertices = m.vx.ToArray(); // adds renderer vertices mf.mesh.triangles = m.tx.ToArray(); // adds renderer triangles mf.mesh.uv = m.uv.ToArray(); // adds uv-maps mf.mesh.RecalculateNormals(); // collider features mc.sharedMesh = null; // removes default collision mesh Mesh temp = new Mesh(); // temporary mesh temp.vertices = m.vc.ToArray(); // adds collider vertices temp.triangles = m.tc.ToArray(); // adds collider triangles temp.RecalculateNormals(); mc.sharedMesh = temp; // inserts new collision mesh }
private void updateChunk(BinaryReader file, long startPosition, Vector3 offset, Quaternion rotation) { file.BaseStream.Seek(startPosition + meshChunkInfoStruct.fields[MSH_CHUNK_GROUP_NAME_INDEX].index, SeekOrigin.Begin); //Get the name of the meshchunk this info is for String currentMeshChunkName = IOUtilities.readECString(file, binaryFile.dataOffset + file.ReadInt32()); //Console.WriteLine("Doing Chunk " + currentMeshChunkName); //Find the meshChunk we need MeshChunk currentMeshChunk = null; foreach (MeshChunk m in mesh.chunks) { if (m.name == currentMeshChunkName) { currentMeshChunk = m; break; } } //If no mesh chunk could be found there was a problem if (currentMeshChunk == null) { Console.WriteLine("Could not find mesh chunk \"{0}\" in msh file \"{1}\".", currentMeshChunkName, mshName); throw new Exception("COULD NOT FIND MESHCHUNK, LOOK AT CONSOLE!!!!!!"); } //Get the material name file.BaseStream.Seek(startPosition + meshChunkInfoStruct.fields[MSH_CHUNK_MATERIAL_INDEX].index, SeekOrigin.Begin); currentMeshChunk.materialObjectName = IOUtilities.readECString(file, binaryFile.dataOffset + file.ReadInt32()) + ".mao"; //Get the chunk ID file.BaseStream.Seek(startPosition + meshChunkInfoStruct.fields[MSH_CHUNK_ID_INDEX].index, SeekOrigin.Begin); currentMeshChunk.id = IOUtilities.readECString(file, binaryFile.dataOffset + file.ReadInt32()); //Get whether it casts shadows file.BaseStream.Seek(startPosition + meshChunkInfoStruct.fields[MSH_CHUNK_CASTS_BAKED_INDEX].index, SeekOrigin.Begin); currentMeshChunk.casts = file.ReadByte() == 1; //Get whether it receives shadows file.BaseStream.Seek(startPosition + meshChunkInfoStruct.fields[MSH_CHUNK_RECEIVES_BAKED_INDEX].index, SeekOrigin.Begin); currentMeshChunk.receives = currentMeshChunk.usesTwoTexCoords ? file.ReadByte() == 1 : false; //Get translation offset and rotation file.BaseStream.Seek(startPosition + meshChunkInfoStruct.fields[MSH_CHUNK_CHILDREN_INDEX].index, SeekOrigin.Begin); int reference = file.ReadInt32(); file.BaseStream.Seek(binaryFile.dataOffset + reference, SeekOrigin.Begin); GenericList attributes = new GenericList(file); for (int j = 0; j < attributes.length; j++) { if ((int)(attributes.type[j].id) == rotationStructIndex) { file.BaseStream.Seek(binaryFile.dataOffset + attributes[j], SeekOrigin.Begin); currentMeshChunk.chunkRotation = new Quaternion(file.ReadSingle(), file.ReadSingle(), file.ReadSingle(), file.ReadSingle()) * rotation; } else if ((int)(attributes.type[j].id) == translationStructIndex) { file.BaseStream.Seek(binaryFile.dataOffset + attributes[j], SeekOrigin.Begin); currentMeshChunk.chunkOffset = offset + new Vector3(file.ReadSingle(), file.ReadSingle(), file.ReadSingle()); } else if ((int)(attributes.type[j].id) == meshChunkInfoIndex) { updateChunk(file, binaryFile.dataOffset + attributes[j], currentMeshChunk.chunkOffset, currentMeshChunk.chunkRotation); } } }
///<summary> ///Initializes all the chunk classes and adds them to a hashtable ///for lookup and retrieval based on their chunk ID; ///</summary> private void initializeChunks() { Chunk meshChunk = new MeshChunk(); Chunk hierarchyChunk = new HierarchyChunk(); Chunk hierarchyHeaderChunk = new HierarchyHeaderChunk(); Chunk pivotsChunk = new PivotsChunk(); Chunk pivotFixupsChunk = new PivotFixupsChunk(); Chunk hlodChunk = new HlodChunk(); Chunk hlodHeaderChunk = new HlodHeaderChunk(); Chunk hlodLodArrayChunk = new HlodLodArrayChunk(); Chunk hlodSubObjectArrayHeaderChunk = new HlodSubObjectArrayHeaderChunk(); Chunk hlodSubObjectChunk = new HlodSubObjectChunk(); Chunk hlodProxyArrayChunk = new HLodProxyArrayChunk(); Chunk meshHeader3Chunk = new MeshHeader3Chunk(); Chunk verticesChunk = new VerticesChunk(); Chunk vertexNormalsChunk = new VertexNormalsChunk(); Chunk trianglesChunk = new TrianglesChunk(); Chunk vertexShadeIndicesChunk = new VertexShadeIndicesChunk(); Chunk materialInfoChunk = new MaterialInfoChunk(); Chunk vertexMaterialsChunk = new VertexMaterialsChunk(); Chunk vertexMaterialChunk = new VertexMaterialChunk(); Chunk vertexMaterialNameChunk = new VertexMaterialNameChunk(); Chunk vertexMaterialInfoChunk = new VertexMaterialInfoChunk(); Chunk shadersChunk = new ShadersChunk(); Chunk texturesChunk = new TexturesChunk(); Chunk textureChunk = new TextureChunk(); Chunk textureNameChunk = new TextureNameChunk(); Chunk textureInfoChunk = new TextureInfoChunk(); Chunk materialPassChunk = new MaterialPassChunk(); Chunk vertexMaterialIdsChunk = new VertexMaterialIdsChunk(); Chunk shaderIdsChunk = new ShaderIdsChunk(); Chunk textureStageChunk = new TextureStageChunk(); Chunk textureIdsChunk = new TextureIdsChunk(); Chunk stageTexCoordsChunk = new StageTexCoordsChunk(); Chunk aabTreeChunk = new AabTreeChunk(); Chunk aabTreeHeaderChunk = new AabTreeHeaderChunk(); Chunk aabTreePolyIndicesChunk = new AabTreePolyIndicesChunk(); Chunk aabTreeNodesChunk = new AabTreeNodesChunk(); Chunk aggregateChunk = new AggregateChunk(); Chunk aggregateHeaderChunk = new AggregateHeaderChunk(); Chunk aggregateInfoChunk = new AggregateInfoChunk(); Chunk aggregateClassInfoChunk = new AggregateClassInfoChunk(); Chunk textureReplacerChunk = new TextureReplacerChunk(); Chunk vertexMapperArgs0Chunk = new VertexMapperArgs0Chunk(); Chunk vertexMapperArgs1Chunk = new VertexMapperArgs1Chunk(); Chunk animationChunk = new AnimationChunk(); Chunk animationHeaderChunk = new AnimationHeaderChunk(); Chunk animationChannelChunk = new AnimationChannelChunk(); Chunk bitChannelChunk = new BitChannelChunk(); Chunk emitterChunk = new EmitterChunk(); Chunk emitterHeaderChunk = new EmitterHeaderChunk(); Chunk emitterUserDataChunk = new EmitterUserDataChunk(); Chunk emitterInfoChunk = new EmitterInfoChunk(); Chunk emitterInfo2Chunk = new EmitterInfo2Chunk(); Chunk emitterPropsChunk = new EmitterPropsChunk(); Chunk emitterRotationKeyframesChunk = new EmitterRotationKeyFramesChunk(); Chunk emitterFrameKeyFramesChunk = new EmitterFrameKeyFramesChunk(); Chunk emitterBlurTimeKeyFramesChunk = new EmitterBlurTimeKeyFramesChunk(); Chunk emitterLinePropertiesChunk = new EmitterLinePropertiesChunk(); Chunk vertexInfluencesChunk = new VertexInfluencesChunk(); Chunk dcgChunk = new DcgChunk(); Chunk hModelChunk = new HModelChunk(); Chunk hModelHeaderChunk = new HModelHeaderChunk(); Chunk hModelAuxDataChunk = new HModelAuxDataChunk(); Chunk nodeChunk = new NodeChunk(); Chunk compressedAnimationChunk = new CompressedAnimationChunk(); Chunk compressedAnimationHeaderChunk = new CompressedAnimationHeaderChunk(); Chunk compressedAnimationChannelChunk = new CompressedAnimationChannelChunk(); Chunk compressedBitChannelChunk = new CompressedBitChannelChunk(); Chunk hLodAggregateArrayChunk = new HLodAggregateArrayChunk(); Chunk prelitUnlitChunk = new PrelitUnlitChunk(); Chunk prelitVertexChunk = new PrelitVertexChunk(); Chunk prelitLightMultiPassChunk = new PrelitLightMultiPassChunk(); Chunk prelitLightMultiTextureChunk = new PrelitLightMultiTextureChunk(); Chunk meshUserTextChunk = new MeshUserTextChunk(); Chunk collectionChunk = new CollectionChunk(); Chunk collectionHeaderChunk = new CollectionHeaderChunk(); Chunk collectionObjectNameChunk = new CollectionObjectNameChunk(); Chunk placeholderChunk = new PlaceholderChunk(); Chunk transformNodeChunk = new TransformNodeChunk(); Chunk dazzleChunk = new DazzleChunk(); Chunk dazzleNameChunk = new DazzleNameChunk(); Chunk dazzleTypeNameChunk = new DazzleTypeNameChunk(); Chunk boxChunk = new BoxChunk(); Chunk deformChunk = new DeformChunk(); Chunk deformSetChunk = new DeformSetChunk(); Chunk deformKeyframeChunk = new DeformKeyframeChunk(); Chunk deformDataChunk = new DeformDataChunk(); //Animation chunkMap.Add((int)ChunkHeader.W3D_CHUNK_ANIMATION, animationChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_ANIMATION_HEADER, animationHeaderChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_ANIMATION_CHANNEL, animationChannelChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_BIT_CHANNEL, bitChannelChunk); // Aggregate chunkMap.Add((int)ChunkHeader.W3D_CHUNK_AGGREGATE, aggregateChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_AGGREGATE_HEADER, aggregateHeaderChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_AGGREGATE_INFO, aggregateInfoChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_AGGREGATE_CLASS_INFO, aggregateClassInfoChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_TEXTURE_REPLACER_INFO, textureReplacerChunk); //Collection chunkMap.Add((int)ChunkHeader.W3D_CHUNK_COLLECTION, collectionChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_COLLECTION_HEADER, collectionHeaderChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_COLLECTION_OBJ_NAME, collectionObjectNameChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_PLACEHOLDER, placeholderChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_TRANSFORM_NODE, transformNodeChunk); //Compressed Animation chunkMap.Add((int)ChunkHeader.W3D_CHUNK_COMPRESSED_ANIMATION, compressedAnimationChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_COMPRESSED_ANIMATION_HEADER, compressedAnimationHeaderChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_COMPRESSED_ANIMATION_CHANNEL, compressedAnimationChannelChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_COMPRESSED_BIT_CHANNEL, compressedBitChannelChunk); //Dazzle chunkMap.Add((int)ChunkHeader.W3D_CHUNK_DAZZLE, dazzleChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_DAZZLE_NAME, dazzleNameChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_DAZZLE_TYPENAME, dazzleTypeNameChunk); //Deform chunkMap.Add((int)ChunkHeader.W3D_CHUNK_DEFORM, deformChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_DEFORM_SET, deformSetChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_DEFORM_KEYFRAME, deformKeyframeChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_DEFORM_DATA, deformDataChunk); //Emitter chunkMap.Add((int)ChunkHeader.W3D_CHUNK_EMITTER, emitterChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_EMITTER_HEADER, emitterHeaderChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_EMITTER_USER_DATA, emitterUserDataChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_EMITTER_INFO, emitterInfoChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_EMITTER_INFOV2, emitterInfo2Chunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_EMITTER_PROPS, emitterPropsChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_EMITTER_LINE_PROPERTIES, emitterLinePropertiesChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_EMITTER_ROTATION_KEYFRAMES, emitterRotationKeyframesChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_EMITTER_FRAME_KEYFRAMES, emitterFrameKeyFramesChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_EMITTER_BLUR_TIME_KEYFRAMES, emitterBlurTimeKeyFramesChunk); // Mesh chunkMap.Add((int)ChunkHeader.W3D_CHUNK_MESH, meshChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_MESH_HEADER3, meshHeader3Chunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_VERTICES, verticesChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_VERTEX_NORMALS, vertexNormalsChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_TRIANGLES, trianglesChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_VERTEX_SHADE_INDICES, vertexShadeIndicesChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_MATERIAL_INFO, materialInfoChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_MESH_USER_TEXT, meshUserTextChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_VERTEX_MATERIALS, vertexMaterialsChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_VERTEX_MATERIAL, vertexMaterialChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_VERTEX_MATERIAL_NAME, vertexMaterialNameChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_VERTEX_MATERIAL_INFO, vertexMaterialInfoChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_SHADERS, shadersChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_TEXTURES, texturesChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_TEXTURE, textureChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_TEXTURE_NAME, textureNameChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_TEXTURE_INFO, textureInfoChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_MATERIAL_PASS, materialPassChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_TEXTURE_STAGE, textureStageChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_TEXTURE_IDS, textureIdsChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_STAGE_TEXCOORDS, stageTexCoordsChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_VERTEX_MATERIAL_IDS, vertexMaterialIdsChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_VERTEX_MAPPER_ARGS0, vertexMapperArgs0Chunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_VERTEX_MAPPER_ARGS1, vertexMapperArgs1Chunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_SHADER_IDS, shaderIdsChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_VERTEX_INFLUENCES, vertexInfluencesChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_AABTREE, aabTreeChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_AABTREE_HEADER, aabTreeHeaderChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_AABTREE_POLYINDICES, aabTreePolyIndicesChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_AABTREE_NODES, aabTreeNodesChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_DCG, dcgChunk); //Primitives chunkMap.Add((int)ChunkHeader.W3D_CHUNK_BOX, boxChunk); //Hierarchy chunkMap.Add((int)ChunkHeader.W3D_CHUNK_HIERARCHY, hierarchyChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_HIERARCHY_HEADER, hierarchyHeaderChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_PIVOTS, pivotsChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_PIVOT_FIXUPS, pivotFixupsChunk); //HLod chunkMap.Add((int)ChunkHeader.W3D_CHUNK_HLOD, hlodChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_HLOD_HEADER, hlodHeaderChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_HLOD_LOD_ARRAY, hlodLodArrayChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_HLOD_SUB_OBJECT_ARRAY_HEADER, hlodSubObjectArrayHeaderChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_HLOD_SUB_OBJECT, hlodSubObjectChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_HLOD_AGGREGATE_ARRAY, hLodAggregateArrayChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_HLOD_PROXY_ARRAY, hlodProxyArrayChunk); //HModel chunkMap.Add((int)ChunkHeader.W3D_CHUNK_HMODEL, hModelChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_HMODEL_HEADER, hModelHeaderChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_HMODEL_AUX_DATA, hModelAuxDataChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_NODE, nodeChunk); //Optional chunkMap.Add((int)ChunkHeader.W3D_CHUNK_PRELIT_UNLIT, prelitUnlitChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_PRELIT_VERTEX, prelitVertexChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_PRELIT_LIGHTMAP_MULTI_PASS, prelitLightMultiPassChunk); chunkMap.Add((int)ChunkHeader.W3D_CHUNK_PRELIT_LIGHTMAP_MULTI_TEXTURE, prelitLightMultiTextureChunk); }
public static MeshChunk[] ChunkTerrain(Terrain terrainObj, int xChunks, int zChunks, int bladesPerChunk, float expandAmnt, float bladeHeight) { TerrainData terrain = terrainObj.terrainData; Vector3 terrainScale = terrain.size; Vector3 chunkSize = new Vector3(terrainScale.x / xChunks, terrainScale.y * 0.5f, terrainScale.z / zChunks); Vector3 halfChunkSize = chunkSize * 0.5f; MeshChunk[] chunks = new MeshChunk[xChunks * zChunks]; int w = terrain.heightmapWidth - 1; int h = terrain.heightmapHeight - 1; float cWf = w / (float)xChunks; float cHf = h / (float)zChunks; int cW = (int)cWf; int cH = (int)cHf; int index = 0; for (int z = 0; z < zChunks; z++) { for (int x = 0; x < xChunks; x++) { float[,] tHeights = terrain.GetHeights((int)(cWf * x), (int)(cHf * z), cW, cH); float maxHeight = 0; float minHeight = 1; foreach (float tH in tHeights) { if (tH > maxHeight) maxHeight = tH; if (tH < minHeight) minHeight = tH; } MaterialPropertyBlock propBlock = new MaterialPropertyBlock(); Vector3 chunkPos = Vector3.Scale(chunkSize, new Vector3(x, 0, z)); Vector3 mapChunkPos = new Vector4(chunkPos.x, chunkPos.z); propBlock.SetVector("_chunkPos", mapChunkPos); chunkPos += halfChunkSize; chunkPos.y = chunkSize.y * (maxHeight + minHeight); halfChunkSize.y = chunkSize.y * (maxHeight - minHeight); Mesh cMesh = new Mesh(); cMesh.vertices = new Vector3[] { Vector3.zero }; cMesh.SetTriangles(new int[bladesPerChunk * 3], 0, false); chunks[index++] = new MeshChunk() { meshBounds = new Bounds() { center = chunkPos, extents = halfChunkSize }, worldBounds = new Bounds() { extents = halfChunkSize }, chunkPos = mapChunkPos, propertyBlock = propBlock, mesh = cMesh }; } } ExpandChunks(chunks, expandAmnt, bladeHeight); return chunks; }
public override void readData() { BinaryReader file = binaryFile.openReader(); //holds references int reference; //Holds length of lists uint listLength; //Positions Vector3[] verts; //1st channel uvs Vector2[] uvs; //second channel (lightmap) uvs Vector2[] luvs; //Make sure this is not a FX mesh (instance stream is 0) file.BaseStream.Seek(binaryFile.dataOffset + binaryFile.structs[0].fields[5].index, SeekOrigin.Begin); if (file.ReadByte() != 0) { chunks = new MeshChunk[0]; return; } //seek to the beginning of the data part of the file file.BaseStream.Seek(binaryFile.dataOffset, SeekOrigin.Begin); //get the reference to the name of the mesh //get the name of the mesh name = IOUtilities.readECString(file, binaryFile.dataOffset + file.ReadInt32()); //Get the reference to the list of chunks file.BaseStream.Seek(binaryFile.dataOffset + binaryFile.structs[0].fields[1].index, SeekOrigin.Begin); reference = file.ReadInt32(); file.BaseStream.Seek(binaryFile.dataOffset + reference, SeekOrigin.Begin); listLength = file.ReadUInt32(); //Save the current position for the loop long startPosition = file.BaseStream.Position; //Make an array of chunks of the correct size chunks = new MeshChunk[listLength]; int triangleNum = 0; //Create all the chunks for (int i = 0; i < listLength; i++) { file.BaseStream.Seek(startPosition + (i * 4), SeekOrigin.Begin); file.BaseStream.Seek(binaryFile.dataOffset + file.ReadInt32(), SeekOrigin.Begin); chunks[i] = new MeshChunk(file, binaryFile.dataOffset, binaryFile.structs[4], binaryFile.structs[1]); triangleNum += (int)chunks[i].indexCount / 3; } triangleNum = 0; //Seek to the vertex data position file.BaseStream.Seek(binaryFile.dataOffset + binaryFile.structs[0].fields[2].index, SeekOrigin.Begin); //Get the reference to the list long vertexOffset = file.ReadUInt32() + binaryFile.dataOffset + 4; //Seek to the index data position file.BaseStream.Seek(binaryFile.dataOffset + binaryFile.structs[0].fields[3].index, SeekOrigin.Begin); //Get the reference to the list long indexOffset = file.ReadUInt32() + binaryFile.dataOffset + 4; //Index variables for triangles ushort index1, index2, index3; //For each chunk read in vertex data for (int i = 0; i < chunks.Length; i++) { verts = new Vector3[chunks[i].vertexCount]; uvs = new Vector2[chunks[i].vertexCount]; luvs = new Vector2[chunks[i].vertexCount]; //Read in the vertex data for (int j = 0; j < chunks[i].vertexCount; j++) { int vertArrayIndex = j * (chunks[i].vertexElementCount); int positionIndex = vertArrayIndex; int normalIndex = vertArrayIndex + 3; int uvIndex = vertArrayIndex + 6; long currentIndex = vertexOffset + chunks[i].vertexOffset + (chunks[i].vertexSize * j); //Read in the positions file.BaseStream.Seek(currentIndex + chunks[i].positionOffset, SeekOrigin.Begin); //Put them in the vert array verts[j] = new Vector3(IOUtilities.readFloat16(file), IOUtilities.readFloat16(file), IOUtilities.readFloat16(file)); //Put them in the chunk for easy rendering chunks[i].verts[positionIndex] = verts[j].X; chunks[i].verts[positionIndex + 1] = verts[j].Y; chunks[i].verts[positionIndex + 2] = verts[j].Z; //Read in the normals for rendering only, we make our own normals later file.BaseStream.Seek(currentIndex + chunks[i].normalOffset, SeekOrigin.Begin); chunks[i].verts[normalIndex] = IOUtilities.readFloat16(file); chunks[i].verts[normalIndex + 1] = IOUtilities.readFloat16(file); chunks[i].verts[normalIndex + 2] = IOUtilities.readFloat16(file); //Read in the uvs file.BaseStream.Seek(currentIndex + chunks[i].textureOffset, SeekOrigin.Begin); uvs[j] = new Vector2(IOUtilities.readFloat16(file), IOUtilities.readFloat16(file)); //Put them in the chunk for easy rendering chunks[i].verts[uvIndex] = uvs[j].X; chunks[i].verts[uvIndex + 1] = uvs[j].Y; //If there are a second set, read them in too if (chunks[i].usesTwoTexCoords) { file.BaseStream.Seek(currentIndex + chunks[i].texture2Offset, SeekOrigin.Begin); luvs[j] = new Vector2(IOUtilities.readFloat16(file), IOUtilities.readFloat16(file)); } } //Seek to index data (skipping the length int at beginning) file.BaseStream.Seek(indexOffset, SeekOrigin.Begin); for (int j = 0; j < chunks[i].indexCount / 3; j++) { int indexIndex = j * 3; //Read in the indices index1 = file.ReadUInt16(); index2 = file.ReadUInt16(); index3 = file.ReadUInt16(); chunks[i].indices[indexIndex] = index1; chunks[i].indices[indexIndex + 1] = index2; chunks[i].indices[indexIndex + 2] = index3; //If lightmap coords are specified make a triangle with them if (chunks[i].usesTwoTexCoords) { chunks[i].tris[j] = new Triangle(verts[index1], verts[index2], verts[index3], uvs[index1], uvs[index2], uvs[index3], luvs[index1], luvs[index2], luvs[index3]); } else { //Otherwise make one without them chunks[i].tris[j] = new Triangle(verts[index1], verts[index2], verts[index3], uvs[index1], uvs[index2], uvs[index3]); } //Calculate the area of the triangle and add it to the total area of the mesh chunks[i].area += 0.5 * Vector3.Cross(chunks[i].tris[j].y - chunks[i].tris[j].x, chunks[i].tris[j].z - chunks[i].tris[j].x).Length; //Increase offset by 3 indices (2 bytes each) indexOffset += 6; } } //Close the file file.Close(); }
public override void readData() { int reference, length; long startOfList; //Get the binary reader BinaryReader file = binaryFile.openReader(); //Set up the struct definitions setStructDefinitions(); //Get the sector ID file.BaseStream.Seek(binaryFile.dataOffset + infoStruct.fields[SECTOR_ID_INDEX].index, SeekOrigin.Begin); _sectorID = file.ReadInt32(); name = "Sector " + sectorID; /*----------MAP VERTS----------*/ //Get the reference to the map vertex list and go there file.BaseStream.Seek(binaryFile.dataOffset + infoStruct.fields[MAP_VERTEX_LIST_INDEX].index, SeekOrigin.Begin); reference = file.ReadInt32(); file.BaseStream.Seek(binaryFile.dataOffset + reference, SeekOrigin.Begin); //Fill the map vertex list with all the map verts length = file.ReadInt32(); _mapVerts = new List <TerrainMapVertex>(length); startOfList = file.BaseStream.Position; for (int i = 0; i < length; i++) { //Seek to the next struct in the list file.BaseStream.Seek(startOfList + (i * mapVertexStruct.structSize), SeekOrigin.Begin); //Add it to the list _mapVerts.Add(new TerrainMapVertex(mapVertexStruct, file)); } /*----------MAP EDGES----------*/ //Get the reference to the map edge list and go there file.BaseStream.Seek(binaryFile.dataOffset + infoStruct.fields[MAP_EDGE_LIST_INDEX].index, SeekOrigin.Begin); reference = file.ReadInt32(); file.BaseStream.Seek(binaryFile.dataOffset + reference, SeekOrigin.Begin); //Fill the map edge list with all the map edges length = file.ReadInt32(); _mapEdges = new List <TerrainMapEdge>(length); startOfList = file.BaseStream.Position; TerrainMapEdge tempEdge; for (int i = 0; i < length; i++) { //Seek to the next struct in the list file.BaseStream.Seek(startOfList + (i * mapEdgeStruct.structSize), SeekOrigin.Begin); //Create the edge tempEdge = new TerrainMapEdge(mapEdgeStruct, file); //Get the actual index in the array of the map vert for (int j = 0; j < _mapVerts.Count; j++) { if (_mapVerts[j].id == tempEdge.startVertexIndex) { tempEdge.startVertexIndex = j; break; } } //Add it to the list _mapEdges.Add(tempEdge); } /*----------MAP FACES----------*/ //Get the reference to the map face list and go there file.BaseStream.Seek(binaryFile.dataOffset + infoStruct.fields[MAP_FACE_LIST_INDEX].index, SeekOrigin.Begin); reference = file.ReadInt32(); file.BaseStream.Seek(binaryFile.dataOffset + reference, SeekOrigin.Begin); //Fill the map face list with all the map faces length = file.ReadInt32(); _mapFaces = new List <TerrainMapFace>(length); startOfList = file.BaseStream.Position; TerrainMapFace tempFace; for (int i = 0; i < length; i++) { //Seek to the next struct in the list file.BaseStream.Seek(startOfList + (i * mapFaceStruct.structSize), SeekOrigin.Begin); //Create the face tempFace = new TerrainMapFace(mapFaceStruct, file); //Find the actual edge indices for (int edgeIndex = 0; edgeIndex < 3; edgeIndex++) { for (int j = 0; j < _mapEdges.Count; j++) { if (tempFace[edgeIndex] == _mapEdges[j].id) { tempFace[edgeIndex] = j; break; } } } //Add it to the list _mapFaces.Add(tempFace); } /*----------MESH VERTS----------*/ //Get the reference to the mesh vertex list and go there file.BaseStream.Seek(binaryFile.dataOffset + infoStruct.fields[MESH_VERTEX_LIST_INDEX].index, SeekOrigin.Begin); reference = file.ReadInt32(); file.BaseStream.Seek(binaryFile.dataOffset + reference, SeekOrigin.Begin); //Fill the vertex list with all the vertex length = file.ReadInt32(); _verts = new List <TerrainMeshVertex>(length); startOfList = file.BaseStream.Position; for (int i = 0; i < length; i++) { //Seek to the next struct in the list file.BaseStream.Seek(startOfList + (i * meshVertexStruct.structSize), SeekOrigin.Begin); //Add it to the list _verts.Add(new TerrainMeshVertex(meshVertexStruct, file)); } /*----------MESH EDGES----------*/ //Get the reference to the mesh edge list and go there file.BaseStream.Seek(binaryFile.dataOffset + infoStruct.fields[MESH_EDGE_LIST_INDEX].index, SeekOrigin.Begin); reference = file.ReadInt32(); file.BaseStream.Seek(binaryFile.dataOffset + reference, SeekOrigin.Begin); //Fill the edge list with all the edge length = file.ReadInt32(); _edges = new List <TerrainMeshEdge>(length); startOfList = file.BaseStream.Position; TerrainMeshEdge tempMeshEdge; for (int i = 0; i < length; i++) { //Seek to the next struct in the list file.BaseStream.Seek(startOfList + (i * meshEdgeStruct.structSize), SeekOrigin.Begin); //Create the edge tempMeshEdge = new TerrainMeshEdge(meshEdgeStruct, file); //Get the actual index in the array of the mesh vert for (int j = 0; j < _mapVerts.Count; j++) { if (_verts[j].id == tempMeshEdge.startVertexIndex) { tempMeshEdge.startVertexIndex = j; break; } } //Add it to the list _edges.Add(tempMeshEdge); } /*----------MESH FACES----------*/ //Get the reference to the mesh face list and go there file.BaseStream.Seek(binaryFile.dataOffset + infoStruct.fields[MESH_FACE_LIST_INDEX].index, SeekOrigin.Begin); reference = file.ReadInt32(); file.BaseStream.Seek(binaryFile.dataOffset + reference, SeekOrigin.Begin); //Fill the face list with all the faces length = file.ReadInt32(); _faces = new List <TerrainMeshFace>(length); startOfList = file.BaseStream.Position; TerrainMeshFace tempMeshFace; for (int i = 0; i < length; i++) { //Seek to the next struct in the list file.BaseStream.Seek(startOfList + (i * meshFaceStruct.structSize), SeekOrigin.Begin); //Make the face tempMeshFace = new TerrainMeshFace(meshFaceStruct, file); //Find the actual edge indices for (int edgeIndex = 0; edgeIndex < 3; edgeIndex++) { for (int j = 0; j < _edges.Count; j++) { if (tempMeshFace[edgeIndex] == _edges[j].id) { tempMeshFace[edgeIndex] = j; break; } } } //Find the actual map face index for (int j = 0; j < _mapFaces.Count; j++) { if (tempMeshFace.mapId == _mapFaces[j].id) { tempMeshFace.mapId = j; break; } } //Add it to the list _faces.Add(tempMeshFace); } file.Close(); chunks = new MeshChunk[1]; Triangle[] tris = new Triangle[faces.Count]; //Hold temporary vertex values Vector3 x, y, z; Vector2 u, v, w; //For each faces make a triangle for (int i = 0; i < faces.Count; i++) { //Get the mesh coordinates x = verts[edges[faces[i].edges[0]].startVertexIndex].position; y = verts[edges[faces[i].edges[1]].startVertexIndex].position; z = verts[edges[faces[i].edges[2]].startVertexIndex].position; //Get the map coordinates (lightmap coordinates are the same) u = mapVerts[mapEdges[mapFaces[faces[i].mapId].edges[0]].startVertexIndex].position.Xy; v = mapVerts[mapEdges[mapFaces[faces[i].mapId].edges[1]].startVertexIndex].position.Xy; w = mapVerts[mapEdges[mapFaces[faces[i].mapId].edges[2]].startVertexIndex].position.Xy; //Make the triangle tris[i] = new Triangle(x, y, z, u, v, w, u, v, w); } chunks[0] = new MeshChunk(tris); chunks[0].casts = true; chunks[0].receives = true; }
void discard_chunk(MeshChunk m) { m.submesh.Destroy(); m.submesh = null; m.current_count = 0; }
static Color BrakeOnColor = new Color(158, 110, 6); //color of brake-off light color... public CarMesh(MeshChunk meshChunk, BitmapChunk bmpChunk, Color brakeColor) : base(meshChunk, bmpChunk) { foreach (var poly in _polys) { switch (poly.Label) { case "rt_rear": _rightRearWheel = poly; break; case "lt_rear": _leftRearWheel = poly; break; case "rt_frnt": _rightFrontWheel = poly; break; case "lt_frnt": _leftFrontWheel = poly; break; case "bkll": _leftBrakeLight = poly; break; case "bklr": _rightBrakeLight = poly; break; } } var tyreEntry = bmpChunk.FindByName("tyr1"); if (tyreEntry != null) { _wheelTexture = tyreEntry.Texture; } // This seems like it should be done in a shader but I couldn't get it to work well enough // (dealing with original paletted colors doesn't work so well in a texture stretched over a polygon) var rsidPoly = _polys.FirstOrDefault(a => a.TextureName == "rsid"); if (rsidPoly != null) { // Generate a new texture for brake lights on. Color[] pixels = new Color[rsidPoly.Texture.Width * rsidPoly.Texture.Height]; rsidPoly.Texture.GetData <Color>(pixels); for (int i = 0; i < pixels.Length; i++) { if (pixels[i] == brakeColor) { pixels[i] = BrakeOnColor; } } _brakeOnTexture = new Texture2D(Engine.Instance.Device, rsidPoly.Texture.Width, rsidPoly.Texture.Height); _brakeOnTexture.SetData <Color>(pixels); // Generate a new texture for brake lights off. for (int i = 0; i < pixels.Length; i++) { if (pixels[i] == BrakeOnColor) { pixels[i] = BrakeOffColor; } } _brakeOffTexture = new Texture2D(Engine.Instance.Device, _leftBrakeLight.Texture.Width, _leftBrakeLight.Texture.Height); _brakeOffTexture.SetData <Color>(pixels); } }
public override MeshChunk MeshBlock(Chunk c, int x, int y, int z, MeshChunk m) { return(m); }
public Mesh(DatDigger.Sections.Model.MeshChunk mesh, Cache.VarEquip varEquip) : base() { this.mesh = mesh; this.varEquip = varEquip; }