public TerrainPatchBuilder( ) { int numVertices = 0; for ( int level = 0; level < MaxLodLevels; ++level ) { numVertices += LevelPoolSize( level ) * NumberOfLevelVertices( level ); } VertexBufferFormat format = new VertexBufferFormat( ); format.Add( VertexFieldSemantic.Position, VertexFieldElementTypeId.Float32, 3 ); format.Add( VertexFieldSemantic.Normal, VertexFieldElementTypeId.Float32, 3 ); GraphicsLog.Info( "Allocating terrain patch builder VBO: {0} vertices in format {1}", numVertices, format ); m_Buffer = Graphics.Factory.CreateVertexBuffer( ); m_Buffer.Create( format, numVertices ); int curVertexIndex = 0; for ( int level = 0; level < MaxLodLevels; ++level ) { Lod newLod = new Lod( ); m_LodLevels[ level ] = newLod; int numLevelVertices = NumberOfLevelVertices( level ); int poolSize = LevelPoolSize( level ); for ( int poolIndex = 0; poolIndex < poolSize; ++poolIndex ) { newLod.VbPool.Add( curVertexIndex ); curVertexIndex += numLevelVertices; } // NOTE: BP: BABY P SAYS HELLO } }
/// <summary> /// Adjusts the internal <see cref="LevelsOfDetail"/> array to match /// the passed count. If the passed count is greater than <see cref="LevelsOfDetail"/>'s /// count, <see cref="LevelsOfDetail"/> is expanded. If it is /// less than <see cref="LevelsOfDetail"/>'s count, <see cref="LevelsOfDetail"/> is /// truncated to match the passed count. /// </summary> /// <param name="count">Count to match <see cref="LevelsOfDetail"/> with.</param> public void AdjustLevelsToCount(int count) { if (LevelsOfDetail == null) { LevelsOfDetail = new Lod[count]; } if (count > LevelsOfDetail.Length) { Lod[] tmp = new Lod[count]; LevelsOfDetail.CopyTo(tmp, 0); //New indices should have an increasing StartRadius int lastStartRadius = LevelsOfDetail[count - (count - LevelsOfDetail.Length) - 1].StartRadius; for (int i = LevelsOfDetail.Length; i < count; i++) { lastStartRadius++; tmp[i] = new Lod(lastStartRadius, 129); } LevelsOfDetail = tmp; } if (count < LevelsOfDetail.Length) { Lod[] tmp = new Lod[count]; for (int i = 0; i < count; i++) { tmp[i] = LevelsOfDetail[i]; } LevelsOfDetail = tmp; } }
protected override Task <TiledLayerInitializationInfo> OnInitializeTiledLayerRequestedAsync() { return(Task.Run(() => { var extent = new Envelope(8683687.93695427, 2379976.95194823, 14945347.5840909, 5762088.12795044, SpatialReferences.WebMercator); //Envelope extent = new Envelope(-20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892, SpatialReferences.WebMercator); IEnumerable <Lod> lods = null; if (lods == null) { double resolution = 156543.03392804062; double scale = (resolution * 96.0) * 39.37; Lod[] lodArray = new Lod[0x13]; for (int i = 0; i < lodArray.Length; i++) { lodArray[i] = new Lod(resolution, scale); resolution /= 2.0; scale /= 2.0; } lods = lodArray; } int width = 256; int height = 256; float dpi = 96f; double originX = -20037508.3427892; double originY = 20037508.3427892; return new TiledLayerInitializationInfo(width, height, originX, originY, extent, dpi, lods); })); }
public LodData() { if (LevelsOfDetail == null) { LevelsOfDetail = new Lod[1]; LevelsOfDetail[0] = new Lod(0, 129); } }
public void BuildCollision(ResourceTypes.Collisions.Collision.NXSStruct nxsData, string name) { lods = new Lod[1]; lods[0] = new Lod(); lods[0].Vertices = new Vertex[nxsData.Data.Vertices.Length]; lods[0].Indices = new ushort[nxsData.Data.Indices.Length]; for (int x = 0; x != nxsData.Data.Indices.Length; x++) { lods[0].Indices[x] = (ushort)nxsData.Data.Indices[x]; } for (int x = 0; x != lods[0].Vertices.Length; x++) { lods[0].Vertices[x] = new Vertex(); lods[0].Vertices[x].Position = nxsData.Data.Vertices[x]; } string[] matNames = new string[nxsData.Sections.Length]; List <ushort>[] matInds = new List <ushort> [nxsData.Sections.Length]; for (int t = 0; t != matInds.Length; t++) { matInds[t] = new List <ushort>(); } lods[0].Parts = new ModelPart[nxsData.Sections.Length]; int indIDX = 0; for (int t = 0; t != nxsData.Data.Materials.Length; t++) { for (int g = 0; g != nxsData.Sections.Length; g++) { if ((int)nxsData.Data.Materials[t] == (nxsData.Sections[g].Unk1 + 2)) { matNames[g] = nxsData.Data.Materials[t].ToString(); matInds[g].Add((ushort)nxsData.Data.Indices[indIDX]); matInds[g].Add((ushort)nxsData.Data.Indices[indIDX + 1]); matInds[g].Add((ushort)nxsData.Data.Indices[indIDX + 2]); indIDX += 3; } } } List <ushort> inds = new List <ushort>(); for (int x = 0; x != lods[0].Parts.Length; x++) { lods[0].Parts[x] = new ModelPart(); lods[0].Parts[x].Material = matNames[x]; lods[0].Parts[x].StartIndex = (uint)inds.Count; inds.AddRange(matInds[x]); lods[0].Parts[x].NumFaces = (uint)Math.Abs(inds.Count - (matInds[x].Count / 3)); } this.name = name; lods[0].Indices = inds.ToArray(); }
public virtual uint GetWordCount() { uint wordCount = 1; if (Enumerant.Bias == (Value & Enumerant.Bias)) { wordCount += Bias.GetWordCount(); } if (Enumerant.Lod == (Value & Enumerant.Lod)) { wordCount += Lod.GetWordCount(); } if (Enumerant.Grad == (Value & Enumerant.Grad)) { wordCount += Grad1.GetWordCount(); wordCount += Grad2.GetWordCount(); } if (Enumerant.ConstOffset == (Value & Enumerant.ConstOffset)) { wordCount += ConstOffset.GetWordCount(); } if (Enumerant.Offset == (Value & Enumerant.Offset)) { wordCount += Offset.GetWordCount(); } if (Enumerant.ConstOffsets == (Value & Enumerant.ConstOffsets)) { wordCount += ConstOffsets.GetWordCount(); } if (Enumerant.Sample == (Value & Enumerant.Sample)) { wordCount += Sample.GetWordCount(); } if (Enumerant.MinLod == (Value & Enumerant.MinLod)) { wordCount += MinLod.GetWordCount(); } if (Enumerant.MakeTexelAvailable == (Value & Enumerant.MakeTexelAvailable)) { wordCount += MakeTexelAvailable.GetWordCount(); } if (Enumerant.MakeTexelAvailableKHR == (Value & Enumerant.MakeTexelAvailableKHR)) { wordCount += MakeTexelAvailableKHR.GetWordCount(); } if (Enumerant.MakeTexelVisible == (Value & Enumerant.MakeTexelVisible)) { wordCount += MakeTexelVisible.GetWordCount(); } if (Enumerant.MakeTexelVisibleKHR == (Value & Enumerant.MakeTexelVisibleKHR)) { wordCount += MakeTexelVisibleKHR.GetWordCount(); } return(wordCount); }
public void Write(WordWriter writer) { writer.WriteWord((uint)Value); if (Enumerant.Bias == (Value & Enumerant.Bias)) { Bias.Write(writer); } if (Enumerant.Lod == (Value & Enumerant.Lod)) { Lod.Write(writer); } if (Enumerant.Grad == (Value & Enumerant.Grad)) { Grad1.Write(writer); Grad2.Write(writer); } if (Enumerant.ConstOffset == (Value & Enumerant.ConstOffset)) { ConstOffset.Write(writer); } if (Enumerant.Offset == (Value & Enumerant.Offset)) { Offset.Write(writer); } if (Enumerant.ConstOffsets == (Value & Enumerant.ConstOffsets)) { ConstOffsets.Write(writer); } if (Enumerant.Sample == (Value & Enumerant.Sample)) { Sample.Write(writer); } if (Enumerant.MinLod == (Value & Enumerant.MinLod)) { MinLod.Write(writer); } if (Enumerant.MakeTexelAvailable == (Value & Enumerant.MakeTexelAvailable)) { MakeTexelAvailable.Write(writer); } if (Enumerant.MakeTexelAvailableKHR == (Value & Enumerant.MakeTexelAvailableKHR)) { MakeTexelAvailableKHR.Write(writer); } if (Enumerant.MakeTexelVisible == (Value & Enumerant.MakeTexelVisible)) { MakeTexelVisible.Write(writer); } if (Enumerant.MakeTexelVisibleKHR == (Value & Enumerant.MakeTexelVisibleKHR)) { MakeTexelVisibleKHR.Write(writer); } }
public void GenerateEvent(EventType type, bool useTimer = true) { if (!ServerManager.Instance.StartedEvents.Contains(type)) { Task.Factory.StartNew(async() => { ServerManager.Instance.StartedEvents.Add(type); switch (type) { case EventType.RANKINGREFRESH: ServerManager.Instance.RefreshRanking(); break; case EventType.LOD: Lod.GenerateLod(); break; case EventType.MINILANDREFRESHEVENT: MinilandRefresh.GenerateMinilandEvent(); break; case EventType.INSTANTBATTLE: InstantBattle.GenerateInstantBattle(useTimer); break; case EventType.TALENTARENA: //ArenaEvent.GenerateTalentArena(); break; case EventType.LODDH: Lod.GenerateLod(35); break; case EventType.ICEBREAKER: IceBreaker.GenerateIceBreaker(useTimer); break; case EventType.BATTLEROYAL: //BattleRoyaleManager.Instance.Prepare(useTimer); break; case EventType.CALIGOR: await Caligor.GenerateCaligor(); break; case EventType.ACT4SHIP: Act4Ship.GenerateAct4Ship(FactionType.Angel); Act4Ship.GenerateAct4Ship(FactionType.Demon); break; } }); } }
public Collision.CollisionModel BuildFromM2TStructure(M2TStructure sourceModel) { Collision.CollisionModel collisionModel = new Collision.CollisionModel(); collisionModel.Hash = FNV64.Hash(sourceModel.Name); Lod modelLod = sourceModel.Lods[0]; IList <Vector3> vertexList = modelLod.Vertices.Select(v => v.Position).ToList(); // Material sections should be unique and sorted by material var sortedParts = new SortedDictionary <ushort, List <ModelPart> >( modelLod.Parts .GroupBy(p => MaterialToIndex(p.Material)) .ToDictionary(p => p.Key, p => p.ToList()) ); collisionModel.Sections = new List <Collision.Section>(sortedParts.Count); IList <TriangleMesh.Triangle> orderedTriangles = new List <TriangleMesh.Triangle>(modelLod.Indices.Length / 3); IList <ushort> materials = new List <ushort>(); foreach (var part in sortedParts) { var sameMaterialParts = part.Value; collisionModel.Sections.Add(new Collision.Section { Material = part.Key - 2, Start = orderedTriangles.Count * 3, NumEdges = (int)sameMaterialParts.Sum(p => p.NumFaces) * 3 }); foreach (var sameMaterialPart in sameMaterialParts) { var start = (int)sameMaterialPart.StartIndex; var end = start + sameMaterialPart.NumFaces * 3; for (int ci = start; ci < end; ci += 3) { orderedTriangles.Add(new TriangleMesh.Triangle( modelLod.Indices[ci], modelLod.Indices[ci + 1], modelLod.Indices[ci + 2] )); materials.Add(part.Key); } } } collisionModel.Mesh = new TriangleMeshBuilder().Build(vertexList, orderedTriangles, materials); return(collisionModel); }
public static void GenerateEvent(EventType type) { if (!ServerManager.Instance.StartedEvents.Contains(type)) { Task.Factory.StartNew(() => { ServerManager.Instance.StartedEvents.Add(type); switch (type) { case EventType.RankingRefresh: ServerManager.Instance.RefreshRanking(); ServerManager.Instance.StartedEvents.Remove(EventType.RankingRefresh); break; case EventType.LOD: Lod.GenerateLod(); break; case EventType.MinilandRefresh: MinilandRefresh.GenerateMinilandEvent(); break; case EventType.InstantBattle: InstantBattle.GenerateInstantBattle(); break; case EventType.LODDH: Lod.GenerateLod(35); break; case EventType.MeteoriteGame: MeteoriteGame.GenerateMeteoriteGame(); break; case EventType.Act4Ship: Act4Ship.GenerateAct4Ship(1); Act4Ship.GenerateAct4Ship(2); break; case EventType.TalentArena: TalentArena.Run(); break; case EventType.Caligor: CaligorRaid.Run(); break; } }); } }
/// <summary> /// Build Lods from retrieved data. /// </summary> public void BuildLods(FrameGeometry frameGeometry, FrameMaterial frameMaterial, VertexBuffer[] vertexBuffers, IndexBuffer[] indexBuffers) { lods = new Lod[frameGeometry.NumLods]; for (int i = 0; i != lods.Length; i++) { FrameLOD frameLod = frameGeometry.LOD[i]; lods[i] = new Lod { VertexDeclaration = frameGeometry.LOD[i].VertexDeclaration }; IndexBuffer indexBuffer = indexBuffers[i]; VertexBuffer vertexBuffer = vertexBuffers[i]; int vertexSize; Dictionary <VertexFlags, FrameLOD.VertexOffset> vertexOffsets = frameLod.GetVertexOffsets(out vertexSize); lods[i].Vertices = new Vertex[frameLod.NumVerts]; if (vertexSize * frameLod.NumVerts != vertexBuffer.Data.Length) { throw new System.Exception(); } for (int v = 0; v != lods[i].Vertices.Length; v++) { //declare data required and send to decompresser byte[] data = new byte[vertexSize]; Array.Copy(vertexBuffers[i].Data, (v * vertexSize), data, 0, vertexSize); lods[i].Vertices[v] = VertexTranslator.DecompressVertex(data, frameGeometry.LOD[i].VertexDeclaration, frameGeometry.DecompressionOffset, frameGeometry.DecompressionFactor, vertexOffsets); } lods[i].Indices = indexBuffer.GetData(); MaterialStruct[] materials = frameMaterial.Materials[i]; lods[i].Parts = new ModelPart[materials.Length]; for (int x = 0; x != materials.Length; x++) { if (string.IsNullOrEmpty(materials[x].MaterialName)) { var material = MaterialsManager.LookupMaterialByHash(materials[x].MaterialHash); materials[x].MaterialName = material.GetMaterialName(); } ModelPart modelPart = new ModelPart(); modelPart.Material = materials[x].MaterialName; modelPart.StartIndex = (uint)materials[x].StartIndex; modelPart.NumFaces = (uint)materials[x].NumFaces; lods[i].Parts[x] = modelPart; } } }
public override bool PostavStroj(int paPor) { Spolocnost spol = Hra.DajInstanciu().Spolocnost; if (paPor >= 0 && paPor < aMozneStroje.Count) { Lod lodStavana = new Lod(aMozneStroje[paPor]); if (spol.UpravFinancie(-lodStavana.Cena)) { DopravnyProstriedok dp = new DopravnyProstriedok(lodStavana); spol.PridajDP(dp); PridajOdstavene(dp); } } return false; }
public void LoadBody(byte[] buffer) { System.IO.BinaryReader br = new System.IO.BinaryReader(new System.IO.MemoryStream(buffer)); int count = br.ReadInt32(); lodMats = new Lod[count]; for (int i = 0; i < count; i++) { lodMats[i] = new Lod(); int matc = br.ReadInt32(); lodMats[i].mats = new SubsetMaterial[matc]; for (int j = 0; j < matc; j++) { lodMats[i].mats[j] = new SubsetMaterial(); lodMats[i].mats[j].DiffuseTextureName = br.ReadPackString(); } } }
static public void UnInitializeFactories() { Node.UnInitializeFactory(); Group.UnInitializeFactory(); Transform.UnInitializeFactory(); Lod.UnInitializeFactory(); State.UnInitializeFactory(); Geometry.UnInitializeFactory(); Scene.UnInitializeFactory(); PerspCamera.UnInitializeFactory(); DynamicLoader.UnInitializeFactory(); CullTraverseAction.UnInitializeFactory(); NodeAction.UnInitializeFactory(); Context.UnInitializeFactory(); Texture.UnInitializeFactory(); Roi.UnInitializeFactory(); RoiNode.UnInitializeFactory(); ExtRef.UnInitializeFactory(); }
private static Region CreateRegion() { var box = new LatLonAltBox(); box.North = 1; box.South = 2; box.East = 3; box.West = 4; var lod = new Lod(); lod.MinimumPixels = 100; var region = new Region(); region.LatLonAltBox = box; region.LevelOfDetail = lod; return(region); }
private ImmutableArray <Lod> LoadLods(BinaryReader reader, int count) { Lod[] lods = new Lod[count]; for (int i = 0; i < count; ++i) { long offset = reader.BaseStream.Position; int meshCount = reader.ReadInt32(); long meshOffset = offset + reader.ReadInt32(); float switchPoint = reader.ReadSingle(); long save = reader.BaseStream.Position; reader.BaseStream.Position = meshOffset; ImmutableArray <Mesh> meshes = LoadMeshes(reader, meshCount); reader.BaseStream.Position = save; lods[i] = new Lod(switchPoint, meshes); } return(new ImmutableArray <Lod>(lods)); }
static public void InitializeFactories() { Node.InitializeFactory(); Group.InitializeFactory(); Transform.InitializeFactory(); Lod.InitializeFactory(); State.InitializeFactory(); Geometry.InitializeFactory(); Scene.InitializeFactory(); PerspCamera.InitializeFactory(); DynamicLoader.InitializeFactory(); CullTraverseAction.InitializeFactory(); NodeAction.InitializeFactory(); Context.InitializeFactory(); Texture.InitializeFactory(); Roi.InitializeFactory(); RoiNode.InitializeFactory(); ExtRef.InitializeFactory(); Crossboard.InitializeFactory(); }
public void ReadMaterials(byte[] memory) { TreeNode res = new TreeNode("Materials pos: 0x" + readerpos.ToString("X4")); Materials m = new Materials(); Mesh.InternalVersion = BitConverter.ToInt32(memory, readerpos); m.LodCount = BitConverter.ToInt32(memory, readerpos + 4); res.Nodes.Add("LodCount : " + m.LodCount); TreeNode t1 = new TreeNode("Lods"); readerpos += 8; m.Lods = new List<Lod>(); m.MatInst = new List<MaterialInstanceConstant>(); for (int i = 0; i < m.LodCount; i++) { Lod l = new Lod(); l.Guid = new byte[16]; string t = "Guid: "; for (int j = 0; j < 16; j++) { l.Guid[j] = memory[readerpos]; t += l.Guid[j].ToString("X2") + " "; readerpos++; } t1.Nodes.Add(new TreeNode(t)); l.SectionCount = BitConverter.ToInt32(memory, readerpos); t1.Nodes.Add(new TreeNode("Section Count : " + l.SectionCount.ToString())); l.Sections = new List<Section>(); readerpos += 4; TreeNode t2 = new TreeNode("Sections"); for (int j = 0; j < l.SectionCount; j++) { Section s = new Section(); string q = "Section [" + j.ToString() + "] : {(Name)"; //s.Name = BitConverter.ToInt32(memory, readerpos); //if (s.Name > 0) // m.MatInst.Add(new MaterialInstanceConstant(pcc, s.Name - 1)); // q += pcc.getObjectName(s.Name) + " ; "; //else q += s.Name.ToString() + " ; "; s.Unk1 = BitConverter.ToInt32(memory, readerpos + 4); q += s.Unk1.ToString() + " ; "; s.Unk2 = BitConverter.ToInt32(memory, readerpos + 8); q += s.Unk2.ToString() + " ; "; s.Unk3 = BitConverter.ToInt32(memory, readerpos + 12); q += s.Unk3.ToString() + " ; (FirstIdx)"; s.FirstIdx1 = BitConverter.ToInt32(memory, readerpos + 16); q += s.FirstIdx1.ToString() + " ; (NumFaces)"; s.NumFaces1 = BitConverter.ToInt32(memory, readerpos + 20); q += s.NumFaces1.ToString() + " ; (VertexMin)"; s.MatEff1 = BitConverter.ToInt32(memory, readerpos + 24); q += s.MatEff1.ToString() + " ; (VertexMax)"; s.MatEff2 = BitConverter.ToInt32(memory, readerpos + 28); q += s.MatEff2.ToString() + " ; "; s.Unk4 = BitConverter.ToInt32(memory, readerpos + 32); q += s.Unk4.ToString() + " ; "; s.Unk5 = BitConverter.ToInt32(memory, readerpos + 36); q += s.Unk5.ToString() + " ; (FirstIdx)"; if (s.Unk5 == 1) { s.FirstIdx2 = BitConverter.ToInt32(memory, readerpos + 40); q += s.FirstIdx2.ToString() + " ; (NumFaces)"; s.NumFaces2 = BitConverter.ToInt32(memory, readerpos + 44); q += s.NumFaces2.ToString() + " ; "; s.Unk6 = memory[readerpos + 48]; q += s.Unk6.ToString() + "}"; } else { s.Unk6 = memory[readerpos + 40]; s.FirstIdx2 = BitConverter.ToInt32(memory, readerpos + 41); q += s.FirstIdx2.ToString() + " ; (NumFaces)"; s.NumFaces2 = BitConverter.ToInt32(memory, readerpos + 45); q += s.NumFaces2.ToString() + " ; "; q += s.Unk6.ToString() + "}"; } t2.Nodes.Add(q); readerpos += 49; l.Sections.Add(s); } t1.Nodes.Add(t2); l.SizeVert = BitConverter.ToInt32(memory, readerpos); t1.Nodes.Add(new TreeNode("Size Verts : " + l.SizeVert.ToString())); l.NumVert = BitConverter.ToInt32(memory, readerpos + 4); t1.Nodes.Add(new TreeNode("Num Vert : " + l.NumVert.ToString())); l.LodCount = BitConverter.ToInt32(memory, readerpos + 8); t1.Nodes.Add(new TreeNode("Lod Count : " + l.LodCount.ToString())); if(l.Sections[0].Unk5 == 1) readerpos += 12; else readerpos += 4; m.Lods.Add(l); } res.Nodes.Add(t1); TreeNode t3 = new TreeNode("Materials"); for (int i = 0; i < m.MatInst.Count(); i++) t3.Nodes.Add(m.MatInst[i].ToTree()); res.Nodes.Add(t3); m.t = res; Mesh.Mat = m; }
public override int loadbody(BinaryReader br) { long pos = br.BaseStream.Position; int count = br.ReadInt32(); lodMats = new List<Lod>();// Lod[count]; for (int i = 0; i < count; i++) { Lod l = new Lod(); lodMats.Add(l); int matc = br.ReadInt32(); lodMats[i].mats = new List<SubsetMaterial>();// SubsetMaterial[br.ReadInt32()]; for (int j = 0; j < matc; j++) { SubsetMaterial sm = new SubsetMaterial(); sm.DiffuseTextureName = br.ReadPackString(); lodMats[i].mats.Add(sm); } } return Convert.ToInt32(br.BaseStream.Position - pos); }
public Lod AddLod() { Lod lod = new Lod(); lodMats.Add(lod); return lod; }
private ImmutableArray<Lod> LoadLods(BinaryReader reader, int count) { Lod[] lods = new Lod[count]; for (int i = 0; i < count; ++i) { long offset = reader.BaseStream.Position; int meshCount = reader.ReadInt32(); long meshOffset = offset + reader.ReadInt32(); float switchPoint = reader.ReadSingle(); long save = reader.BaseStream.Position; reader.BaseStream.Position = meshOffset; ImmutableArray<Mesh> meshes = LoadMeshes(reader, meshCount); reader.BaseStream.Position = save; lods[i] = new Lod(switchPoint, meshes); } return new ImmutableArray<Lod>(lods); }
public void ReadMaterials(byte[] memory) { Materials m = new Materials(); Mesh.InternalVersion = BitConverter.ToInt32(memory, readerpos); m.LodCount = BitConverter.ToInt32(memory, readerpos + 4); readerpos += 8; m.Lods = new List<Lod>(); for (int i = 0; i < m.LodCount; i++) { Lod l = new Lod(); l.Guid = new byte[16]; for (int j = 0; j < 16; j++) { l.Guid[j] = memory[readerpos]; readerpos++; } l.SectionCount = BitConverter.ToInt32(memory, readerpos); l.Sections = new List<Section>(); readerpos += 4; for (int j = 0; j < l.SectionCount; j++) { Section s = new Section(); s.Unk1 = BitConverter.ToInt32(memory, readerpos + 4); s.Unk2 = BitConverter.ToInt32(memory, readerpos + 8); s.Unk3 = BitConverter.ToInt32(memory, readerpos + 12); s.FirstIdx1 = BitConverter.ToInt32(memory, readerpos + 16); s.NumFaces1 = BitConverter.ToInt32(memory, readerpos + 20); s.MatEff1 = BitConverter.ToInt32(memory, readerpos + 24); s.MatEff2 = BitConverter.ToInt32(memory, readerpos + 28); s.Unk4 = BitConverter.ToInt32(memory, readerpos + 32); s.Unk5 = BitConverter.ToInt32(memory, readerpos + 36); if (s.Unk5 == 1) { s.FirstIdx2 = BitConverter.ToInt32(memory, readerpos + 40); s.NumFaces2 = BitConverter.ToInt32(memory, readerpos + 44); s.Unk6 = memory[readerpos + 48]; } else { s.Unk6 = memory[readerpos + 40]; s.FirstIdx2 = BitConverter.ToInt32(memory, readerpos + 41); s.NumFaces2 = BitConverter.ToInt32(memory, readerpos + 45); } readerpos += 49; l.Sections.Add(s); } l.SizeVert = BitConverter.ToInt32(memory, readerpos); l.NumVert = BitConverter.ToInt32(memory, readerpos + 4); l.LodCount = BitConverter.ToInt32(memory, readerpos + 8); if (l.Sections[0].Unk5 == 1) readerpos += 12; else readerpos += 4; m.Lods.Add(l); } Mesh.Mat = m; }
public void ExportToM2T(string exportPath) { // Check if the directory exists if (!Directory.Exists(exportPath)) { // Ask if we can create it DialogResult Result = MessageBox.Show("The path does not exist. Do you want to create it?", "Toolkit", MessageBoxButtons.YesNo, MessageBoxIcon.Information); if (Result == DialogResult.Yes) { Directory.CreateDirectory(exportPath); } else { // Can't export file with no valid directory. MessageBox.Show("Cannot export a mesh with no valid directory. Please change your directory.", "Toolkit", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } using (BinaryWriter writer = new BinaryWriter(File.Create(exportPath + name + ".m2t"))) { writer.Write(fileHeader.ToCharArray()); writer.Write(fileVersion); //mesh name writer.Write(name); writer.Write(isSkinned); if (isSkinned) { writer.Write((byte)skeleton.Joints.Length); for (int i = 0; i < skeleton.Joints.Length; i++) { var joint = skeleton.Joints[i]; writer.WriteString8(joint.Name); writer.Write(joint.ParentIndex); Quaternion rotation; Vector3 position, scale; joint.LocalTransform.Decompose(out scale, out rotation, out position); position.WriteToFile(writer); rotation.WriteToFile(writer); scale.WriteToFile(writer); } } //Number of Lods writer.Write((byte)lods.Length); for (int i = 0; i != lods.Length; i++) { List <string> exportLog = new List <string>(); Lod lod = lods[i]; //Write section for VertexFlags. writer.Write((int)lod.VertexDeclaration); //write length and then all vertices. writer.Write(lods[i].Vertices.Length); for (int x = 0; x != lods[i].Vertices.Length; x++) { Vertex vert = lods[i].Vertices[x]; vert.Normal = new Vector3(vert.Normal.X, vert.Normal.Y, vert.Normal.Z); if (lod.VertexDeclaration.HasFlag(VertexFlags.Position)) { vert.Position.WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.Normals)) { vert.Normal.WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.Tangent)) { vert.Tangent.WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.Skin)) { writer.Write(vert.BoneIDs); for (int z = 0; z < 4; z++) { writer.Write(vert.BoneWeights[z]); } } if (lod.VertexDeclaration.HasFlag(VertexFlags.Color)) { exportLog.Add(string.Format("{0} {1} {2} {3}", vert.Color0[0], vert.Color0[1], vert.Color0[2], vert.Color0[3])); writer.Write(vert.Color0); } if (lod.VertexDeclaration.HasFlag(VertexFlags.Color1)) { exportLog.Add(string.Format("{0} {1} {2} {3}", vert.Color1[0], vert.Color1[1], vert.Color1[2], vert.Color1[3])); writer.Write(vert.Color1); } if (lod.VertexDeclaration.HasFlag(VertexFlags.TexCoords0)) { vert.UVs[0].WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.TexCoords1)) { vert.UVs[1].WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.TexCoords2)) { vert.UVs[2].WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.ShadowTexture)) { vert.UVs[3].WriteToFile(writer); } } //write mesh count and texture names. writer.Write(lod.Parts.Length); for (int x = 0; x != lod.Parts.Length; x++) { writer.Write(lods[i].Parts[x].Material); writer.Write(lods[i].Parts[x].StartIndex); writer.Write(lods[i].Parts[x].NumFaces); } //write triangle data. writer.Write(lod.Indices.Length); for (int x = 0; x != lod.Indices.Length; x++) { writer.Write(lods[i].Indices[x]); } } } }
public void ReadFromM2T(BinaryReader reader) { if (new string(reader.ReadChars(3)) != fileHeader) { return; } if (reader.ReadByte() != fileVersion) { return; } //mesh name name = reader.ReadString(); //Number of Lods Lods = new Lod[reader.ReadByte()]; for (int i = 0; i != Lods.Length; i++) { Lods[i] = new Lod { VertexDeclaration = 0 }; if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.Position; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.Normals; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.Tangent; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.Skin; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.Color; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.TexCoords0; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.TexCoords1; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.TexCoords2; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.ShadowTexture; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.Color1; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.BBCoeffs; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.DamageGroup; } //write length and then all vertices. lods[i].Vertices = new Vertex[reader.ReadInt32()]; lods[i].NumUVChannels = 4; for (int x = 0; x != lods[i].Vertices.Length; x++) { Vertex vert = new Vertex(); vert.UVs = new Half2[lods[i].NumUVChannels]; if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.Position)) { vert.Position = Vector3Extenders.ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.Normals)) { vert.Normal = Vector3Extenders.ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.Tangent)) { vert.Tangent = Vector3Extenders.ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords0)) { vert.UVs[0] = Half2Extenders.ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords1)) { vert.UVs[1] = Half2Extenders.ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords2)) { vert.UVs[2] = Half2Extenders.ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.ShadowTexture)) { vert.UVs[3] = Half2Extenders.ReadFromFile(reader); } lods[i].Vertices[x] = vert; } //write mesh count and texture names. Lods[i].Parts = new ModelPart[reader.ReadInt32()]; for (int x = 0; x != Lods[i].Parts.Length; x++) { Lods[i].Parts[x] = new ModelPart(); Lods[i].Parts[x].Material = reader.ReadString(); ulong hash = 0; ulong.TryParse(Lods[i].Parts[x].Material, out hash); Lods[i].Parts[x].Hash = hash; Lods[i].Parts[x].StartIndex = reader.ReadUInt32(); Lods[i].Parts[x].NumFaces = reader.ReadUInt32(); } int numIndices = reader.ReadInt32(); Lods[i].Indices = new ushort[numIndices]; for (int x = 0; x != Lods[i].Indices.Length; x++) { Lods[i].Indices[x] = reader.ReadUInt16(); } Lods[i].CalculatePartBounds(); } }
//Add GameObjects to dictionary // Traverse function iterates the scene graph to build local branches on Unity GameObject Traverse(Node n, Material currentMaterial) { // We must be called in edit lock if (n == null || !n.IsValid()) { return(null); } // --------------------------- Add game object --------------------------------------- string name = n.GetName(); if (String.IsNullOrEmpty(name)) { name = n.GetNativeTypeName(); } GameObject gameObject = new GameObject(name); var nodeHandle = gameObject.AddComponent <NodeHandle>(); //nodeHandle.Renderer = Renderer; nodeHandle.node = n; nodeHandle.currentMaterial = currentMaterial; nodeHandle.ComputeShader = Settings.ComputeShader; // ---------------------------- Check material state ---------------------------------- if (n.HasState()) { State state = n.State; if (state.HasTexture(0) && state.GetMode(StateMode.TEXTURE) == StateModeActivation.ON) { gzTexture texture = state.GetTexture(0); if (!textureMaterialStorage.TryGetValue(texture.GetNativeReference(), out currentMaterial)) { if (texture.HasImage()) { ImageFormat image_format; ComponentType comp_type; uint components; uint depth; uint width; uint height; uint size; bool uncompress = false; Image image = texture.GetImage(); image_format = image.GetFormat(); image.Dispose(); switch (image_format) // Not yet { case ImageFormat.COMPRESSED_RGBA8_ETC2: if (!SystemInfo.SupportsTextureFormat(TextureFormat.ETC2_RGBA8)) { uncompress = true; } break; case ImageFormat.COMPRESSED_RGB8_ETC2: if (!SystemInfo.SupportsTextureFormat(TextureFormat.ETC2_RGB)) { uncompress = true; } break; case ImageFormat.COMPRESSED_RGBA_S3TC_DXT1: case ImageFormat.COMPRESSED_RGB_S3TC_DXT1: if (!SystemInfo.SupportsTextureFormat(TextureFormat.DXT1)) { uncompress = true; } break; case ImageFormat.COMPRESSED_RGBA_S3TC_DXT5: if (!SystemInfo.SupportsTextureFormat(TextureFormat.DXT5)) { uncompress = true; } break; } if (texture.GetMipMapImageArray(ref _image_texture_data, out size, out image_format, out comp_type, out components, out width, out height, out depth, true, uncompress)) { if (depth == 1) { if (n is Crossboard) { currentMaterial = new Material(Settings.CrossboardShader); } else { currentMaterial = new Material(Settings.DefaultShader); } TextureFormat format = TextureFormat.ARGB32; switch (comp_type) { case ComponentType.UNSIGNED_BYTE: { switch (image_format) { case ImageFormat.RGBA: format = TextureFormat.RGBA32; break; case ImageFormat.RGB: format = TextureFormat.RGB24; break; case ImageFormat.COMPRESSED_RGBA_S3TC_DXT1: case ImageFormat.COMPRESSED_RGB_S3TC_DXT1: format = TextureFormat.DXT1; break; case ImageFormat.COMPRESSED_RGBA_S3TC_DXT5: format = TextureFormat.DXT5; break; case ImageFormat.COMPRESSED_RGB8_ETC2: format = TextureFormat.ETC2_RGB; break; case ImageFormat.COMPRESSED_RGBA8_ETC2: format = TextureFormat.ETC2_RGBA8; break; default: // Issue your own error here because we can not use this texture yet return(null); } } break; default: // Issue your own error here because we can not use this texture yet return(null); } Texture2D tex = new Texture2D((int)width, (int)height, format, true); tex.LoadRawTextureData(_image_texture_data); switch (texture.MinFilter) { default: tex.filterMode = FilterMode.Point; break; case gzTexture.TextureMinFilter.LINEAR: case gzTexture.TextureMinFilter.LINEAR_MIPMAP_NEAREST: tex.filterMode = FilterMode.Bilinear; break; case gzTexture.TextureMinFilter.LINEAR_MIPMAP_LINEAR: tex.filterMode = FilterMode.Trilinear; break; } tex.Apply(texture.UseMipMaps, true); currentMaterial.mainTexture = tex; } } } // Add some kind of check for textures shared by many // Right now only for crossboards if (n is Crossboard) { textureMaterialStorage.Add(texture.GetNativeReference(), currentMaterial); } } nodeHandle.currentMaterial = currentMaterial; texture.Dispose(); } state.Dispose(); } // ---------------------------- Transform check ------------------------------------- gzTransform tr = n as gzTransform; if (tr != null) { Vec3 translation; if (tr.GetTranslation(out translation)) { Vector3 trans = new Vector3(translation.x, translation.y, translation.z); gameObject.transform.localPosition = trans; } // Notify subscribers of new Transform OnNewTransform?.Invoke(gameObject); } // ---------------------------- DynamicLoader check ------------------------------------- DynamicLoader dl = n as DynamicLoader; // Add dynamic loader as game object in dictionary // so other dynamic loaded data can parent them as child to loader if (dl != null) { List <GameObject> list; if (!NodeUtils.FindGameObjects(dl.GetNativeReference(), out list)) // We are not registered { NodeUtils.AddGameObjectReference(dl.GetNativeReference(), gameObject); nodeHandle.inNodeUtilsRegistry = true; // Added to registry // We shall continue to iterate as a group to see if we already have loaded children } else // We are already in list { return(list[0]); // Lets return first object wich is our main registered node } // Notify subscribers of new Loader OnNewLoader?.Invoke(gameObject); } // ---------------------------- Lod check ------------------------------------- Lod ld = n as Lod; if (ld != null) { foreach (Node child in ld) { GameObject go_child = Traverse(child, currentMaterial); if (go_child == null) { return(null); } NodeHandle h = go_child.GetComponent <NodeHandle>(); if (h != null) { if (!NodeUtils.HasGameObjects(h.node.GetNativeReference())) { NodeUtils.AddGameObjectReference(h.node.GetNativeReference(), go_child); h.inNodeUtilsRegistry = true; h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_TRAVERSABLE); h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_NOT_TRAVERSABLE); } } go_child.transform.SetParent(gameObject.transform, false); } // Notify subscribers of new Lod OnNewLod?.Invoke(gameObject); // Dont process group as group is already processed return(gameObject); } // ---------------------------- Roi check ------------------------------------- Roi roi = n as Roi; if (roi != null) { nodeHandle.updateTransform = true; nodeHandle.inNodeUpdateList = true; updateNodeObjects.AddLast(gameObject); foreach (Node child in roi) { GameObject go_child = Traverse(child, currentMaterial); if (go_child == null) { return(null); } NodeHandle h = go_child.GetComponent <NodeHandle>(); if (h != null) { if (!NodeUtils.HasGameObjects(h.node.GetNativeReference())) { NodeUtils.AddGameObjectReference(h.node.GetNativeReference(), go_child); h.inNodeUtilsRegistry = true; h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_TRAVERSABLE); h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_NOT_TRAVERSABLE); } } go_child.transform.SetParent(gameObject.transform, false); } // Dont process group return(gameObject); } // ---------------------------- RoiNode check ------------------------------------- RoiNode roinode = n as RoiNode; if (roinode != null) { nodeHandle.updateTransform = true; nodeHandle.inNodeUpdateList = true; updateNodeObjects.AddLast(gameObject); } // ---------------------------- Group check ------------------------------------- Group g = n as Group; if (g != null) { foreach (Node child in g) { GameObject go_child = Traverse(child, currentMaterial); if (go_child == null) { return(null); } go_child.transform.SetParent(gameObject.transform, false); } return(gameObject); } // ---------------------------ExtRef check ----------------------------------------- ExtRef ext = n as ExtRef; if (ext != null) { AssetLoadInfo info = new AssetLoadInfo(gameObject, ext.ResourceURL, ext.ObjectID); pendingAssetLoads.Push(info); } // ---------------------------- Crossboard check ----------------------------------- Crossboard cb = n as Crossboard; if (cb != null && GfxCaps.HasCapability(Capability.UseTreeCrossboards)) { // Scheduled for later build pendingBuilds.Enqueue(nodeHandle); } // ---------------------------- Geometry check ------------------------------------- Geometry geom = n as Geometry; if (geom != null) { nodeHandle.BuildGameObject(); // Notify subscribers of new Geometry OnNewGeometry?.Invoke(gameObject); // Later on we will identify types of geoemtry that will be scheduled later if they are extensive and not ground that covers other geometry // and build them in a later pass distributed over time // pendingBuilds.Enqueue(nodeHandle); } return(gameObject); }
/// <summary> /// Build Lods from retrieved data. /// </summary> public void BuildLods(FrameGeometry frameGeometry, FrameMaterial frameMaterial, VertexBuffer[] vertexBuffers, IndexBuffer[] indexBuffers) { lods = new Lod[frameGeometry.NumLods]; for (int i = 0; i != lods.Length; i++) { FrameLOD frameLod = frameGeometry.LOD[i]; lods[i] = new Lod { VertexDeclaration = frameGeometry.LOD[i].VertexDeclaration }; IndexBuffer indexBuffer = indexBuffers[i]; VertexBuffer vertexBuffer = vertexBuffers[i]; int vertexSize; Dictionary <VertexFlags, FrameLOD.VertexOffset> vertexOffsets = frameLod.GetVertexOffsets(out vertexSize); lods[i].Vertices = new Vertex[frameLod.NumVertsPr]; if (vertexSize * frameLod.NumVertsPr != vertexBuffer.Data.Length) { throw new System.Exception(); } for (int v = 0; v != lods[i].Vertices.Length; v++) { Vertex vertex = new Vertex(); vertex.UVs = new Half2[4]; if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Position)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Position].Offset; var output = VertexTranslator.ReadPositionDataFromVB(vertexBuffer.Data, startIndex, frameGeometry.DecompressionFactor, frameGeometry.DecompressionOffset); vertex.Position = Vector3Extenders.FromVector4(output); vertex.Binormal = new Vector3(output.X); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Tangent)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Position].Offset; vertex.Tangent = VertexTranslator.ReadTangentDataFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Normals)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Normals].Offset; vertex.Normal = VertexTranslator.ReadNormalDataFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Skin)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Skin].Offset; vertex.BoneWeights = VertexTranslator.ReadWeightsFromVB(vertexBuffer.Data, startIndex); vertex.BoneIDs = VertexTranslator.ReadBonesFromVB(vertexBuffer.Data, startIndex + 4); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Color)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Color].Offset; vertex.Color0 = VertexTranslator.ReadColorFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Color1)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Color1].Offset; vertex.Color1 = VertexTranslator.ReadColorFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords0)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.TexCoords0].Offset; vertex.UVs[0] = VertexTranslator.ReadTexcoordFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords1)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.TexCoords1].Offset; vertex.UVs[1] = VertexTranslator.ReadTexcoordFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords2)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.TexCoords2].Offset; vertex.UVs[2] = VertexTranslator.ReadTexcoordFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.ShadowTexture)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.ShadowTexture].Offset; vertex.UVs[3] = VertexTranslator.ReadTexcoordFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.BBCoeffs)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.BBCoeffs].Offset; vertex.BBCoeffs = VertexTranslator.ReadBBCoeffsVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.DamageGroup)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.DamageGroup].Offset; vertex.DamageGroup = VertexTranslator.ReadDamageGroupFromVB(vertexBuffer.Data, startIndex); } lods[i].Vertices[v] = vertex; } lods[i].Indices = indexBuffer.Data; MaterialStruct[] materials = frameMaterial.Materials[i]; lods[i].Parts = new ModelPart[materials.Length]; for (int x = 0; x != materials.Length; x++) { if (string.IsNullOrEmpty(materials[x].MaterialName)) { var material = MaterialsManager.LookupMaterialByHash(materials[x].MaterialHash); materials[x].MaterialName = material.MaterialName; } ModelPart modelPart = new ModelPart(); modelPart.Material = materials[x].MaterialName; modelPart.StartIndex = (uint)materials[x].StartIndex; modelPart.NumFaces = (uint)materials[x].NumFaces; lods[i].Parts[x] = modelPart; } } }
public void ExportToM2T(string exportPath) { using (BinaryWriter writer = new BinaryWriter(File.Create(exportPath + name + ".m2t"))) { writer.Write(fileHeader.ToCharArray()); writer.Write(fileVersion); //mesh name writer.Write(name); writer.Write(isSkinned); if (isSkinned) { writer.Write((byte)skeleton.BoneNames.Length); for (int i = 0; i < skeleton.BoneNames.Length; i++) { StringHelpers.StringHelpers.WriteString8(writer, skeleton.BoneNames[i]); writer.Write(skeleton.Parents[i]); Quaternion rotation; Vector3 position, scale; skeleton.Transform[i].Decompose(out scale, out rotation, out position); position.WriteToFile(writer); rotation.ToEuler().WriteToFile(writer); scale.WriteToFile(writer); } } //Number of Lods writer.Write((byte)lods.Length); for (int i = 0; i != lods.Length; i++) { List <string> exportLog = new List <string>(); Lod lod = lods[i]; //Write section for VertexFlags. writer.Write((int)lod.VertexDeclaration); //write length and then all vertices. writer.Write(lods[i].Vertices.Length); for (int x = 0; x != lods[i].Vertices.Length; x++) { Vertex vert = lods[i].Vertices[x]; vert.Normal = new Vector3(vert.Normal.X, vert.Normal.Y, vert.Normal.Z); if (lod.VertexDeclaration.HasFlag(VertexFlags.Position)) { vert.Position.WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.Normals)) { vert.Normal.WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.Tangent)) { vert.Tangent.WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.Skin)) { writer.Write(vert.BoneIDs); for (int z = 0; z < 4; z++) { writer.Write(vert.BoneWeights[z]); } } if (lod.VertexDeclaration.HasFlag(VertexFlags.Color)) { exportLog.Add(string.Format("{0} {1} {2} {3}", vert.Color0[0], vert.Color0[1], vert.Color0[2], vert.Color0[3])); writer.Write(vert.Color0); } if (lod.VertexDeclaration.HasFlag(VertexFlags.Color1)) { exportLog.Add(string.Format("{0} {1} {2} {3}", vert.Color1[0], vert.Color1[1], vert.Color1[2], vert.Color1[3])); writer.Write(vert.Color1); } if (lod.VertexDeclaration.HasFlag(VertexFlags.TexCoords0)) { vert.UVs[0].WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.TexCoords1)) { vert.UVs[1].WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.TexCoords2)) { vert.UVs[2].WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.ShadowTexture)) { vert.UVs[3].WriteToFile(writer); } } //write mesh count and texture names. writer.Write(lod.Parts.Length); for (int x = 0; x != lod.Parts.Length; x++) { writer.Write(lods[i].Parts[x].Material); writer.Write(lods[i].Parts[x].StartIndex); writer.Write(lods[i].Parts[x].NumFaces); } //write triangle data. writer.Write(lod.Indices.Length); for (int x = 0; x != lod.Indices.Length; x++) { writer.Write(lods[i].Indices[x]); } } } }
public void BuildCollision(ResourceTypes.Collisions.Collision.CollisionModel collisionModel, string name) { lods = new Lod[1]; lods[0] = new Lod(); TriangleMesh triangleMesh = collisionModel.Mesh; lods[0].Vertices = new Vertex[triangleMesh.Vertices.Count]; lods[0].Indices = new uint[triangleMesh.Triangles.Count * 3]; for (int triIdx = 0, idxIdx = 0; triIdx < triangleMesh.Triangles.Count; triIdx++, idxIdx += 3) { lods[0].Indices[idxIdx] = triangleMesh.Triangles[triIdx].v0; lods[0].Indices[idxIdx + 1] = triangleMesh.Triangles[triIdx].v1; lods[0].Indices[idxIdx + 2] = triangleMesh.Triangles[triIdx].v2; } for (int x = 0; x != lods[0].Vertices.Length; x++) { lods[0].Vertices[x] = new Vertex(); lods[0].Vertices[x].Position = triangleMesh.Vertices[x]; } //sort materials in order: //M2T doesn't support unorganised triangles, only triangles in order by material. //basically like mafia itself, so we have to reorder them and then save. //this doesn't mess anything up, just takes a little longer :) Dictionary <string, List <uint> > sortedMats = new Dictionary <string, List <uint> >(); for (int i = 0; i < triangleMesh.MaterialIndices.Count; i++) { string mat = ((CollisionMaterials)triangleMesh.MaterialIndices[i]).ToString(); if (!sortedMats.ContainsKey(mat)) { List <uint> list = new List <uint>(); list.Add(collisionModel.Mesh.Triangles[i].v0); list.Add(collisionModel.Mesh.Triangles[i].v1); list.Add(collisionModel.Mesh.Triangles[i].v2); sortedMats.Add(mat, list); } else { sortedMats[mat].Add(collisionModel.Mesh.Triangles[i].v0); sortedMats[mat].Add(collisionModel.Mesh.Triangles[i].v1); sortedMats[mat].Add(collisionModel.Mesh.Triangles[i].v2); } } lods[0].Parts = new ModelPart[sortedMats.Count]; List <uint> inds = new List <uint>(); for (int x = 0; x != lods[0].Parts.Length; x++) { lods[0].Parts[x] = new ModelPart(); lods[0].Parts[x].Material = sortedMats.ElementAt(x).Key; lods[0].Parts[x].StartIndex = (uint)inds.Count; inds.AddRange(sortedMats.ElementAt(x).Value); lods[0].Parts[x].NumFaces = (uint)(sortedMats.ElementAt(x).Value.Count / 3); } this.name = name; lods[0].Indices = inds.ToArray(); }
public void ReadFromM2T(BinaryReader reader) { if (new string(reader.ReadChars(3)) != fileHeader) { return; } if (reader.ReadByte() != fileVersion) { return; } //mesh name name = reader.ReadString(); //Number of Lods Lods = new Lod[reader.ReadByte()]; for (int i = 0; i != Lods.Length; i++) { Lods[i] = new Lod { VertexDeclaration = 0 }; if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.Position; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.Normals; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.Tangent; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.BlendData; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.flag_0x80; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.TexCoords0; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.TexCoords1; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.TexCoords2; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.TexCoords7; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.flag_0x20000; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.flag_0x40000; } if (reader.ReadBoolean()) { Lods[i].VertexDeclaration += (int)VertexFlags.DamageGroup; } //write length and then all vertices. lods[i].Vertices = new Vertex[reader.ReadInt32()]; lods[i].NumUVChannels = 4; for (int x = 0; x != lods[i].Vertices.Length; x++) { Vertex vert = new Vertex(); vert.UVs = new UVVector2[lods[i].NumUVChannels]; if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.Position)) { vert.Position.ReadfromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.Normals)) { vert.Normal.ReadfromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.Tangent)) { vert.Tangent.ReadfromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords0)) { vert.UVs[0] = new UVVector2(); vert.UVs[0].ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords1)) { vert.UVs[1] = new UVVector2(); vert.UVs[1].ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords2)) { vert.UVs[2] = new UVVector2(); vert.UVs[2].ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords7)) { vert.UVs[3] = new UVVector2(); vert.UVs[3].ReadFromFile(reader); } lods[i].Vertices[x] = vert; } //write mesh count and texture names. Lods[i].Parts = new ModelPart[reader.ReadInt32()]; for (int x = 0; x != Lods[i].Parts.Length; x++) { Lods[i].Parts[x] = new ModelPart(); Lods[i].Parts[x].Material = reader.ReadString(); } List <List <Short3> > partTriangles = new List <List <Short3> >(Lods[i].Parts.Length); for (int x = 0; x != partTriangles.Capacity; x++) { partTriangles.Add(new List <Short3>()); } int totalFaces = reader.ReadInt32(); for (int x = 0; x != totalFaces; x++) { Short3 tri = new Short3(reader); short matId = reader.ReadInt16(); partTriangles[matId].Add(tri); } for (int x = 0; x != Lods[i].Parts.Length; x++) { Lods[i].Parts[x].Indices = partTriangles[x].ToArray(); Lods[i].Parts[x].CalculatePartBounds(lods[i].Vertices); } } }
private void ReadM2TVersionTwo(BinaryReader reader) { //mesh name name = reader.ReadString(); isSkinned = reader.ReadBoolean(); if (isSkinned) { byte size = reader.ReadByte(); skeleton = new Skeleton(); skeleton.Joints = new Joint[size]; for (int i = 0; i < size; i++) { Joint joint = new Joint(); joint.Name = reader.ReadString8(); joint.ParentIndex = reader.ReadByte(); joint.Parent = (joint.ParentIndex != 0xFF) ? skeleton.Joints[joint.ParentIndex] : null; //may crash because root will not be in range Vector3 position = Vector3Extenders.ReadFromFile(reader); Quaternion rotation = QuaternionExtensions.ReadFromFile(reader); Vector3 scale = Vector3Extenders.ReadFromFile(reader); joint.WorldTransform = MatrixExtensions.SetMatrix(rotation, scale, position); skeleton.Joints[i] = joint; } } //Number of Lods Lods = new Lod[reader.ReadByte()]; for (int i = 0; i != Lods.Length; i++) { Lods[i] = new Lod { VertexDeclaration = 0 }; lods[i].VertexDeclaration = (VertexFlags)reader.ReadInt32(); //write length and then all vertices. lods[i].Vertices = new Vertex[reader.ReadInt32()]; for (int x = 0; x != lods[i].Vertices.Length; x++) { Vertex vert = new Vertex(); vert.UVs = new Half2[4]; if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.Position)) { vert.Position = Vector3Extenders.ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.Normals)) { vert.Normal = Vector3Extenders.ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.Tangent)) { vert.Tangent = Vector3Extenders.ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.Skin)) { vert.BoneIDs = reader.ReadBytes(4); vert.BoneWeights = new float[4]; for (int z = 0; z < 4; z++) { vert.BoneWeights[z] = reader.ReadSingle(); } } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.Color)) { vert.Color0 = reader.ReadBytes(4); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.Color1)) { vert.Color1 = reader.ReadBytes(4); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords0)) { vert.UVs[0] = Half2Extenders.ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords1)) { vert.UVs[1] = Half2Extenders.ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords2)) { vert.UVs[2] = Half2Extenders.ReadFromFile(reader); } if (Lods[i].VertexDeclaration.HasFlag(VertexFlags.ShadowTexture)) { vert.UVs[3] = Half2Extenders.ReadFromFile(reader); } lods[i].Vertices[x] = vert; } //read mesh count and texture names. Lods[i].Parts = new ModelPart[reader.ReadInt32()]; for (int x = 0; x != Lods[i].Parts.Length; x++) { Lods[i].Parts[x] = new ModelPart(); Lods[i].Parts[x].Material = reader.ReadString(); Lods[i].Parts[x].StartIndex = reader.ReadUInt32(); Lods[i].Parts[x].NumFaces = reader.ReadUInt32(); var material = MaterialsManager.LookupMaterialByName(Lods[i].Parts[x].Material); if (material != null) { Lods[i].Parts[x].Hash = material.GetMaterialHash(); } } int numIndices = reader.ReadInt32(); Lods[i].Indices = new uint[numIndices]; for (int x = 0; x != Lods[i].Indices.Length; x++) { Lods[i].Indices[x] = reader.ReadUInt32(); } Lods[i].CalculatePartBounds(); } }
/// <summary> /// Build Lods from retrieved data. /// </summary> public void BuildLods(FrameGeometry frameGeometry, FrameMaterial frameMaterial, VertexBuffer[] vertexBuffers, IndexBuffer[] indexBuffers) { lods = new Lod[frameGeometry.NumLods]; for (int i = 0; i != lods.Length; i++) { FrameLOD frameLod = frameGeometry.LOD[i]; lods[i] = new Lod { VertexDeclaration = frameGeometry.LOD[i].VertexDeclaration }; IndexBuffer indexBuffer = indexBuffers[i]; VertexBuffer vertexBuffer = vertexBuffers[i]; int vertexSize; Dictionary <VertexFlags, FrameLOD.VertexOffset> vertexOffsets = frameLod.GetVertexOffsets(out vertexSize); lods[i].NumUVChannels = 4; lods[i].Vertices = new Vertex[frameLod.NumVertsPr]; for (int v = 0; v != lods[i].Vertices.Length; v++) { Vertex vertex = new Vertex(); vertex.UVs = new UVVector2[lods[i].NumUVChannels]; if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Position)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Position].Offset; vertex.ReadPositionData(vertexBuffer.Data, startIndex, frameGeometry.DecompressionFactor, frameGeometry.DecompressionOffset); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Tangent)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Position].Offset; vertex.ReadTangentData(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Normals)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Normals].Offset; vertex.ReadNormalData(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.BlendData)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.BlendData].Offset; vertex.ReadBlendData(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.flag_0x80)) { Console.WriteLine("Skip vertex with flag_0x80"); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords0)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.TexCoords0].Offset; vertex.ReadUvData(vertexBuffer.Data, startIndex, 0); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords1)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.TexCoords1].Offset; vertex.ReadUvData(vertexBuffer.Data, startIndex, 1); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords2)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.TexCoords2].Offset; vertex.ReadUvData(vertexBuffer.Data, startIndex, 2); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords7)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.TexCoords7].Offset; vertex.ReadUvData(vertexBuffer.Data, startIndex, 3); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.flag_0x20000)) { Console.WriteLine("Skip vertex with flag_0x20000"); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.flag_0x40000)) { Console.WriteLine("Skip vertex with flag_0x40000"); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.DamageGroup)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.DamageGroup].Offset; vertex.ReadDamageGroup(vertexBuffer.Data, startIndex); } if (lods[i].NormalMapInfoPresent) { vertex.BuildBinormals(); } lods[i].Vertices[v] = vertex; MaterialStruct[] materials = frameMaterial.Materials[i]; lods[i].Parts = new ModelPart[materials.Length]; for (int x = 0; x != materials.Length; x++) { ModelPart modelPart = new ModelPart(); Material mat = MaterialsManager.LookupMaterialByHash(materials[x].MaterialHash); if (mat == null || mat.SPS.Length == 0) { modelPart.Material = "_test_gray"; } else { modelPart.Material = (mat == null) ? "null" : mat.SPS[0].File; } int num = materials[x].StartIndex + materials[x].NumFaces * 3; List <Short3> intList = new List <Short3>(materials[x].NumFaces); int startIndex = materials[x].StartIndex; while (startIndex < num) { Short3 indice = new Short3(); indice.S1 = indexBuffer.Data[startIndex + 0]; indice.S2 = indexBuffer.Data[startIndex + 1]; indice.S3 = indexBuffer.Data[startIndex + 2]; intList.Add(indice); startIndex += 3; } modelPart.Indices = intList.ToArray(); lods[i].Parts[x] = modelPart; } } } }
// Traverse function iterates the scene graph to build local branches on Unity GameObject Traverse(Node n, Material currentMaterial) { if (n == null || !n.IsValid()) { return(null); } string name = n.GetName(); if (String.IsNullOrEmpty(name)) { name = n.GetNativeTypeName(); } GameObject gameObject = new GameObject(name); var nodeHandle = gameObject.AddComponent <NodeHandle>(); nodeHandle.node = n; nodeHandle.inObjectDict = false; // ---------------------------- Check material state ---------------------------------- if (n.HasState()) { State state = n.State; if (state.HasTexture(0) && state.GetMode(StateMode.TEXTURE) == StateModeActivation.ON) { gzTexture texture = state.GetTexture(0); if (texture.HasImage()) { gzImage image = texture.GetImage(); int depth = (int)image.GetDepth(); int width = (int)image.GetWidth(); int height = (int)image.GetHeight(); if (depth == 1) { if (currentMaterial == null) { currentMaterial = new Material(Shader); } TextureFormat format = TextureFormat.ARGB32; ImageType image_type = image.GetImageType(); switch (image_type) { case ImageType.RGB_8_DXT1: format = TextureFormat.DXT1; break; } Texture2D tex = new Texture2D(width, height, format, false); byte[] image_data; image.GetImageArray(out image_data); tex.LoadRawTextureData(image_data); tex.filterMode = FilterMode.Trilinear; tex.Apply(); currentMaterial.mainTexture = tex; } image.Dispose(); } texture.Dispose(); } state.Dispose(); } // ---------------------------- Transform check ------------------------------------- gzTransform tr = n as gzTransform; if (tr != null) { Vec3 translation; if (tr.GetTranslation(out translation)) { Vector3 trans = new Vector3(translation.x, translation.y, translation.z); gameObject.transform.localPosition = trans; } } // ---------------------------- DynamicLoader check ------------------------------------- DynamicLoader dl = n as DynamicLoader; if (dl != null) { if (!nodeHandle.inObjectDict) { AddGameObjectReference(dl.GetNativeReference(), gameObject); nodeHandle.inObjectDict = true; } } // ---------------------------- Lod check ------------------------------------- Lod ld = n as Lod; if (ld != null) { foreach (Node child in ld) { GameObject go_child = Traverse(child, currentMaterial); NodeHandle h = go_child.GetComponent <NodeHandle>(); if (h != null) { if (!h.inObjectDict) { AddGameObjectReference(h.node.GetNativeReference(), go_child); h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_TRAVERSABLE); h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_NOT_TRAVERSABLE); h.inObjectDict = true; } } go_child.transform.SetParent(gameObject.transform, false); } // Dont process group return(gameObject); } // ---------------------------- Roi check ------------------------------------- Roi roi = n as Roi; if (roi != null) { nodeHandle.updateTransform = true; foreach (Node child in roi) { GameObject go_child = Traverse(child, currentMaterial); NodeHandle h = go_child.GetComponent <NodeHandle>(); if (h != null) { if (!h.inObjectDict) { AddGameObjectReference(h.node.GetNativeReference(), go_child); h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_TRAVERSABLE); h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_NOT_TRAVERSABLE); h.inObjectDict = true; } } go_child.transform.SetParent(gameObject.transform, false); } // Dont process group return(gameObject); } // ---------------------------- RoiNode check ------------------------------------- RoiNode roinode = n as RoiNode; if (roinode != null) { nodeHandle.updateTransform = true; } // ---------------------------- Group check ------------------------------------- Group g = n as Group; if (g != null) { foreach (Node child in g) { GameObject go_child = Traverse(child, currentMaterial); go_child.transform.SetParent(gameObject.transform, false); } return(gameObject); } // ---------------------------ExtRef check ----------------------------------------- ExtRef ext = n as ExtRef; if (ext != null) { AssetLoadInfo info = new AssetLoadInfo(gameObject, ext.ResourceURL, ext.ObjectID); pendingAssetLoads.Push(info); } // ---------------------------- Geometry check ------------------------------------- Geometry geom = n as Geometry; if (geom != null) { float[] float_data; int[] indices; if (geom.GetVertexData(out float_data, out indices)) { MeshFilter filter = gameObject.AddComponent <MeshFilter>(); MeshRenderer renderer = gameObject.AddComponent <MeshRenderer>(); Mesh mesh = new Mesh(); Vector3[] vertices = new Vector3[float_data.Length / 3]; int float_index = 0; for (int i = 0; i < vertices.Length; i++) { vertices[i] = new Vector3(float_data[float_index], float_data[float_index + 1], float_data[float_index + 2]); float_index += 3; } mesh.vertices = vertices; mesh.triangles = indices; if (geom.GetColorData(out float_data)) { if (float_data.Length / 4 == vertices.Length) { float_index = 0; Color[] cols = new Color[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { cols[i] = new Color(float_data[float_index], float_data[float_index + 1], float_data[float_index + 2], float_data[float_index + 3]); float_index += 4; } mesh.colors = cols; } } if (geom.GetNormalData(out float_data)) { if (float_data.Length / 3 == vertices.Length) { float_index = 0; Vector3[] normals = new Vector3[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { normals[i] = new Vector3(float_data[float_index], float_data[float_index + 1], float_data[float_index + 2]); float_index += 3; } mesh.normals = normals; } } //else // mesh.RecalculateNormals(); uint texture_units = geom.GetTextureUnits(); if (texture_units > 0) { if (geom.GetTexCoordData(out float_data, 0)) { if (float_data.Length / 2 == vertices.Length) { float_index = 0; Vector2[] tex_coords = new Vector2[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { tex_coords[i] = new Vector2(float_data[float_index], float_data[float_index + 1]); float_index += 2; } mesh.uv = tex_coords; } } if ((texture_units > 1) && geom.GetTexCoordData(out float_data, 1)) { if (float_data.Length / 2 == vertices.Length) { float_index = 0; Vector2[] tex_coords = new Vector2[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { tex_coords[i] = new Vector2(float_data[float_index], float_data[float_index + 1]); float_index += 2; } mesh.uv2 = tex_coords; } } if ((texture_units > 2) && geom.GetTexCoordData(out float_data, 2)) { if (float_data.Length / 2 == vertices.Length) { float_index = 0; Vector2[] tex_coords = new Vector2[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { tex_coords[i] = new Vector2(float_data[float_index], float_data[float_index + 1]); float_index += 2; } mesh.uv3 = tex_coords; } } if ((texture_units > 3) && geom.GetTexCoordData(out float_data, 3)) { if (float_data.Length / 2 == vertices.Length) { float_index = 0; Vector2[] tex_coords = new Vector2[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { tex_coords[i] = new Vector2(float_data[float_index], float_data[float_index + 1]); float_index += 2; } mesh.uv4 = tex_coords; } } } filter.sharedMesh = mesh; renderer.sharedMaterial = currentMaterial; } } return(gameObject); }
public void ReadMaterials(byte[] memory) { Materials m = new Materials(); Mesh.InternalVersion = BitConverter.ToInt32(memory, readerpos); m.LodCount = BitConverter.ToInt32(memory, readerpos + 4); readerpos += 8; m.Lods = new List <Lod>(); for (int i = 0; i < m.LodCount; i++) { Lod l = new Lod(); l.Guid = new byte[16]; for (int j = 0; j < 16; j++) { l.Guid[j] = memory[readerpos]; readerpos++; } l.SectionCount = BitConverter.ToInt32(memory, readerpos); l.Sections = new List <Section>(); readerpos += 4; for (int j = 0; j < l.SectionCount; j++) { Section s = new Section(); s.Unk1 = BitConverter.ToInt32(memory, readerpos + 4); s.Unk2 = BitConverter.ToInt32(memory, readerpos + 8); s.Unk3 = BitConverter.ToInt32(memory, readerpos + 12); s.FirstIdx1 = BitConverter.ToInt32(memory, readerpos + 16); s.NumFaces1 = BitConverter.ToInt32(memory, readerpos + 20); s.MatEff1 = BitConverter.ToInt32(memory, readerpos + 24); s.MatEff2 = BitConverter.ToInt32(memory, readerpos + 28); s.Unk4 = BitConverter.ToInt32(memory, readerpos + 32); s.Unk5 = BitConverter.ToInt32(memory, readerpos + 36); if (s.Unk5 == 1) { s.FirstIdx2 = BitConverter.ToInt32(memory, readerpos + 40); s.NumFaces2 = BitConverter.ToInt32(memory, readerpos + 44); s.Unk6 = memory[readerpos + 48]; } else { s.Unk6 = memory[readerpos + 40]; s.FirstIdx2 = BitConverter.ToInt32(memory, readerpos + 41); s.NumFaces2 = BitConverter.ToInt32(memory, readerpos + 45); } readerpos += 49; l.Sections.Add(s); } l.SizeVert = BitConverter.ToInt32(memory, readerpos); l.NumVert = BitConverter.ToInt32(memory, readerpos + 4); l.LodCount = BitConverter.ToInt32(memory, readerpos + 8); if (l.Sections[0].Unk5 == 1) { readerpos += 12; } else { readerpos += 4; } m.Lods.Add(l); } Mesh.Mat = m; }
public void ExportToM2T(string exportPath) { if (File.Exists(exportPath + name + ".m2t")) { return; } using (BinaryWriter writer = new BinaryWriter(File.Create(exportPath + name + ".m2t"))) { writer.Write(fileHeader.ToCharArray()); writer.Write(fileVersion); //mesh name writer.Write(name); //Number of Lods writer.Write((byte)lods.Length); for (int i = 0; i != lods.Length; i++) { Lod lod = lods[i]; //Write section for VertexFlags. writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.Position)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.Normals)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.Tangent)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.Skin)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.Color)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.TexCoords0)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.TexCoords1)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.TexCoords2)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.ShadowTexture)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.Color1)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.BBCoeffs)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.DamageGroup)); //write length and then all vertices. writer.Write(lods[i].Vertices.Length); for (int x = 0; x != lods[i].Vertices.Length; x++) { Vertex vert = lods[i].Vertices[x]; vert.Normal = new Vector3(vert.Normal.X, vert.Normal.Y, vert.Normal.Z); if (lod.VertexDeclaration.HasFlag(VertexFlags.Position)) { vert.Position.WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.Normals)) { vert.Normal.WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.Tangent)) { vert.Tangent.WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.TexCoords0)) { vert.UVs[0].WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.TexCoords1)) { vert.UVs[1].WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.TexCoords2)) { vert.UVs[2].WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.ShadowTexture)) { vert.UVs[3].WriteToFile(writer); } } //write mesh count and texture names. writer.Write(lod.Parts.Length); for (int x = 0; x != lod.Parts.Length; x++) { writer.Write(lods[i].Parts[x].Material); writer.Write(lods[i].Parts[x].StartIndex); writer.Write(lods[i].Parts[x].NumFaces); } //write triangle data. writer.Write(lod.Indices.Length); for (int x = 0; x != lod.Indices.Length; x++) { writer.Write(lods[i].Indices[x]); } } } }
public void BuildBasicCollision(Lod model) { nxs = Convert.ToString(22239310); mesh = Convert.ToString(1213416781); num1 = 1; num2 = 3; unkSmall = 0.001f; num3 = 255; num4 = 0; List <Int3> ltriangles = new List <Int3>(); List <CollisionMaterials> lmatTypes = new List <CollisionMaterials>(); for (int i = 0; i != model.Parts.Length; i++) { model.Parts[i].Material = ConvertCollisionMats(model.Parts[i].Material).ToString(); for (int x = 0; x != model.Parts[i].Indices.Length; x++) { ltriangles.Add(new Int3(model.Parts[i].Indices[x])); lmatTypes.Add((CollisionMaterials)Enum.Parse(typeof(CollisionMaterials), model.Parts[i].Material)); } } nPoints = model.Vertices.Length; nTriangles = ltriangles.Count; if (num2 == 3) { num5 = nTriangles - 1; if (nTriangles <= 256) { UnkData = new byte[nTriangles]; } else { unkBytes = new short[nTriangles]; } } points = new Vector3[nPoints]; for (int i = 0; i != points.Length; i++) { points[i] = model.Vertices[i].Position; } triangles = ltriangles.ToArray(); unkShorts = lmatTypes.ToArray(); unk0 = 1; unk1 = 1; unkShortSectorData = new short[nTriangles]; unkByteSectorData = new byte[nTriangles]; opcHbmData = new HBMOPCDataClass(); opcHbmData.BuildBasicOPCHBM(); boundingBox = new BoundingBox(); unkFloats = new float[14]; //sort out bounding box/sphere List <Vertex[]> data = new List <Vertex[]>(); data.Add(model.Vertices); boundingBox = new BoundingBox(); boundingSphere = new BoundingSphere(new Vector3(0), 0); boundingBox.CalculateBounds(data); boundingSphere.CreateFromBoundingBox(boundingBox); unkSize = nTriangles; unkSizeData = new byte[unkSize]; for (int i = 0; i != unkSizeData.Length; i++) { unkSizeData[i] = 0; } }
/// <summary> /// Build Lods from retrieved data. /// </summary> public void BuildLods(FrameGeometry frameGeometry, FrameMaterial frameMaterial, VertexBuffer[] vertexBuffers, IndexBuffer[] indexBuffers) { lods = new Lod[frameGeometry.NumLods]; for (int i = 0; i != lods.Length; i++) { FrameLOD frameLod = frameGeometry.LOD[i]; lods[i] = new Lod { VertexDeclaration = frameGeometry.LOD[i].VertexDeclaration }; IndexBuffer indexBuffer = indexBuffers[i]; VertexBuffer vertexBuffer = vertexBuffers[i]; int vertexSize; Dictionary <VertexFlags, FrameLOD.VertexOffset> vertexOffsets = frameLod.GetVertexOffsets(out vertexSize); lods[i].NumUVChannels = 4; lods[i].Vertices = new Vertex[frameLod.NumVertsPr]; for (int v = 0; v != lods[i].Vertices.Length; v++) { Vertex vertex = new Vertex(); vertex.UVs = new Half2[lods[i].NumUVChannels]; if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Position)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Position].Offset; vertex.Position = VertexTranslator.ReadPositionDataFromVB(vertexBuffer.Data, startIndex, frameGeometry.DecompressionFactor, frameGeometry.DecompressionOffset); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Tangent)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Position].Offset; vertex.Tangent = VertexTranslator.ReadTangentDataFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Normals)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Normals].Offset; vertex.Normal = VertexTranslator.ReadNormalDataFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Skin)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Skin].Offset; vertex.BlendWeight = VertexTranslator.ReadBlendWeightFromVB(vertexBuffer.Data, startIndex); vertex.BoneID = VertexTranslator.ReadBlendIDFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Color)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Color].Offset; vertex.Color0 = VertexTranslator.ReadColorFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords0)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.TexCoords0].Offset; vertex.UVs[0] = VertexTranslator.ReadTexcoordFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords1)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.TexCoords1].Offset; vertex.UVs[1] = VertexTranslator.ReadTexcoordFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords2)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.TexCoords2].Offset; vertex.UVs[2] = VertexTranslator.ReadTexcoordFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.ShadowTexture)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.ShadowTexture].Offset; vertex.UVs[3] = VertexTranslator.ReadTexcoordFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Color1)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Color1].Offset; vertex.Color1 = VertexTranslator.ReadColorFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.BBCoeffs)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.BBCoeffs].Offset; vertex.BBCoeffs = VertexTranslator.ReadBBCoeffsVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.DamageGroup)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.DamageGroup].Offset; vertex.DamageGroup = VertexTranslator.ReadDamageGroupFromVB(vertexBuffer.Data, startIndex); } if (lods[i].NormalMapInfoPresent) { vertex.BuildBinormals(); } lods[i].Vertices[v] = vertex; lods[i].Indices = indexBuffer.Data; MaterialStruct[] materials = frameMaterial.Materials[i]; lods[i].Parts = new ModelPart[materials.Length]; for (int x = 0; x != materials.Length; x++) { ModelPart modelPart = new ModelPart(); modelPart.Material = materials[x].MaterialHash.ToString(); modelPart.StartIndex = (uint)materials[x].StartIndex; modelPart.NumFaces = (uint)materials[x].NumFaces; lods[i].Parts[x] = modelPart; } } } }
public void ExportToM2T(string exportPath) { if (File.Exists(exportPath + name + ".m2t")) { return; } using (BinaryWriter writer = new BinaryWriter(File.Create(exportPath + name + ".m2t"))) { writer.Write(fileHeader.ToCharArray()); writer.Write(fileVersion); //mesh name writer.Write(name); //Number of Lods writer.Write((byte)lods.Length); for (int i = 0; i != lods.Length; i++) { Lod lod = lods[i]; //Write section for VertexFlags. writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.Position)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.Normals)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.Tangent)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.BlendData)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.flag_0x80)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.TexCoords0)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.TexCoords1)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.TexCoords2)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.TexCoords7)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.flag_0x20000)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.flag_0x40000)); writer.Write(lod.VertexDeclaration.HasFlag(VertexFlags.DamageGroup)); //write length and then all vertices. writer.Write(lods[i].Vertices.Length); for (int x = 0; x != lods[i].Vertices.Length; x++) { Vertex vert = lods[i].Vertices[x]; if (lod.VertexDeclaration.HasFlag(VertexFlags.Position)) { vert.Position.WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.Normals)) { vert.Normal.WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.Tangent)) { vert.Tangent.WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.TexCoords0)) { vert.UVs[0].WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.TexCoords1)) { vert.UVs[1].WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.TexCoords2)) { vert.UVs[2].WriteToFile(writer); } if (lod.VertexDeclaration.HasFlag(VertexFlags.TexCoords7)) { vert.UVs[3].WriteToFile(writer); } } //write mesh count and texture names. writer.Write(lod.Parts.Length); for (int x = 0; x != lod.Parts.Length; x++) { writer.Write(lods[i].Parts[x].Material); } //write triangle data. int totalFaces = 0; foreach (ModelPart part in lods[i].Parts) { totalFaces += part.Indices.Length; } writer.Write(totalFaces); for (int x = 0; x != lod.Parts.Length; x++) { for (int z = 0; z != lods[i].Parts[x].Indices.Length; z++) { //write triangle, and then material lods[i].Parts[x].Indices[z].WriteToFile(writer); writer.Write((ushort)x); } } } } }