public static void Init() { SelectedMaterial = new NJS_MATERIAL { DiffuseColor = Color.White, SpecularColor = Color.Black, UseAlpha = false, DoubleSided = true, Exponent = 10, IgnoreSpecular = false, UseTexture = false, IgnoreLighting = true }; UnSelectedMaterial = new NJS_MATERIAL { DiffuseColor = Color.Maroon, SpecularColor = Color.Black, UseAlpha = false, DoubleSided = true, Exponent = 10, IgnoreSpecular = false, UseTexture = false, IgnoreLighting = true }; vertexHelper = new PointHelper { HandleSize = 3f }; }
public override List <RenderInfo> Render(Device dev, EditorCamera camera, MatrixStack transform) { if (!camera.SphereInFrustum(Bounds)) { return(EmptyRenderInfo); } List <RenderInfo> result = new List <RenderInfo>(); transform.Push(); transform.NJTranslate(Position); transform.NJRotateY(Rotation.Y); transform.NJScale((Scale.X), (Scale.Y), (Scale.Z)); RenderInfo outputInfo = new RenderInfo(VolumeMesh, 0, transform.Top, Material, null, FillMode.Solid, Bounds); if (Selected) { NJS_MATERIAL mat = new NJS_MATERIAL { DiffuseColor = Color.White, IgnoreLighting = true, UseAlpha = false }; result.Add(new RenderInfo(VolumeMesh, 0, transform.Top, mat, null, FillMode.Wireframe, Bounds)); } result.Add(outputInfo); transform.Pop(); return(result); }
private string GetMaterialDescription(NJS_MATERIAL material) { List <string> matdescs = new List <string>(); System.Text.StringBuilder sb = new (); matdescs.Add(material.UseTexture ? "Tex " + material.TextureID : "No Tex"); if (material.UseAlpha) { if (material.DestinationAlpha == AlphaInstruction.One || material.SourceAlpha == AlphaInstruction.One) { matdescs.Add("Alpha ONE"); } else { matdescs.Add("Alpha " + material.DiffuseColor.A); } } if (material.IgnoreLighting) { matdescs.Add("IgnoreLight"); } if (material.EnvironmentMap) { matdescs.Add("EnvMap"); } sb.AppendJoin(" / ", matdescs); return(sb.ToString()); }
/// <summary> /// Processes the vertex data to be rendered /// </summary> public override void ProcessVertexData() { List <MeshInfo> meshInfo = new List <MeshInfo>(); List <IOVtx> positions = vertexData.Find(x => x.attribute == GCVertexAttribute.Position)?.data; List <IOVtx> normals = vertexData.Find(x => x.attribute == GCVertexAttribute.Normal)?.data; List <IOVtx> colors = vertexData.Find(x => x.attribute == GCVertexAttribute.Color0)?.data; List <IOVtx> uvs = vertexData.Find(x => x.attribute == GCVertexAttribute.Tex0)?.data; NJS_MATERIAL mat = new NJS_MATERIAL(); mat.UseAlpha = false; foreach (GCMesh m in opaqueMeshes) { meshInfo.Add(m.Process(mat, positions, normals, colors, uvs)); } mat.UseAlpha = true; foreach (GCMesh m in translucentMeshes) { meshInfo.Add(m.Process(mat, positions, normals, colors, uvs)); } MeshInfo = meshInfo.ToArray(); }
public override void Init(ObjectData data, string name) { mesh = Mesh.Box(1f, 1f, 1f); material = new NJS_MATERIAL { DiffuseColor = Color.FromArgb(180, 180, 180, 180), UseAlpha = true }; }
public override void Init(ObjectData data, string name) { mesh = Mesh.Box(0.5f, 0.5f, 0.5f); material = new NJS_MATERIAL { DiffuseColor = Color.FromArgb(127, 178, 178, 178), UseAlpha = false }; }
public override void Init(ObjectData data, string name, Device dev) { mesh = Mesh.Box(dev, 1f, 1f, 1f); material = new NJS_MATERIAL { DiffuseColor = Color.FromArgb(180, 180, 180, 180), UseAlpha = true }; texture = new Texture(dev, new Bitmap(2, 2), 0, Pool.Managed); }
public RenderInfo(Mesh mesh, int subset, Matrix transform, NJS_MATERIAL material, Texture texture, FillMode fillMode, BoundingSphere bounds) { Mesh = mesh; Subset = subset; Transform = transform; Material = material; Texture = texture; FillMode = fillMode; Bounds = bounds; }
private void upButton_Click(object sender, EventArgs e) { NJS_MATERIAL selectedMaterial = materials[comboMaterial.SelectedIndex]; int index = comboMaterial.SelectedIndex; materials.Insert(index - 1, selectedMaterial); materials.RemoveAt(index + 1); UpdateComboBox(); RaiseFormUpdated(); }
public RenderInfo(Mesh mesh, int subset, Matrix transform, NJS_MATERIAL material, Texture texture, FillMode fillMode, BoundingSphere bounds) { Mesh = mesh; Subset = subset; Transform = transform; if (material != null) { Material = new NJS_MATERIAL(material); } Texture = texture; FillMode = fillMode; Bounds = bounds; }
public void ReadMaterial(byte[] file, uint address, uint materialStructCount) { NJS_MATERIAL newMat = new NJS_MATERIAL(); int curAddress = (int)address; for (int i = 0; i < materialStructCount; i++) { uint type = ByteConverter.ToUInt32(file, curAddress); curAddress += 4; switch (type) { case 2: newMat.SourceAlpha = (AlphaInstruction)ByteConverter.ToUInt32(file, curAddress); curAddress += 4; newMat.DestinationAlpha = (AlphaInstruction)ByteConverter.ToUInt32(file, curAddress); curAddress += 4; mat2_08 = ByteConverter.ToInt32(file, curAddress); curAddress += 4; break; case 3: newMat.TextureID = ByteConverter.ToInt32(file, curAddress); curAddress += 4; mat3_04 = ByteConverter.ToInt32(file, curAddress); curAddress += 4; mat3_08 = ByteConverter.ToInt32(file, curAddress); curAddress += 4; break; case 4: mat4_00 = ByteConverter.ToInt32(file, curAddress); curAddress += 4; mat4_04 = ByteConverter.ToInt32(file, curAddress); curAddress += 4; mat4_08 = ByteConverter.ToInt32(file, curAddress); curAddress += 4; break; case 5: newMat.DiffuseColor = VColor.FromBytes(file, (int)address, ColorType.RGBA8888_32); mat5_04 = ByteConverter.ToInt32(file, curAddress); curAddress += 4; mat5_08 = ByteConverter.ToInt32(file, curAddress); curAddress += 4; break; case 6: mat6_00 = ByteConverter.ToInt32(file, curAddress); curAddress += 4; mat6_04 = ByteConverter.ToInt32(file, curAddress); curAddress += 4; mat6_08 = ByteConverter.ToInt32(file, curAddress); curAddress += 4; break; default: ByteConverter.ToInt32(file, curAddress); curAddress += 4; ByteConverter.ToInt32(file, curAddress); curAddress += 4; ByteConverter.ToInt32(file, curAddress); curAddress += 4; //Debug.WriteLine($"Unexpected xj material type {type} at {(curAddress - 4).ToString("X")}"); break; } } mat = newMat; }
private bool DrawSelectedObject(NJS_OBJECT obj, MatrixStack transform, ref int modelindex, ref int animindex) { transform.Push(); modelindex++; if (obj.Animate) { animindex++; } if (animation != null && animation.Models.ContainsKey(animindex)) { obj.ProcessTransforms(animation.Models[animindex], animframe, transform); } else { obj.ProcessTransforms(transform); } if (obj == selectedObject) { if (obj.Attach != null) { for (int j = 0; j < obj.Attach.MeshInfo.Length; j++) { Color col = obj.Attach.MeshInfo[j].Material == null ? Color.White : obj.Attach.MeshInfo[j].Material.DiffuseColor; col = Color.FromArgb(255 - col.R, 255 - col.G, 255 - col.B); NJS_MATERIAL mat = new NJS_MATERIAL { DiffuseColor = col, IgnoreLighting = true, UseAlpha = false }; new RenderInfo(meshes[modelindex], j, transform.Top, mat, null, FillMode.WireFrame, obj.Attach.CalculateBounds(j, transform.Top)).Draw(d3ddevice); } } transform.Pop(); return(true); } foreach (NJS_OBJECT child in obj.Children) { if (DrawSelectedObject(child, transform, ref modelindex, ref animindex)) { transform.Pop(); return(true); } } transform.Pop(); return(false); }
public override void ProcessVertexData() { List <MeshInfo> meshInfo = new List <MeshInfo>(); bool hasUV = VertexData.TexCoord_0.Count != 0; bool hasVColor = VertexData.Color_0.Count != 0; foreach (Mesh m in GeometryData.OpaqueMeshes) { meshInfo.Add(ProcessMesh(m, hasUV, hasVColor, false)); cur_mat = new NJS_MATERIAL(cur_mat); } foreach (Mesh m in GeometryData.TranslucentMeshes) { meshInfo.Add(ProcessMesh(m, hasUV, hasVColor, true)); cur_mat = new NJS_MATERIAL(cur_mat); } MeshInfo = meshInfo.ToArray(); }
public static void Init() { VolumeMesh = Mesh.Box(2f, 2f, 2f); Material = new NJS_MATERIAL { DiffuseColor = Color.FromArgb(200, Color.Purple), SpecularColor = Color.Black, UseAlpha = true, DoubleSided = false, Exponent = 10, IgnoreSpecular = false, UseTexture = false }; pointHelperA = new PointHelper { BoxTexture = Gizmo.ATexture, DrawCube = true }; pointHelperB = new PointHelper { BoxTexture = Gizmo.BTexture, DrawCube = true }; }
public static RenderInfo[] RenderSprite(Device dev, MatrixStack transform, Texture texture, Vector3 center, bool selected) { List <RenderInfo> result = new List <RenderInfo>(); NJS_MATERIAL mat = new NJS_MATERIAL { DiffuseColor = Color.White }; if (texture == null) { texture = QuestionMark; } result.Add(new RenderInfo(QuestionBoxMesh, 0, transform.Top, mat, texture, dev.GetRenderState <FillMode>(RenderState.FillMode), new BoundingSphere(center.X, center.Y, center.Z, 8))); if (selected) { mat = new NJS_MATERIAL { DiffuseColor = Color.Yellow, UseAlpha = false }; result.Add(new RenderInfo(QuestionBoxMesh, 0, transform.Top, mat, null, FillMode.Wireframe, new BoundingSphere(center.X, center.Y, center.Z, 8))); } return(result.ToArray()); }
public static void InitGizmo(Device d3dDevice) { #region Creating Streams From Resources MemoryStream x_NullStream = new MemoryStream(Resources.x_null); MemoryStream y_NullStream = new MemoryStream(Resources.y_null); MemoryStream z_NullStream = new MemoryStream(Resources.z_null); MemoryStream x_MoveStream = new MemoryStream(Resources.x_move); MemoryStream y_MoveStream = new MemoryStream(Resources.y_move); MemoryStream z_MoveStream = new MemoryStream(Resources.z_move); MemoryStream xy_MoveStream = new MemoryStream(Resources.xy_move); MemoryStream zx_MoveStream = new MemoryStream(Resources.zx_move); MemoryStream zy_MoveStream = new MemoryStream(Resources.zy_move); MemoryStream x_RotationStream = new MemoryStream(Resources.x_rotation); MemoryStream y_RotationStream = new MemoryStream(Resources.y_rotation); MemoryStream z_RotationStream = new MemoryStream(Resources.z_rotation); MemoryStream x_ScaleStream = new MemoryStream(Resources.x_scale); MemoryStream y_ScaleStream = new MemoryStream(Resources.y_scale); MemoryStream z_ScaleStream = new MemoryStream(Resources.z_scale); #endregion #region Temporary ExtendedMaterials #endregion #region Loading Meshes and Materials from Streams XMoveMesh = Mesh.FromStream(x_MoveStream, MeshFlags.Managed, d3dDevice, out ExtendedMaterial[] xMaterials); YMoveMesh = Mesh.FromStream(y_MoveStream, MeshFlags.Managed, d3dDevice, out ExtendedMaterial[] yMaterials); ZMoveMesh = Mesh.FromStream(z_MoveStream, MeshFlags.Managed, d3dDevice, out ExtendedMaterial[] zMaterials); XNullMesh = Mesh.FromStream(x_NullStream, MeshFlags.Managed, d3dDevice); YNullMesh = Mesh.FromStream(y_NullStream, MeshFlags.Managed, d3dDevice); ZNullMesh = Mesh.FromStream(z_NullStream, MeshFlags.Managed, d3dDevice); XYMoveMesh = Mesh.FromStream(xy_MoveStream, MeshFlags.Managed, d3dDevice, out ExtendedMaterial[] doubleAxisMaterials); ZXMoveMesh = Mesh.FromStream(zx_MoveStream, MeshFlags.Managed, d3dDevice); ZYMoveMesh = Mesh.FromStream(zy_MoveStream, MeshFlags.Managed, d3dDevice); XRotateMesh = Mesh.FromStream(x_RotationStream, MeshFlags.Managed, d3dDevice); YRotateMesh = Mesh.FromStream(y_RotationStream, MeshFlags.Managed, d3dDevice); ZRotateMesh = Mesh.FromStream(z_RotationStream, MeshFlags.Managed, d3dDevice); XScaleMesh = Mesh.FromStream(x_ScaleStream, MeshFlags.Managed, d3dDevice); YScaleMesh = Mesh.FromStream(y_ScaleStream, MeshFlags.Managed, d3dDevice); ZScaleMesh = Mesh.FromStream(z_ScaleStream, MeshFlags.Managed, d3dDevice); BoxMesh = Mesh.Box(d3dDevice, 1, 1, 1); Mesh TexturedBox = BoxMesh.Clone(BoxMesh.Options.Value, VertexFormats.Position | VertexFormats.Normal | VertexFormats.Texture0 | VertexFormats.Texture1, BoxMesh.Device); //The following code makes the assumption that the vertices of the box are // generated the same way as they are in the April 2005 SDK using (VertexBuffer vb = TexturedBox.VertexBuffer) { CustomVertex.PositionNormalTextured[] verts = (CustomVertex.PositionNormalTextured[])vb.Lock(0, typeof(CustomVertex.PositionNormalTextured), LockFlags.None, TexturedBox.NumberVertices); try { for (int i = 0; i < verts.Length; i += 4) { verts[i + 0].Tu = 0.0f; verts[i + 0].Tv = 0.0f; verts[i + 1].Tu = 1.0f; verts[i + 1].Tv = 0.0f; verts[i + 2].Tu = 1.0f; verts[i + 2].Tv = 1.0f; verts[i + 3].Tu = 0.0f; verts[i + 3].Tv = 1.0f; } } finally { vb.Unlock(); } } BoxMesh = TexturedBox; XMaterial = new NJS_MATERIAL() { DiffuseColor = xMaterials[0].Material3D.Diffuse, Exponent = 0f, UseTexture = false, IgnoreLighting = true, IgnoreSpecular = true }; YMaterial = new NJS_MATERIAL() { DiffuseColor = yMaterials[0].Material3D.Diffuse, Exponent = 0f, UseTexture = false, IgnoreLighting = true, IgnoreSpecular = true }; ZMaterial = new NJS_MATERIAL() { DiffuseColor = zMaterials[0].Material3D.Diffuse, Exponent = 0f, UseTexture = false, IgnoreLighting = true, IgnoreSpecular = true }; DoubleAxisMaterial = new NJS_MATERIAL() { DiffuseColor = doubleAxisMaterials[0].Material3D.Diffuse, Exponent = 0f, UseTexture = false, IgnoreLighting = true, IgnoreSpecular = true }; HighlightMaterial = new NJS_MATERIAL() { DiffuseColor = Color.LightGoldenrodYellow, Exponent = 0f, UseTexture = false, IgnoreLighting = true, IgnoreSpecular = true }; ATexture = Texture.FromBitmap(d3dDevice, Resources.PointATexture, Usage.AutoGenerateMipMap, Pool.Managed); BTexture = Texture.FromBitmap(d3dDevice, Resources.PointBTexture, Usage.AutoGenerateMipMap, Pool.Managed); StandardMaterial = new NJS_MATERIAL() { DiffuseColor = Color.Gray, IgnoreLighting = true, IgnoreSpecular = true, UseAlpha = false, UseTexture = true, Exponent = 100f }; #endregion #region Cleanup x_NullStream.Close(); y_NullStream.Close(); z_NullStream.Close(); x_MoveStream.Close(); y_MoveStream.Close(); z_MoveStream.Close(); x_RotationStream.Close(); y_RotationStream.Close(); z_RotationStream.Close(); #endregion }
private void objToolStripMenuItem_Click(object sender, EventArgs e) { using (SaveFileDialog a = new SaveFileDialog { DefaultExt = "obj", Filter = "OBJ Files|*.obj" }) if (a.ShowDialog() == DialogResult.OK) { using (StreamWriter objstream = new StreamWriter(a.FileName, false)) using (StreamWriter mtlstream = new StreamWriter(Path.ChangeExtension(a.FileName, "mtl"), false)) { List <NJS_MATERIAL> materials = new List <NJS_MATERIAL>(); int totalVerts = 0; int totalNorms = 0; int totalUVs = 0; bool errorFlag = false; for (int i = 0; i < @event.Scenes[scenenum].Entities.Count; i++) { if (@event.Scenes[scenenum].Entities[i].Model != null) { SonicRetro.SAModel.Direct3D.Extensions.WriteModelAsObj(objstream, @event.Scenes[scenenum].Entities[i].Model, ref materials, new MatrixStack(), ref totalVerts, ref totalNorms, ref totalUVs, ref errorFlag); } } #region Material Exporting objstream.WriteLine("mtllib " + Path.GetFileNameWithoutExtension(a.FileName) + ".mtl"); for (int i = 0; i < materials.Count; i++) { int texIndx = materials[i].TextureID; NJS_MATERIAL material = materials[i]; mtlstream.WriteLine("newmtl material_{0}", i); mtlstream.WriteLine("Ka 1 1 1"); mtlstream.WriteLine(string.Format("Kd {0} {1} {2}", material.DiffuseColor.R / 255, material.DiffuseColor.G / 255, material.DiffuseColor.B / 255)); mtlstream.WriteLine(string.Format("Ks {0} {1} {2}", material.SpecularColor.R / 255, material.SpecularColor.G / 255, material.SpecularColor.B / 255)); mtlstream.WriteLine("illum 1"); if (!string.IsNullOrEmpty(TextureInfo[texIndx].Name) && material.UseTexture) { mtlstream.WriteLine("Map_Kd " + TextureInfo[texIndx].Name + ".png"); // save texture string mypath = Path.GetDirectoryName(a.FileName); TextureInfo[texIndx].Image.Save(Path.Combine(mypath, TextureInfo[texIndx].Name + ".png")); } //progress.Step = String.Format("Texture {0}/{1}", material.TextureID + 1, LevelData.TextureBitmaps[LevelData.leveltexs].Length); //progress.StepProgress(); Application.DoEvents(); } #endregion if (errorFlag) { MessageBox.Show("Error(s) encountered during export. Inspect the output file for more details."); } } } }
private void exportOBJToolStripMenuItem_Click(object sender, EventArgs e) { using (SaveFileDialog a = new SaveFileDialog { DefaultExt = "obj", Filter = "OBJ Files|*.obj", FileName = selectedObject.Model.Name }) { if (a.ShowDialog() == DialogResult.OK) { string objFileName = a.FileName; using (StreamWriter objstream = new StreamWriter(objFileName, false)) { List <NJS_MATERIAL> materials = new List <NJS_MATERIAL>(); objstream.WriteLine("mtllib " + TexturePackName + ".mtl"); int totalVerts = 0; int totalNorms = 0; int totalUVs = 0; bool errorFlag = false; SonicRetro.SAModel.Direct3D.Extensions.WriteModelAsObj(objstream, selectedObject.Model, ref materials, new MatrixStack(), ref totalVerts, ref totalNorms, ref totalUVs, ref errorFlag); if (errorFlag) { MessageBox.Show("Error(s) encountered during export. Inspect the output file for more details."); } string mypath = Path.GetDirectoryName(objFileName); using (StreamWriter mtlstream = new StreamWriter(Path.Combine(mypath, TexturePackName + ".mtl"), false)) { for (int i = 0; i < materials.Count; i++) { int texIndx = materials[i].TextureID; NJS_MATERIAL material = materials[i]; mtlstream.WriteLine("newmtl material_{0}", i); mtlstream.WriteLine("Ka 1 1 1"); mtlstream.WriteLine(string.Format("Kd {0} {1} {2}", material.DiffuseColor.R / 255, material.DiffuseColor.G / 255, material.DiffuseColor.B / 255)); mtlstream.WriteLine(string.Format("Ks {0} {1} {2}", material.SpecularColor.R / 255, material.SpecularColor.G / 255, material.SpecularColor.B / 255)); mtlstream.WriteLine("illum 1"); if (!string.IsNullOrEmpty(TextureInfo[texIndx].Name) && material.UseTexture) { mtlstream.WriteLine("Map_Kd " + TextureInfo[texIndx].Name + ".png"); // save texture TextureInfo[texIndx].Image.Save(Path.Combine(mypath, TextureInfo[texIndx].Name + ".png")); } } } } } } }
public static void InitGizmo(Device d3dDevice) { Attach attach = new ModelFile(Resources.x_null).Model.Attach; attach.ProcessVertexData(); XNullMesh = attach.CreateD3DMesh(); attach = new ModelFile(Resources.y_null).Model.Attach; attach.ProcessVertexData(); YNullMesh = attach.CreateD3DMesh(); attach = new ModelFile(Resources.z_null).Model.Attach; attach.ProcessVertexData(); ZNullMesh = attach.CreateD3DMesh(); attach = new ModelFile(Resources.x_move).Model.Attach; attach.ProcessVertexData(); XMoveMesh = attach.CreateD3DMesh(); XMaterial = ((BasicAttach)attach).Material[0]; attach = new ModelFile(Resources.y_move).Model.Attach; attach.ProcessVertexData(); YMoveMesh = attach.CreateD3DMesh(); YMaterial = ((BasicAttach)attach).Material[0]; attach = new ModelFile(Resources.z_move).Model.Attach; attach.ProcessVertexData(); ZMoveMesh = attach.CreateD3DMesh(); ZMaterial = ((BasicAttach)attach).Material[0]; attach = new ModelFile(Resources.xy_move).Model.Attach; attach.ProcessVertexData(); XYMoveMesh = attach.CreateD3DMesh(); DoubleAxisMaterial = ((BasicAttach)attach).Material[0]; attach = new ModelFile(Resources.zx_move).Model.Attach; attach.ProcessVertexData(); ZXMoveMesh = attach.CreateD3DMesh(); attach = new ModelFile(Resources.zy_move).Model.Attach; attach.ProcessVertexData(); ZYMoveMesh = attach.CreateD3DMesh(); attach = new ModelFile(Resources.x_rotation).Model.Attach; attach.ProcessVertexData(); XRotateMesh = attach.CreateD3DMesh(); attach = new ModelFile(Resources.y_rotation).Model.Attach; attach.ProcessVertexData(); YRotateMesh = attach.CreateD3DMesh(); attach = new ModelFile(Resources.z_rotation).Model.Attach; attach.ProcessVertexData(); ZRotateMesh = attach.CreateD3DMesh(); attach = new ModelFile(Resources.x_scale).Model.Attach; attach.ProcessVertexData(); XScaleMesh = attach.CreateD3DMesh(); attach = new ModelFile(Resources.y_scale).Model.Attach; attach.ProcessVertexData(); YScaleMesh = attach.CreateD3DMesh(); attach = new ModelFile(Resources.z_scale).Model.Attach; attach.ProcessVertexData(); ZScaleMesh = attach.CreateD3DMesh(); BoxMesh = Mesh.Box(1, 1, 1); HighlightMaterial = new NJS_MATERIAL() { DiffuseColor = Color.LightGoldenrodYellow, Exponent = 0f, UseTexture = false, IgnoreLighting = true, IgnoreSpecular = true }; ATexture = Resources.PointATexture.ToTexture(d3dDevice); BTexture = Resources.PointBTexture.ToTexture(d3dDevice); StandardMaterial = new NJS_MATERIAL() { DiffuseColor = Color.Gray, IgnoreLighting = true, IgnoreSpecular = true, UseAlpha = false, UseTexture = true, Exponent = 100f }; }
public static void Init(Device dev) { VolumeMesh = Mesh.Box(dev, 2f, 2f, 2f); Material = new NJS_MATERIAL { DiffuseColor = Color.FromArgb(200, Color.Purple), SpecularColor = Color.Black, UseAlpha = true, DoubleSided = false, Exponent = 10, IgnoreSpecular = false, UseTexture = false }; pointHelperA = new PointHelper { BoxTexture = Gizmo.ATexture, DrawCube = true }; pointHelperB = new PointHelper { BoxTexture = Gizmo.BTexture, DrawCube = true }; }
static void Main(string[] args) { string filename; if (args.Length > 0) { filename = args[0]; Console.WriteLine("File: {0}", filename); } else { Console.Write("File: "); filename = Console.ReadLine(); } LandTable level = LandTable.LoadFromFile(filename); switch (level.Format) { case LandTableFormat.SA1: { List <COL> newcollist = new List <COL>(); foreach (COL col in level.COL.Where((col) => col.Model != null && col.Model.Attach != null)) { if ((col.SurfaceFlags & SurfaceFlags.Visible) == SurfaceFlags.Visible) { COL newcol = new COL() { Bounds = col.Bounds }; newcol.SurfaceFlags = SurfaceFlags.Visible; newcol.Model = new SonicRetro.SAModel.NJS_OBJECT() { Name = col.Model.Name + "_cnk" }; newcol.Model.Position = col.Model.Position; newcol.Model.Rotation = col.Model.Rotation; newcol.Model.Scale = col.Model.Scale; BasicAttach basatt = (BasicAttach)col.Model.Attach; ChunkAttach cnkatt = new ChunkAttach(true, true) { Name = basatt.Name + "_cnk", Bounds = basatt.Bounds }; newcol.Model.Attach = cnkatt; VertexChunk vcnk; if (basatt.Normal != null && basatt.Normal.Length > 0) { vcnk = new VertexChunk(ChunkType.Vertex_VertexNormal); } else { vcnk = new VertexChunk(ChunkType.Vertex_Vertex); } vcnk.Vertices = new List <Vertex>(basatt.Vertex); if (basatt.Normal != null) { vcnk.Normals = new List <Vertex>(basatt.Normal); } vcnk.VertexCount = (ushort)basatt.Vertex.Length; vcnk.Size = (ushort)((vcnk.Type == ChunkType.Vertex_VertexNormal ? vcnk.VertexCount * 6 : vcnk.VertexCount * 3) + 1); cnkatt.Vertex.Add(vcnk); foreach (NJS_MESHSET mesh in basatt.Mesh) { if (mesh.PolyType != Basic_PolyType.Strips) { Console.WriteLine("Warning: Skipping non-strip mesh in {0} ({1}).", basatt.MeshName, mesh.PolyType); continue; } NJS_MATERIAL mat = null; if (basatt.Material != null && mesh.MaterialID < basatt.Material.Count) { mat = basatt.Material[mesh.MaterialID]; cnkatt.Poly.Add(new PolyChunkBitsBlendAlpha() { SourceAlpha = mat.SourceAlpha, DestinationAlpha = mat.DestinationAlpha }); cnkatt.Poly.Add(new PolyChunkTinyTextureID() { ClampU = mat.ClampU, ClampV = mat.ClampV, FilterMode = mat.FilterMode, FlipU = mat.FlipU, FlipV = mat.FlipV, SuperSample = mat.SuperSample, TextureID = (ushort)mat.TextureID }); cnkatt.Poly.Add(new PolyChunkMaterial() { Diffuse = mat.DiffuseColor, Specular = mat.SpecularColor, SpecularExponent = (byte)mat.Exponent }); } PolyChunkStrip strip; if (mesh.UV != null & mesh.VColor != null) { strip = new PolyChunkStrip(ChunkType.Strip_StripUVNColor); } else if (mesh.UV != null) { strip = new PolyChunkStrip(ChunkType.Strip_StripUVN); } else if (mesh.VColor != null) { strip = new PolyChunkStrip(ChunkType.Strip_StripColor); } else { strip = new PolyChunkStrip(ChunkType.Strip_Strip); } if (mat != null) { strip.IgnoreLight = mat.IgnoreLighting; strip.IgnoreSpecular = mat.IgnoreSpecular; strip.UseAlpha = mat.UseAlpha; strip.DoubleSide = mat.DoubleSided; strip.FlatShading = mat.FlatShading; strip.EnvironmentMapping = mat.EnvironmentMap; } int striptotal = 0; foreach (Strip item in mesh.Poly.Cast <Strip>()) { UV[] uvs = null; if (mesh.UV != null) { uvs = new UV[item.Indexes.Length]; Array.Copy(mesh.UV, striptotal, uvs, 0, item.Indexes.Length); } Color[] vcolors = null; if (mesh.VColor != null) { vcolors = new Color[item.Indexes.Length]; Array.Copy(mesh.VColor, striptotal, vcolors, 0, item.Indexes.Length); } strip.Strips.Add(new PolyChunkStrip.Strip(item.Reversed, item.Indexes, uvs, vcolors)); striptotal += item.Indexes.Length; } cnkatt.Poly.Add(strip); } newcollist.Add(newcol); } if ((col.SurfaceFlags & ~SurfaceFlags.Visible) != 0) { col.SurfaceFlags &= ~SurfaceFlags.Visible; newcollist.Add(col); } } level.COL = newcollist; } level.Anim = new List <GeoAnimData>(); level.Tool = "SA Tools Level Converter"; level.SaveToFile(System.IO.Path.ChangeExtension(filename, "sa2lvl"), LandTableFormat.SA2); break; case LandTableFormat.SA2: Vertex[] VertexBuffer = new Vertex[0]; Vertex[] NormalBuffer = new Vertex[0]; foreach (COL col in level.COL.Where((col) => col.Model != null && col.Model.Attach is ChunkAttach)) { ChunkAttach cnkatt = (ChunkAttach)col.Model.Attach; BasicAttach basatt = new BasicAttach() { Name = cnkatt.Name, Bounds = cnkatt.Bounds }; if (cnkatt.Vertex != null) { foreach (VertexChunk chunk in cnkatt.Vertex) { if (VertexBuffer.Length < chunk.IndexOffset + chunk.VertexCount) { Array.Resize(ref VertexBuffer, chunk.IndexOffset + chunk.VertexCount); Array.Resize(ref NormalBuffer, chunk.IndexOffset + chunk.VertexCount); } Array.Copy(chunk.Vertices.ToArray(), 0, VertexBuffer, chunk.IndexOffset, chunk.Vertices.Count); Array.Copy(chunk.Normals.ToArray(), 0, NormalBuffer, chunk.IndexOffset, chunk.Normals.Count); } } NJS_MATERIAL material = new NJS_MATERIAL() { UseTexture = true }; int minVtx = int.MaxValue; int maxVtx = int.MinValue; foreach (PolyChunk chunk in cnkatt.Poly) { switch (chunk.Type) { case ChunkType.Bits_BlendAlpha: { PolyChunkBitsBlendAlpha c2 = (PolyChunkBitsBlendAlpha)chunk; material.SourceAlpha = c2.SourceAlpha; material.DestinationAlpha = c2.DestinationAlpha; } break; case ChunkType.Bits_MipmapDAdjust: break; case ChunkType.Bits_SpecularExponent: material.Exponent = ((PolyChunkBitsSpecularExponent)chunk).SpecularExponent; break; case ChunkType.Tiny_TextureID: case ChunkType.Tiny_TextureID2: { PolyChunkTinyTextureID c2 = (PolyChunkTinyTextureID)chunk; material.ClampU = c2.ClampU; material.ClampV = c2.ClampV; material.FilterMode = c2.FilterMode; material.FlipU = c2.FlipU; material.FlipV = c2.FlipV; material.SuperSample = c2.SuperSample; material.TextureID = c2.TextureID; } break; case ChunkType.Material_Diffuse: case ChunkType.Material_Ambient: case ChunkType.Material_DiffuseAmbient: case ChunkType.Material_Specular: case ChunkType.Material_DiffuseSpecular: case ChunkType.Material_AmbientSpecular: case ChunkType.Material_DiffuseAmbientSpecular: case ChunkType.Material_Diffuse2: case ChunkType.Material_Ambient2: case ChunkType.Material_DiffuseAmbient2: case ChunkType.Material_Specular2: case ChunkType.Material_DiffuseSpecular2: case ChunkType.Material_AmbientSpecular2: case ChunkType.Material_DiffuseAmbientSpecular2: { PolyChunkMaterial c2 = (PolyChunkMaterial)chunk; if (c2.Diffuse.HasValue) { material.DiffuseColor = c2.Diffuse.Value; } if (c2.Specular.HasValue) { material.SpecularColor = c2.Specular.Value; material.Exponent = c2.SpecularExponent; } } break; case ChunkType.Strip_Strip: case ChunkType.Strip_StripUVN: case ChunkType.Strip_StripUVH: case ChunkType.Strip_StripNormal: case ChunkType.Strip_StripUVNNormal: case ChunkType.Strip_StripUVHNormal: case ChunkType.Strip_StripColor: case ChunkType.Strip_StripUVNColor: case ChunkType.Strip_StripUVHColor: case ChunkType.Strip_Strip2: case ChunkType.Strip_StripUVN2: case ChunkType.Strip_StripUVH2: { PolyChunkStrip c2 = (PolyChunkStrip)chunk; material.DoubleSided = c2.DoubleSide; material.EnvironmentMap = c2.EnvironmentMapping; material.FlatShading = c2.FlatShading; material.IgnoreLighting = c2.IgnoreLight; material.IgnoreSpecular = c2.IgnoreSpecular; material.UseAlpha = c2.UseAlpha; bool hasVColor = false; switch (chunk.Type) { case ChunkType.Strip_StripColor: case ChunkType.Strip_StripUVNColor: case ChunkType.Strip_StripUVHColor: hasVColor = true; break; } bool hasUV = false; switch (chunk.Type) { case ChunkType.Strip_StripUVN: case ChunkType.Strip_StripUVH: case ChunkType.Strip_StripUVNColor: case ChunkType.Strip_StripUVHColor: case ChunkType.Strip_StripUVN2: case ChunkType.Strip_StripUVH2: hasUV = true; break; } List <Strip> strips = new List <Strip>(c2.StripCount); List <UV> uvs = hasUV ? new List <UV>() : null; List <Color> vcolors = hasVColor ? new List <Color>() : null; foreach (PolyChunkStrip.Strip strip in c2.Strips) { minVtx = Math.Min(minVtx, strip.Indexes.Min()); maxVtx = Math.Max(maxVtx, strip.Indexes.Max()); strips.Add(new Strip(strip.Indexes, strip.Reversed)); if (hasUV) { uvs.AddRange(strip.UVs); } if (hasVColor) { vcolors.AddRange(strip.VColors); } } NJS_MESHSET mesh = new NJS_MESHSET(strips.ToArray(), false, hasUV, hasVColor); if (hasUV) { uvs.CopyTo(mesh.UV); } if (hasVColor) { vcolors.CopyTo(mesh.VColor); } mesh.MaterialID = (ushort)basatt.Material.Count; basatt.Mesh.Add(mesh); basatt.Material.Add(material); material = new NJS_MATERIAL(material.GetBytes(), 0); } break; } } int numVtx = maxVtx - minVtx + 1; basatt.ResizeVertexes(numVtx); Array.Copy(VertexBuffer, minVtx, basatt.Vertex, 0, numVtx); Array.Copy(NormalBuffer, minVtx, basatt.Normal, 0, numVtx); foreach (NJS_MESHSET mesh in basatt.Mesh) { foreach (Poly poly in mesh.Poly) { for (int i = 0; i < poly.Indexes.Length; i++) { poly.Indexes[i] = (ushort)(poly.Indexes[i] - minVtx); } } } col.Model.Attach = basatt; } level.Anim = new List <GeoAnimData>(); level.Tool = "SA Tools Level Converter"; level.SaveToFile(System.IO.Path.ChangeExtension(filename, "sa1lvl"), LandTableFormat.SA1); break; } }
public override List <RenderInfo> Render(Device dev, EditorCamera camera, MatrixStack transform) { if (!camera.SphereInFrustum(Bounds)) { return(EmptyRenderInfo); } List <RenderInfo> result = new List <RenderInfo>(); transform.Push(); transform.NJTranslate(Position); transform.NJRotateY(Rotation.Y); switch (CollisionType) { case (SADXCamColType.CamCol_Sphere): VolumeMesh = Mesh.Sphere(2f, 6, 8); Material = new NJS_MATERIAL { DiffuseColor = Color.FromArgb(200, Color.Blue), SpecularColor = Color.Black, UseAlpha = true, DoubleSided = false, Exponent = 10, IgnoreSpecular = false, UseTexture = false }; transform.NJScale((Scale.X), (Scale.X), (Scale.X)); break; case (SADXCamColType.CamCol_Plane): VolumeMesh = Mesh.Box(2f, 2f, 0f); Material = new NJS_MATERIAL { DiffuseColor = Color.FromArgb(200, Color.Green), SpecularColor = Color.Black, UseAlpha = true, DoubleSided = false, Exponent = 10, IgnoreSpecular = false, UseTexture = false }; transform.NJScale((Scale.X), (Scale.Y), (1f)); break; case (SADXCamColType.CamCol_Block): VolumeMesh = Mesh.Box(2f, 2f, 2f); Material = new NJS_MATERIAL { DiffuseColor = Color.FromArgb(200, Color.Purple), SpecularColor = Color.Black, UseAlpha = true, DoubleSided = false, Exponent = 10, IgnoreSpecular = false, UseTexture = false }; transform.NJScale((Scale.X), (Scale.Y), (Scale.Z)); break; default: VolumeMesh = Mesh.Sphere(2f, 6, 8); Material = new NJS_MATERIAL { DiffuseColor = Color.FromArgb(200, Color.Blue), SpecularColor = Color.Black, UseAlpha = true, DoubleSided = false, Exponent = 10, IgnoreSpecular = false, UseTexture = false }; transform.NJScale((Scale.X), (Scale.X), (Scale.X)); break; } RenderInfo outputInfo = new RenderInfo(VolumeMesh, 0, transform.Top, Material, null, FillMode.Solid, Bounds); if (Selected) { NJS_MATERIAL mat = new NJS_MATERIAL { DiffuseColor = Color.White, IgnoreLighting = true, UseAlpha = false }; result.Add(new RenderInfo(VolumeMesh, 0, transform.Top, mat, null, FillMode.Wireframe, Bounds)); } result.Add(outputInfo); transform.Pop(); return(result); }
public static BasicAttach ToBasic(this ChunkAttach cnkatt) { BasicAttach basatt = new BasicAttach() { Name = cnkatt.Name, Bounds = cnkatt.Bounds }; if (cnkatt.Vertex != null) { foreach (VertexChunk chunk in cnkatt.Vertex) { if (VertexBuffer.Length < chunk.IndexOffset + chunk.VertexCount) { Array.Resize(ref VertexBuffer, chunk.IndexOffset + chunk.VertexCount); Array.Resize(ref NormalBuffer, chunk.IndexOffset + chunk.VertexCount); Array.Resize(ref ColorBuffer, chunk.IndexOffset + chunk.VertexCount); } Array.Copy(chunk.Vertices.ToArray(), 0, VertexBuffer, chunk.IndexOffset, chunk.Vertices.Count); Array.Copy(chunk.Normals.ToArray(), 0, NormalBuffer, chunk.IndexOffset, chunk.Normals.Count); if (chunk.Diffuse.Count > 0) { Array.Copy(chunk.Diffuse.Cast <Color?>().ToArray(), 0, ColorBuffer, chunk.IndexOffset, chunk.Diffuse.Count); } } } NJS_MATERIAL material = new NJS_MATERIAL() { UseTexture = true }; int minVtx = int.MaxValue; int maxVtx = int.MinValue; foreach (PolyChunk chunk in cnkatt.Poly) { switch (chunk.Type) { case ChunkType.Bits_BlendAlpha: { PolyChunkBitsBlendAlpha c2 = (PolyChunkBitsBlendAlpha)chunk; material.SourceAlpha = c2.SourceAlpha; material.DestinationAlpha = c2.DestinationAlpha; } break; case ChunkType.Bits_MipmapDAdjust: break; case ChunkType.Bits_SpecularExponent: material.Exponent = ((PolyChunkBitsSpecularExponent)chunk).SpecularExponent; break; case ChunkType.Tiny_TextureID: case ChunkType.Tiny_TextureID2: { PolyChunkTinyTextureID c2 = (PolyChunkTinyTextureID)chunk; material.ClampU = c2.ClampU; material.ClampV = c2.ClampV; material.FilterMode = c2.FilterMode; material.FlipU = c2.FlipU; material.FlipV = c2.FlipV; material.SuperSample = c2.SuperSample; material.TextureID = c2.TextureID; } break; case ChunkType.Material_Diffuse: case ChunkType.Material_Ambient: case ChunkType.Material_DiffuseAmbient: case ChunkType.Material_Specular: case ChunkType.Material_DiffuseSpecular: case ChunkType.Material_AmbientSpecular: case ChunkType.Material_DiffuseAmbientSpecular: case ChunkType.Material_Diffuse2: case ChunkType.Material_Ambient2: case ChunkType.Material_DiffuseAmbient2: case ChunkType.Material_Specular2: case ChunkType.Material_DiffuseSpecular2: case ChunkType.Material_AmbientSpecular2: case ChunkType.Material_DiffuseAmbientSpecular2: { PolyChunkMaterial c2 = (PolyChunkMaterial)chunk; material.SourceAlpha = c2.SourceAlpha; material.DestinationAlpha = c2.DestinationAlpha; if (c2.Diffuse.HasValue) { material.DiffuseColor = c2.Diffuse.Value; } if (c2.Specular.HasValue) { material.SpecularColor = c2.Specular.Value; material.Exponent = c2.SpecularExponent; } } break; case ChunkType.Strip_Strip: case ChunkType.Strip_StripUVN: case ChunkType.Strip_StripUVH: case ChunkType.Strip_StripNormal: case ChunkType.Strip_StripUVNNormal: case ChunkType.Strip_StripUVHNormal: case ChunkType.Strip_StripColor: case ChunkType.Strip_StripUVNColor: case ChunkType.Strip_StripUVHColor: case ChunkType.Strip_Strip2: case ChunkType.Strip_StripUVN2: case ChunkType.Strip_StripUVH2: { PolyChunkStrip c2 = (PolyChunkStrip)chunk; material.DoubleSided = c2.DoubleSide; material.EnvironmentMap = c2.EnvironmentMapping; material.FlatShading = c2.FlatShading; material.IgnoreLighting = c2.IgnoreLight; material.IgnoreSpecular = c2.IgnoreSpecular; material.UseAlpha = c2.UseAlpha; bool hasStripVColor = false; switch (chunk.Type) { case ChunkType.Strip_StripColor: case ChunkType.Strip_StripUVNColor: case ChunkType.Strip_StripUVHColor: hasStripVColor = true; break; } bool hasUV = false; switch (chunk.Type) { case ChunkType.Strip_StripUVN: case ChunkType.Strip_StripUVH: case ChunkType.Strip_StripUVNColor: case ChunkType.Strip_StripUVHColor: case ChunkType.Strip_StripUVN2: case ChunkType.Strip_StripUVH2: hasUV = true; break; } bool hasVertVColor = false; if (!hasStripVColor && c2.Strips.All(a => a.Indexes.All(b => ColorBuffer[b].HasValue))) { hasVertVColor = true; } bool hasVColor = hasStripVColor || hasVertVColor; List <Strip> strips = new List <Strip>(c2.StripCount); List <UV> uvs = hasUV ? new List <UV>() : null; List <Color> vcolors = hasVColor ? new List <Color>() : null; foreach (PolyChunkStrip.Strip strip in c2.Strips) { minVtx = Math.Min(minVtx, strip.Indexes.Min()); maxVtx = Math.Max(maxVtx, strip.Indexes.Max()); strips.Add(new Strip((ushort[])strip.Indexes.Clone(), strip.Reversed)); if (hasUV) { uvs.AddRange(strip.UVs); } if (hasStripVColor) { vcolors.AddRange(strip.VColors); } else if (hasVertVColor) { foreach (short i in strip.Indexes) { vcolors.Add(ColorBuffer[i].Value); } } } NJS_MESHSET mesh = new NJS_MESHSET(strips.ToArray(), false, hasUV, hasVColor); if (hasUV) { uvs.CopyTo(mesh.UV); } if (hasVColor) { vcolors.CopyTo(mesh.VColor); } mesh.MaterialID = (ushort)basatt.Material.Count; basatt.Mesh.Add(mesh); basatt.Material.Add(material); material = new NJS_MATERIAL(material.GetBytes(), 0); } break; } } int numVtx = maxVtx - minVtx + 1; basatt.ResizeVertexes(numVtx); Array.Copy(VertexBuffer, minVtx, basatt.Vertex, 0, numVtx); Array.Copy(NormalBuffer, minVtx, basatt.Normal, 0, numVtx); foreach (NJS_MESHSET mesh in basatt.Mesh) { foreach (Poly poly in mesh.Poly) { for (int i = 0; i < poly.Indexes.Length; i++) { poly.Indexes[i] = (ushort)(poly.Indexes[i] - minVtx); } } } return(basatt); }
private static void ConvertCOL(List <COL> newcollist, Dictionary <string, Attach> visitedAttaches, COL col) { if ((col.SurfaceFlags & SurfaceFlags.Visible) == SurfaceFlags.Visible) { BasicAttach basatt = (BasicAttach)col.Model.Attach; COL newcol = new COL() { Bounds = col.Bounds }; newcol.SurfaceFlags = SurfaceFlags.Visible; newcol.Model = new NJS_OBJECT() { Name = col.Model.Name + "_cnk" }; newcol.Model.Position = col.Model.Position; newcol.Model.Rotation = col.Model.Rotation; newcol.Model.Scale = col.Model.Scale; string newname = basatt.Name + "_cnk"; if (visitedAttaches != null && visitedAttaches.ContainsKey(newname)) { newcol.Model.Attach = visitedAttaches[newname]; } else { ChunkAttach cnkatt = new ChunkAttach(true, true) { Name = newname, Bounds = basatt.Bounds }; if (visitedAttaches != null) { visitedAttaches[newname] = cnkatt; } newcol.Model.Attach = cnkatt; VertexChunk vcnk; bool hasvcolor = basatt.Mesh.Any(a => a.VColor != null); bool hasnormal = !hasvcolor && basatt.Normal?.Length > 0; if (hasvcolor) { vcnk = new VertexChunk(ChunkType.Vertex_VertexDiffuse8); } else if (hasnormal) { vcnk = new VertexChunk(ChunkType.Vertex_VertexNormal); } else { vcnk = new VertexChunk(ChunkType.Vertex_Vertex); } List <CachedVertex> cache = new List <CachedVertex>(basatt.Vertex.Length); List <List <Strip> > strips = new List <List <Strip> >(); List <List <List <UV> > > uvs = new List <List <List <UV> > >(); foreach (NJS_MESHSET mesh in basatt.Mesh) { List <Strip> polys = new List <Strip>(); List <List <UV> > us = null; bool hasUV = mesh.UV != null; bool hasVColor = mesh.VColor != null; int currentstriptotal = 0; switch (mesh.PolyType) { case Basic_PolyType.Triangles: { List <ushort> tris = new List <ushort>(); Dictionary <ushort, UV> uvmap = new Dictionary <ushort, UV>(); foreach (Poly poly in mesh.Poly) { for (int i = 0; i < 3; i++) { ushort ind = (ushort)cache.AddUnique(new CachedVertex( basatt.Vertex[poly.Indexes[i]], basatt.Normal[poly.Indexes[i]], hasVColor ? mesh.VColor[currentstriptotal] : Color.White, mesh.UV?[currentstriptotal])); if (hasUV) { uvmap[ind] = mesh.UV[currentstriptotal]; } ++currentstriptotal; tris.Add(ind); } } if (hasUV) { us = new List <List <UV> >(); } System.Diagnostics.Debug.Assert(nvStripifier.GenerateStrips(tris.ToArray(), out var primitiveGroups)); // Add strips for (var i = 0; i < primitiveGroups.Length; i++) { var primitiveGroup = primitiveGroups[i]; System.Diagnostics.Debug.Assert(primitiveGroup.Type == NvTriStripDotNet.PrimitiveType.TriangleStrip); var stripIndices = new ushort[primitiveGroup.Indices.Length]; List <UV> stripuv = new List <UV>(); for (var j = 0; j < primitiveGroup.Indices.Length; j++) { var vertexIndex = primitiveGroup.Indices[j]; stripIndices[j] = vertexIndex; if (hasUV) { stripuv.Add(uvmap[vertexIndex]); } } polys.Add(new Strip(stripIndices, false)); if (hasUV) { us.Add(stripuv); } } } break; case Basic_PolyType.Quads: { List <ushort> tris = new List <ushort>(); Dictionary <ushort, UV> uvmap = new Dictionary <ushort, UV>(); foreach (Poly poly in mesh.Poly) { ushort[] quad = new ushort[4]; for (int i = 0; i < 4; i++) { ushort ind = (ushort)cache.AddUnique(new CachedVertex( basatt.Vertex[poly.Indexes[i]], basatt.Normal[poly.Indexes[i]], hasVColor ? mesh.VColor[currentstriptotal] : Color.White, mesh.UV?[currentstriptotal])); if (hasUV) { uvmap[ind] = mesh.UV[currentstriptotal]; } ++currentstriptotal; quad[i] = ind; } tris.Add(quad[0]); tris.Add(quad[1]); tris.Add(quad[2]); tris.Add(quad[2]); tris.Add(quad[1]); tris.Add(quad[3]); } if (hasUV) { us = new List <List <UV> >(); } System.Diagnostics.Debug.Assert(nvStripifier.GenerateStrips(tris.ToArray(), out var primitiveGroups)); // Add strips for (var i = 0; i < primitiveGroups.Length; i++) { var primitiveGroup = primitiveGroups[i]; System.Diagnostics.Debug.Assert(primitiveGroup.Type == NvTriStripDotNet.PrimitiveType.TriangleStrip); var stripIndices = new ushort[primitiveGroup.Indices.Length]; List <UV> stripuv = new List <UV>(); for (var j = 0; j < primitiveGroup.Indices.Length; j++) { var vertexIndex = primitiveGroup.Indices[j]; stripIndices[j] = vertexIndex; if (hasUV) { stripuv.Add(uvmap[vertexIndex]); } } polys.Add(new Strip(stripIndices, false)); if (hasUV) { us.Add(stripuv); } } } break; case Basic_PolyType.NPoly: case Basic_PolyType.Strips: if (hasUV) { us = new List <List <UV> >(); } foreach (Strip poly in mesh.Poly.Cast <Strip>()) { List <UV> stripuv = new List <UV>(); ushort[] inds = (ushort[])poly.Indexes.Clone(); for (int i = 0; i < poly.Indexes.Length; i++) { inds[i] = (ushort)cache.AddUnique(new CachedVertex( basatt.Vertex[poly.Indexes[i]], basatt.Normal[poly.Indexes[i]], hasVColor ? mesh.VColor[currentstriptotal] : Color.White)); if (hasUV) { stripuv.Add(mesh.UV[currentstriptotal]); } ++currentstriptotal; } polys.Add(new Strip(inds, poly.Reversed)); if (hasUV) { us.Add(stripuv); } } break; } strips.Add(polys); uvs.Add(us); } foreach (var item in cache) { vcnk.Vertices.Add(item.vertex); if (hasnormal) { vcnk.Normals.Add(item.normal); } if (hasvcolor) { vcnk.Diffuse.Add(item.color); } } vcnk.VertexCount = (ushort)cache.Count; switch (vcnk.Type) { case ChunkType.Vertex_Vertex: vcnk.Size = (ushort)(vcnk.VertexCount * 3 + 1); break; case ChunkType.Vertex_VertexDiffuse8: vcnk.Size = (ushort)(vcnk.VertexCount * 4 + 1); break; case ChunkType.Vertex_VertexNormal: vcnk.Size = (ushort)(vcnk.VertexCount * 6 + 1); break; } cnkatt.Vertex.Add(vcnk); for (int i = 0; i < basatt.Mesh.Count; i++) { NJS_MESHSET mesh = basatt.Mesh[i]; NJS_MATERIAL mat = null; if (basatt.Material != null && mesh.MaterialID < basatt.Material.Count) { mat = basatt.Material[mesh.MaterialID]; cnkatt.Poly.Add(new PolyChunkTinyTextureID() { ClampU = mat.ClampU, ClampV = mat.ClampV, FilterMode = mat.FilterMode, FlipU = mat.FlipU, FlipV = mat.FlipV, SuperSample = mat.SuperSample, TextureID = (ushort)mat.TextureID }); cnkatt.Poly.Add(new PolyChunkMaterial() { SourceAlpha = mat.SourceAlpha, DestinationAlpha = mat.DestinationAlpha, Diffuse = mat.DiffuseColor, Specular = mat.SpecularColor, SpecularExponent = (byte)mat.Exponent }); } PolyChunkStrip strip; if (mesh.UV != null) { strip = new PolyChunkStrip(ChunkType.Strip_StripUVN); } else { strip = new PolyChunkStrip(ChunkType.Strip_Strip); } if (mat != null) { strip.IgnoreLight = mat.IgnoreLighting; strip.IgnoreSpecular = mat.IgnoreSpecular; strip.UseAlpha = mat.UseAlpha; strip.DoubleSide = mat.DoubleSided; strip.FlatShading = mat.FlatShading; strip.EnvironmentMapping = mat.EnvironmentMap; } for (int i1 = 0; i1 < strips[i].Count; i1++) { Strip item = strips[i][i1]; UV[] uv2 = null; if (mesh.UV != null) { uv2 = uvs[i][i1].ToArray(); } strip.Strips.Add(new PolyChunkStrip.Strip(item.Reversed, item.Indexes, uv2, null)); } cnkatt.Poly.Add(strip); } } newcollist.Add(newcol); } if ((col.SurfaceFlags & ~SurfaceFlags.Visible) != 0) { int newflags = col.Flags & 0xF; if (col.SurfaceFlags.HasFlag(SurfaceFlags.Diggable)) { newflags |= 0x20; } if (col.SurfaceFlags.HasFlag(SurfaceFlags.Unclimbable)) { newflags |= 0x80; } if (col.SurfaceFlags.HasFlag(SurfaceFlags.Hurt)) { newflags |= 0x400; } if (col.SurfaceFlags.HasFlag(SurfaceFlags.CannotLand)) { newflags |= 0x1000; } col.Flags = newflags; newcollist.Add(col); } }
private bool DrawSelectedObject(NJS_OBJECT obj, MatrixStack transform, ref int modelindex, ref int animindex) { transform.Push(); modelindex++; if (obj.Animate) animindex++; if (animation != null && animation.Models.ContainsKey(animindex)) obj.ProcessTransforms(animation.Models[animindex], animframe, transform); else obj.ProcessTransforms(transform); if (obj == selectedObject) { if (obj.Attach != null) for (int j = 0; j < obj.Attach.MeshInfo.Length; j++) { Color col = obj.Attach.MeshInfo[j].Material == null ? Color.White : obj.Attach.MeshInfo[j].Material.DiffuseColor; col = Color.FromArgb(255 - col.R, 255 - col.G, 255 - col.B); NJS_MATERIAL mat = new NJS_MATERIAL { DiffuseColor = col, IgnoreLighting = true, UseAlpha = false }; new RenderInfo(meshes[modelindex], j, transform.Top, mat, null, FillMode.WireFrame, obj.Attach.CalculateBounds(j, transform.Top)).Draw(d3ddevice); } transform.Pop(); return true; } foreach (NJS_OBJECT child in obj.Children) if (DrawSelectedObject(child, transform, ref modelindex, ref animindex)) { transform.Pop(); return true; } transform.Pop(); return false; }
public static ChunkAttach ToChunk(this BasicAttach basatt) { ChunkAttach cnkatt = new ChunkAttach(true, true) { Name = basatt.Name + "_cnk", Bounds = basatt.Bounds }; VertexChunk vcnk; bool hasnormal = basatt.Normal?.Length > 0; bool hasvcolor = basatt.Mesh.Any(a => a.VColor != null); if (hasvcolor) { vcnk = new VertexChunk(ChunkType.Vertex_VertexDiffuse8); hasnormal = false; } else if (hasnormal) { vcnk = new VertexChunk(ChunkType.Vertex_VertexNormal); } else { vcnk = new VertexChunk(ChunkType.Vertex_Vertex); } List <CachedVertex> cache = new List <CachedVertex>(basatt.Vertex.Length); List <List <Strip> > strips = new List <List <Strip> >(); List <List <List <UV> > > uvs = new List <List <List <UV> > >(); foreach (NJS_MESHSET mesh in basatt.Mesh) { List <Strip> polys = new List <Strip>(); List <List <UV> > us = null; bool hasUV = mesh.UV != null; bool hasVColor = mesh.VColor != null; int currentstriptotal = 0; switch (mesh.PolyType) { case Basic_PolyType.Triangles: { List <ushort> tris = new List <ushort>(); Dictionary <ushort, UV> uvmap = new Dictionary <ushort, UV>(); foreach (Poly poly in mesh.Poly) { for (int i = 0; i < 3; i++) { ushort ind = (ushort)cache.AddUnique(new CachedVertex( basatt.Vertex[poly.Indexes[i]], basatt.Normal[poly.Indexes[i]], hasVColor ? mesh.VColor[currentstriptotal] : Color.White, mesh.UV?[currentstriptotal])); if (hasUV) { uvmap[ind] = mesh.UV[currentstriptotal]; } ++currentstriptotal; tris.Add(ind); } } if (hasUV) { us = new List <List <UV> >(); } nvStripifier.GenerateStrips(tris.ToArray(), out var primitiveGroups); // Add strips for (var i = 0; i < primitiveGroups.Length; i++) { var primitiveGroup = primitiveGroups[i]; System.Diagnostics.Debug.Assert(primitiveGroup.Type == PrimitiveType.TriangleStrip); var stripIndices = new ushort[primitiveGroup.Indices.Length]; List <UV> stripuv = new List <UV>(); for (var j = 0; j < primitiveGroup.Indices.Length; j++) { var vertexIndex = primitiveGroup.Indices[j]; stripIndices[j] = vertexIndex; if (hasUV) { stripuv.Add(uvmap[vertexIndex]); } } polys.Add(new Strip(stripIndices, false)); if (hasUV) { us.Add(stripuv); } } } break; case Basic_PolyType.Quads: { List <ushort> tris = new List <ushort>(); Dictionary <ushort, UV> uvmap = new Dictionary <ushort, UV>(); foreach (Poly poly in mesh.Poly) { ushort[] quad = new ushort[4]; for (int i = 0; i < 4; i++) { ushort ind = (ushort)cache.AddUnique(new CachedVertex( basatt.Vertex[poly.Indexes[i]], basatt.Normal[poly.Indexes[i]], hasVColor ? mesh.VColor[currentstriptotal] : Color.White, mesh.UV?[currentstriptotal])); if (hasUV) { uvmap[ind] = mesh.UV[currentstriptotal]; } ++currentstriptotal; quad[i] = ind; } tris.Add(quad[0]); tris.Add(quad[1]); tris.Add(quad[2]); tris.Add(quad[2]); tris.Add(quad[1]); tris.Add(quad[3]); } if (hasUV) { us = new List <List <UV> >(); } nvStripifier.GenerateStrips(tris.ToArray(), out var primitiveGroups); // Add strips for (var i = 0; i < primitiveGroups.Length; i++) { var primitiveGroup = primitiveGroups[i]; System.Diagnostics.Debug.Assert(primitiveGroup.Type == PrimitiveType.TriangleStrip); var stripIndices = new ushort[primitiveGroup.Indices.Length]; List <UV> stripuv = new List <UV>(); for (var j = 0; j < primitiveGroup.Indices.Length; j++) { var vertexIndex = primitiveGroup.Indices[j]; stripIndices[j] = vertexIndex; if (hasUV) { stripuv.Add(uvmap[vertexIndex]); } } polys.Add(new Strip(stripIndices, false)); if (hasUV) { us.Add(stripuv); } } } break; case Basic_PolyType.NPoly: case Basic_PolyType.Strips: if (hasUV) { us = new List <List <UV> >(); } foreach (Strip poly in mesh.Poly.Cast <Strip>()) { List <UV> stripuv = new List <UV>(); ushort[] inds = (ushort[])poly.Indexes.Clone(); for (int i = 0; i < poly.Indexes.Length; i++) { inds[i] = (ushort)cache.AddUnique(new CachedVertex( basatt.Vertex[poly.Indexes[i]], basatt.Normal[poly.Indexes[i]], hasVColor ? mesh.VColor[currentstriptotal] : Color.White)); if (hasUV) { stripuv.Add(mesh.UV[currentstriptotal]); } ++currentstriptotal; } polys.Add(new Strip(inds, poly.Reversed)); if (hasUV) { us.Add(stripuv); } } break; } strips.Add(polys); uvs.Add(us); } foreach (var item in cache) { vcnk.Vertices.Add(item.vertex); if (hasnormal) { vcnk.Normals.Add(item.normal); } if (hasvcolor) { vcnk.Diffuse.Add(item.color); } } cnkatt.Vertex.Add(vcnk); for (int i = 0; i < basatt.Mesh.Count; i++) { NJS_MESHSET mesh = basatt.Mesh[i]; NJS_MATERIAL mat = null; if (basatt.Material != null && mesh.MaterialID < basatt.Material.Count) { mat = basatt.Material[mesh.MaterialID]; cnkatt.Poly.Add(new PolyChunkTinyTextureID() { ClampU = mat.ClampU, ClampV = mat.ClampV, FilterMode = mat.FilterMode, FlipU = mat.FlipU, FlipV = mat.FlipV, SuperSample = mat.SuperSample, TextureID = (ushort)mat.TextureID }); cnkatt.Poly.Add(new PolyChunkMaterial() { SourceAlpha = mat.SourceAlpha, DestinationAlpha = mat.DestinationAlpha, Diffuse = mat.DiffuseColor, Specular = mat.SpecularColor, SpecularExponent = (byte)mat.Exponent }); } PolyChunkStrip strip; if (mesh.UV != null) { strip = new PolyChunkStrip(ChunkType.Strip_StripUVN); } else { strip = new PolyChunkStrip(ChunkType.Strip_Strip); } if (mat != null) { strip.IgnoreLight = mat.IgnoreLighting; strip.IgnoreSpecular = mat.IgnoreSpecular; strip.UseAlpha = mat.UseAlpha; strip.DoubleSide = mat.DoubleSided; strip.FlatShading = mat.FlatShading; strip.EnvironmentMapping = mat.EnvironmentMap; } for (int i1 = 0; i1 < strips[i].Count; i1++) { Strip item = strips[i][i1]; UV[] uv2 = null; if (mesh.UV != null) { uv2 = uvs[i][i1].ToArray(); } strip.Strips.Add(new PolyChunkStrip.Strip(item.Reversed, item.Indexes, uv2, null)); } cnkatt.Poly.Add(strip); } return(cnkatt); }
static void Main(string[] args) { string filename; if (args.Length > 0) { filename = args[0]; Console.WriteLine("File: {0}", filename); } else { Console.Write("File: "); filename = Console.ReadLine(); } ModelFile model = new ModelFile(filename); switch (model.Format) { case ModelFormat.Basic: foreach (NJS_OBJECT obj in model.Model.GetObjects().Where(obj => obj.Attach is BasicAttach)) { BasicAttach basatt = (BasicAttach)obj.Attach; ChunkAttach cnkatt = new ChunkAttach(true, true) { Name = basatt.Name + "_cnk", Bounds = basatt.Bounds }; obj.Attach = cnkatt; VertexChunk vcnk; bool hasnormal = basatt.Normal?.Length > 0; bool hasvcolor = basatt.Mesh.Any(a => a.VColor != null); if (hasvcolor) { vcnk = new VertexChunk(ChunkType.Vertex_VertexDiffuse8); } else if (hasnormal) { vcnk = new VertexChunk(ChunkType.Vertex_VertexNormal); } else { vcnk = new VertexChunk(ChunkType.Vertex_Vertex); } List <CachedVertex> cache = new List <CachedVertex>(basatt.Vertex.Length); List <List <Strip> > strips = new List <List <Strip> >(); List <List <List <UV> > > uvs = new List <List <List <UV> > >(); foreach (NJS_MESHSET mesh in basatt.Mesh) { List <Strip> polys = new List <Strip>(); List <List <UV> > us = null; bool hasUV = mesh.UV != null; bool hasVColor = mesh.VColor != null; int currentstriptotal = 0; switch (mesh.PolyType) { case Basic_PolyType.Triangles: { List <ushort> tris = new List <ushort>(); Dictionary <ushort, UV> uvmap = new Dictionary <ushort, UV>(); foreach (Poly poly in mesh.Poly) { for (int i = 0; i < 3; i++) { ushort ind = (ushort)cache.AddUnique(new CachedVertex( basatt.Vertex[poly.Indexes[i]], basatt.Normal[poly.Indexes[i]], hasVColor ? mesh.VColor[currentstriptotal] : Color.White, mesh.UV?[currentstriptotal])); if (hasUV) { uvmap[ind] = mesh.UV[currentstriptotal]; } ++currentstriptotal; tris.Add(ind); } } if (hasUV) { us = new List <List <UV> >(); } nvStripifier.GenerateStrips(tris.ToArray(), out var primitiveGroups); // Add strips for (var i = 0; i < primitiveGroups.Length; i++) { var primitiveGroup = primitiveGroups[i]; System.Diagnostics.Debug.Assert(primitiveGroup.Type == PrimitiveType.TriangleStrip); var stripIndices = new ushort[primitiveGroup.Indices.Length]; List <UV> stripuv = new List <UV>(); for (var j = 0; j < primitiveGroup.Indices.Length; j++) { var vertexIndex = primitiveGroup.Indices[j]; stripIndices[j] = vertexIndex; if (hasUV) { stripuv.Add(uvmap[vertexIndex]); } } polys.Add(new Strip(stripIndices, false)); if (hasUV) { us.Add(stripuv); } } } break; case Basic_PolyType.Quads: { List <ushort> tris = new List <ushort>(); Dictionary <ushort, UV> uvmap = new Dictionary <ushort, UV>(); foreach (Poly poly in mesh.Poly) { ushort[] quad = new ushort[4]; for (int i = 0; i < 4; i++) { ushort ind = (ushort)cache.AddUnique(new CachedVertex( basatt.Vertex[poly.Indexes[i]], basatt.Normal[poly.Indexes[i]], hasVColor ? mesh.VColor[currentstriptotal] : Color.White, mesh.UV?[currentstriptotal])); if (hasUV) { uvmap[ind] = mesh.UV[currentstriptotal]; } ++currentstriptotal; quad[i] = ind; } tris.Add(quad[0]); tris.Add(quad[1]); tris.Add(quad[2]); tris.Add(quad[2]); tris.Add(quad[1]); tris.Add(quad[3]); } if (hasUV) { us = new List <List <UV> >(); } nvStripifier.GenerateStrips(tris.ToArray(), out var primitiveGroups); // Add strips for (var i = 0; i < primitiveGroups.Length; i++) { var primitiveGroup = primitiveGroups[i]; System.Diagnostics.Debug.Assert(primitiveGroup.Type == PrimitiveType.TriangleStrip); var stripIndices = new ushort[primitiveGroup.Indices.Length]; List <UV> stripuv = new List <UV>(); for (var j = 0; j < primitiveGroup.Indices.Length; j++) { var vertexIndex = primitiveGroup.Indices[j]; stripIndices[j] = vertexIndex; if (hasUV) { stripuv.Add(uvmap[vertexIndex]); } } polys.Add(new Strip(stripIndices, false)); if (hasUV) { us.Add(stripuv); } } } break; case Basic_PolyType.NPoly: case Basic_PolyType.Strips: if (hasUV) { us = new List <List <UV> >(); } foreach (Strip poly in mesh.Poly.Cast <Strip>()) { List <UV> stripuv = new List <UV>(); ushort[] inds = (ushort[])poly.Indexes.Clone(); for (int i = 0; i < poly.Indexes.Length; i++) { inds[i] = (ushort)cache.AddUnique(new CachedVertex( basatt.Vertex[poly.Indexes[i]], basatt.Normal[poly.Indexes[i]], hasVColor ? mesh.VColor[currentstriptotal] : Color.White)); if (hasUV) { stripuv.Add(mesh.UV[currentstriptotal]); } ++currentstriptotal; } polys.Add(new Strip(inds, poly.Reversed)); if (hasUV) { us.Add(stripuv); } } break; } strips.Add(polys); uvs.Add(us); } foreach (var item in cache) { vcnk.Vertices.Add(item.vertex); if (hasnormal) { vcnk.Normals.Add(item.normal); } if (hasvcolor) { vcnk.Diffuse.Add(item.color); } } vcnk.VertexCount = (ushort)cache.Count; switch (vcnk.Type) { case ChunkType.Vertex_Vertex: vcnk.Size = (ushort)(vcnk.VertexCount * 3 + 1); break; case ChunkType.Vertex_VertexDiffuse8: vcnk.Size = (ushort)(vcnk.VertexCount * 4 + 1); break; case ChunkType.Vertex_VertexNormal: vcnk.Size = (ushort)(vcnk.VertexCount * 6 + 1); break; case ChunkType.Vertex_VertexNormalDiffuse8: vcnk.Size = (ushort)(vcnk.VertexCount * 7 + 1); break; } cnkatt.Vertex.Add(vcnk); for (int i = 0; i < basatt.Mesh.Count; i++) { NJS_MESHSET mesh = basatt.Mesh[i]; NJS_MATERIAL mat = null; if (basatt.Material != null && mesh.MaterialID < basatt.Material.Count) { mat = basatt.Material[mesh.MaterialID]; cnkatt.Poly.Add(new PolyChunkTinyTextureID() { ClampU = mat.ClampU, ClampV = mat.ClampV, FilterMode = mat.FilterMode, FlipU = mat.FlipU, FlipV = mat.FlipV, SuperSample = mat.SuperSample, TextureID = (ushort)mat.TextureID }); cnkatt.Poly.Add(new PolyChunkMaterial() { SourceAlpha = mat.SourceAlpha, DestinationAlpha = mat.DestinationAlpha, Diffuse = mat.DiffuseColor, Specular = mat.SpecularColor, SpecularExponent = (byte)mat.Exponent }); } PolyChunkStrip strip; if (mesh.UV != null) { strip = new PolyChunkStrip(ChunkType.Strip_StripUVN); } else { strip = new PolyChunkStrip(ChunkType.Strip_Strip); } if (mat != null) { strip.IgnoreLight = mat.IgnoreLighting; strip.IgnoreSpecular = mat.IgnoreSpecular; strip.UseAlpha = mat.UseAlpha; strip.DoubleSide = mat.DoubleSided; strip.FlatShading = mat.FlatShading; strip.EnvironmentMapping = mat.EnvironmentMap; } for (int i1 = 0; i1 < strips[i].Count; i1++) { Strip item = strips[i][i1]; UV[] uv2 = null; if (mesh.UV != null) { uv2 = uvs[i][i1].ToArray(); } strip.Strips.Add(new PolyChunkStrip.Strip(item.Reversed, item.Indexes, uv2, null)); } cnkatt.Poly.Add(strip); } } ModelFile.CreateFile(System.IO.Path.ChangeExtension(filename, "sa2mdl"), model.Model, null, null, null, null, null, ModelFormat.Chunk); break; case ModelFormat.Chunk: Vertex[] VertexBuffer = new Vertex[0]; Vertex[] NormalBuffer = new Vertex[0]; foreach (NJS_OBJECT obj in model.Model.GetObjects().Where(obj => obj.Attach is ChunkAttach)) { ChunkAttach cnkatt = (ChunkAttach)obj.Attach; BasicAttach basatt = new BasicAttach() { Name = cnkatt.Name, Bounds = cnkatt.Bounds }; obj.Attach = basatt; if (cnkatt.Vertex != null) { foreach (VertexChunk chunk in cnkatt.Vertex) { if (VertexBuffer.Length < chunk.IndexOffset + chunk.VertexCount) { Array.Resize(ref VertexBuffer, chunk.IndexOffset + chunk.VertexCount); Array.Resize(ref NormalBuffer, chunk.IndexOffset + chunk.VertexCount); } Array.Copy(chunk.Vertices.ToArray(), 0, VertexBuffer, chunk.IndexOffset, chunk.Vertices.Count); Array.Copy(chunk.Normals.ToArray(), 0, NormalBuffer, chunk.IndexOffset, chunk.Normals.Count); } } NJS_MATERIAL material = new NJS_MATERIAL() { UseTexture = true }; int minVtx = int.MaxValue; int maxVtx = int.MinValue; foreach (PolyChunk chunk in cnkatt.Poly) { switch (chunk.Type) { case ChunkType.Bits_BlendAlpha: { PolyChunkBitsBlendAlpha c2 = (PolyChunkBitsBlendAlpha)chunk; material.SourceAlpha = c2.SourceAlpha; material.DestinationAlpha = c2.DestinationAlpha; } break; case ChunkType.Bits_MipmapDAdjust: break; case ChunkType.Bits_SpecularExponent: material.Exponent = ((PolyChunkBitsSpecularExponent)chunk).SpecularExponent; break; case ChunkType.Tiny_TextureID: case ChunkType.Tiny_TextureID2: { PolyChunkTinyTextureID c2 = (PolyChunkTinyTextureID)chunk; material.ClampU = c2.ClampU; material.ClampV = c2.ClampV; material.FilterMode = c2.FilterMode; material.FlipU = c2.FlipU; material.FlipV = c2.FlipV; material.SuperSample = c2.SuperSample; material.TextureID = c2.TextureID; } break; case ChunkType.Material_Diffuse: case ChunkType.Material_Ambient: case ChunkType.Material_DiffuseAmbient: case ChunkType.Material_Specular: case ChunkType.Material_DiffuseSpecular: case ChunkType.Material_AmbientSpecular: case ChunkType.Material_DiffuseAmbientSpecular: case ChunkType.Material_Diffuse2: case ChunkType.Material_Ambient2: case ChunkType.Material_DiffuseAmbient2: case ChunkType.Material_Specular2: case ChunkType.Material_DiffuseSpecular2: case ChunkType.Material_AmbientSpecular2: case ChunkType.Material_DiffuseAmbientSpecular2: { PolyChunkMaterial c2 = (PolyChunkMaterial)chunk; material.SourceAlpha = c2.SourceAlpha; material.DestinationAlpha = c2.DestinationAlpha; if (c2.Diffuse.HasValue) { material.DiffuseColor = c2.Diffuse.Value; } if (c2.Specular.HasValue) { material.SpecularColor = c2.Specular.Value; material.Exponent = c2.SpecularExponent; } } break; case ChunkType.Strip_Strip: case ChunkType.Strip_StripUVN: case ChunkType.Strip_StripUVH: case ChunkType.Strip_StripNormal: case ChunkType.Strip_StripUVNNormal: case ChunkType.Strip_StripUVHNormal: case ChunkType.Strip_StripColor: case ChunkType.Strip_StripUVNColor: case ChunkType.Strip_StripUVHColor: case ChunkType.Strip_Strip2: case ChunkType.Strip_StripUVN2: case ChunkType.Strip_StripUVH2: { PolyChunkStrip c2 = (PolyChunkStrip)chunk; material.DoubleSided = c2.DoubleSide; material.EnvironmentMap = c2.EnvironmentMapping; material.FlatShading = c2.FlatShading; material.IgnoreLighting = c2.IgnoreLight; material.IgnoreSpecular = c2.IgnoreSpecular; material.UseAlpha = c2.UseAlpha; bool hasVColor = false; switch (chunk.Type) { case ChunkType.Strip_StripColor: case ChunkType.Strip_StripUVNColor: case ChunkType.Strip_StripUVHColor: hasVColor = true; break; } bool hasUV = false; switch (chunk.Type) { case ChunkType.Strip_StripUVN: case ChunkType.Strip_StripUVH: case ChunkType.Strip_StripUVNColor: case ChunkType.Strip_StripUVHColor: case ChunkType.Strip_StripUVN2: case ChunkType.Strip_StripUVH2: hasUV = true; break; } List <Strip> strips = new List <Strip>(c2.StripCount); List <UV> uvs = hasUV ? new List <UV>() : null; List <Color> vcolors = hasVColor ? new List <Color>() : null; foreach (PolyChunkStrip.Strip strip in c2.Strips) { minVtx = Math.Min(minVtx, strip.Indexes.Min()); maxVtx = Math.Max(maxVtx, strip.Indexes.Max()); strips.Add(new Strip((ushort[])strip.Indexes.Clone(), strip.Reversed)); if (hasUV) { uvs.AddRange(strip.UVs); } if (hasVColor) { vcolors.AddRange(strip.VColors); } } NJS_MESHSET mesh = new NJS_MESHSET(strips.ToArray(), false, hasUV, hasVColor); if (hasUV) { uvs.CopyTo(mesh.UV); } if (hasVColor) { vcolors.CopyTo(mesh.VColor); } mesh.MaterialID = (ushort)basatt.Material.Count; basatt.Mesh.Add(mesh); basatt.Material.Add(material); material = new NJS_MATERIAL(material.GetBytes(), 0); } break; } } int numVtx = maxVtx - minVtx + 1; basatt.ResizeVertexes(numVtx); Array.Copy(VertexBuffer, minVtx, basatt.Vertex, 0, numVtx); Array.Copy(NormalBuffer, minVtx, basatt.Normal, 0, numVtx); foreach (NJS_MESHSET mesh in basatt.Mesh) { foreach (Poly poly in mesh.Poly) { for (int i = 0; i < poly.Indexes.Length; i++) { poly.Indexes[i] = (ushort)(poly.Indexes[i] - minVtx); } } } } ModelFile.CreateFile(System.IO.Path.ChangeExtension(filename, "sa1mdl"), model.Model, null, null, null, null, null, ModelFormat.Basic); break; } }
public override List<RenderInfo> Render(Device dev, EditorCamera camera, MatrixStack transform) { if (!camera.SphereInFrustum(Bounds)) return EmptyRenderInfo; List<RenderInfo> result = new List<RenderInfo>(); transform.Push(); transform.NJTranslate(Position); transform.NJRotateY(Rotation.Y); transform.NJScale((Scale.X), (Scale.Y), (Scale.Z)); RenderInfo outputInfo = new RenderInfo(VolumeMesh, 0, transform.Top, Material, null, FillMode.Solid, Bounds); if (Selected) { NJS_MATERIAL mat = new NJS_MATERIAL { DiffuseColor = Color.White, IgnoreLighting = true, UseAlpha = false }; result.Add(new RenderInfo(VolumeMesh, 0, transform.Top, mat, null, FillMode.WireFrame, Bounds)); } result.Add(outputInfo); transform.Pop(); return result; }
private void ExportObj() { SaveFileDialog a = new SaveFileDialog { DefaultExt = "obj", Filter = "OBJ Files|*.obj" }; if (a.ShowDialog() == DialogResult.OK) { using (StreamWriter objstream = new StreamWriter(a.FileName, false)) using (StreamWriter mtlstream = new StreamWriter(Path.ChangeExtension(a.FileName, "mtl"), false)) { int stepCount = LevelData.TextureBitmaps[LevelData.leveltexs].Length + LevelData.geo.COL.Count; if (LevelData.geo.Anim != null) { stepCount += LevelData.geo.Anim.Count; } List <NJS_MATERIAL> materials = new List <NJS_MATERIAL>(); ProgressDialog progress = new ProgressDialog("Exporting stage", stepCount, true, false); progress.Show(this); progress.SetTaskAndStep("Exporting..."); int totalVerts = 0; int totalNorms = 0; int totalUVs = 0; bool errorFlag = false; for (int i = 0; i < LevelData.geo.COL.Count; i++) { Direct3D.Extensions.WriteModelAsObj(objstream, LevelData.geo.COL[i].Model, ref materials, new MatrixStack(), ref totalVerts, ref totalNorms, ref totalUVs, ref errorFlag); progress.Step = String.Format("Mesh {0}/{1}", i + 1, LevelData.geo.COL.Count); progress.StepProgress(); Application.DoEvents(); } if (LevelData.geo.Anim != null) { for (int i = 0; i < LevelData.geo.Anim.Count; i++) { Direct3D.Extensions.WriteModelAsObj(objstream, LevelData.geo.Anim[i].Model, ref materials, new MatrixStack(), ref totalVerts, ref totalNorms, ref totalUVs, ref errorFlag); progress.Step = String.Format("Animation {0}/{1}", i + 1, LevelData.geo.Anim.Count); progress.StepProgress(); Application.DoEvents(); } } if (errorFlag) { MessageBox.Show("Error(s) encountered during export. Inspect the output file for more details.", "Failure", MessageBoxButtons.OK, MessageBoxIcon.Error); } #region Material Exporting string materialPrefix = LevelData.leveltexs; objstream.WriteLine("mtllib " + Path.GetFileNameWithoutExtension(a.FileName) + ".mtl"); for (int i = 0; i < materials.Count; i++) { NJS_MATERIAL material = materials[i]; mtlstream.WriteLine("newmtl material_{0}", i); mtlstream.WriteLine("Ka 1 1 1"); mtlstream.WriteLine(string.Format("Kd {0} {1} {2}", material.DiffuseColor.R / 255, material.DiffuseColor.G / 255, material.DiffuseColor.B / 255)); mtlstream.WriteLine(string.Format("Ks {0} {1} {2}", material.SpecularColor.R / 255, material.SpecularColor.G / 255, material.SpecularColor.B / 255)); mtlstream.WriteLine("illum 1"); if (!string.IsNullOrEmpty(LevelData.leveltexs) && material.UseTexture) { mtlstream.WriteLine("Map_Kd " + LevelData.TextureBitmaps[LevelData.leveltexs][material.TextureID].Name + ".png"); // save texture string mypath = Path.GetDirectoryName(a.FileName); BMPInfo item = LevelData.TextureBitmaps[LevelData.leveltexs][material.TextureID]; item.Image.Save(Path.Combine(mypath, item.Name + ".png")); } //progress.Step = String.Format("Texture {0}/{1}", material.TextureID + 1, LevelData.TextureBitmaps[LevelData.leveltexs].Length); //progress.StepProgress(); Application.DoEvents(); } #endregion progress.SetTaskAndStep("Export complete!"); } } }
public static void InitGizmo(Device d3dDevice) { #region Creating Streams From Resources MemoryStream x_NullStream = new MemoryStream(Resources.x_null); MemoryStream y_NullStream = new MemoryStream(Resources.y_null); MemoryStream z_NullStream = new MemoryStream(Resources.z_null); MemoryStream x_MoveStream = new MemoryStream(Resources.x_move); MemoryStream y_MoveStream = new MemoryStream(Resources.y_move); MemoryStream z_MoveStream = new MemoryStream(Resources.z_move); MemoryStream xy_MoveStream = new MemoryStream(Resources.xy_move); MemoryStream zx_MoveStream = new MemoryStream(Resources.zx_move); MemoryStream zy_MoveStream = new MemoryStream(Resources.zy_move); MemoryStream x_RotationStream = new MemoryStream(Resources.x_rotation); MemoryStream y_RotationStream = new MemoryStream(Resources.y_rotation); MemoryStream z_RotationStream = new MemoryStream(Resources.z_rotation); MemoryStream x_ScaleStream = new MemoryStream(Resources.x_scale); MemoryStream y_ScaleStream = new MemoryStream(Resources.y_scale); MemoryStream z_ScaleStream = new MemoryStream(Resources.z_scale); #endregion #region Temporary ExtendedMaterials ExtendedMaterial[] xMaterials; ExtendedMaterial[] yMaterials; ExtendedMaterial[] zMaterials; ExtendedMaterial[] doubleAxisMaterials; #endregion #region Loading Meshes and Materials from Streams XMoveMesh = Mesh.FromStream(x_MoveStream, MeshFlags.Managed, d3dDevice, out xMaterials); YMoveMesh = Mesh.FromStream(y_MoveStream, MeshFlags.Managed, d3dDevice, out yMaterials); ZMoveMesh = Mesh.FromStream(z_MoveStream, MeshFlags.Managed, d3dDevice, out zMaterials); XNullMesh = Mesh.FromStream(x_NullStream, MeshFlags.Managed, d3dDevice); YNullMesh = Mesh.FromStream(y_NullStream, MeshFlags.Managed, d3dDevice); ZNullMesh = Mesh.FromStream(z_NullStream, MeshFlags.Managed, d3dDevice); XYMoveMesh = Mesh.FromStream(xy_MoveStream, MeshFlags.Managed, d3dDevice, out doubleAxisMaterials); ZXMoveMesh = Mesh.FromStream(zx_MoveStream, MeshFlags.Managed, d3dDevice); ZYMoveMesh = Mesh.FromStream(zy_MoveStream, MeshFlags.Managed, d3dDevice); XRotateMesh = Mesh.FromStream(x_RotationStream, MeshFlags.Managed, d3dDevice); YRotateMesh = Mesh.FromStream(y_RotationStream, MeshFlags.Managed, d3dDevice); ZRotateMesh = Mesh.FromStream(z_RotationStream, MeshFlags.Managed, d3dDevice); XScaleMesh = Mesh.FromStream(x_ScaleStream, MeshFlags.Managed, d3dDevice); YScaleMesh = Mesh.FromStream(y_ScaleStream, MeshFlags.Managed, d3dDevice); ZScaleMesh = Mesh.FromStream(z_ScaleStream, MeshFlags.Managed, d3dDevice); BoxMesh = Mesh.Box(d3dDevice, 1, 1, 1); Mesh TexturedBox = BoxMesh.Clone(BoxMesh.Options.Value, VertexFormats.Position | VertexFormats.Normal | VertexFormats.Texture0 | VertexFormats.Texture1, BoxMesh.Device); //The following code makes the assumption that the vertices of the box are // generated the same way as they are in the April 2005 SDK using (VertexBuffer vb = TexturedBox.VertexBuffer) { CustomVertex.PositionNormalTextured[] verts = (CustomVertex.PositionNormalTextured[])vb.Lock(0, typeof(CustomVertex.PositionNormalTextured), LockFlags.None, TexturedBox.NumberVertices); try { for (int i = 0; i < verts.Length; i += 4) { verts[i + 0].Tu = 0.0f; verts[i + 0].Tv = 0.0f; verts[i + 1].Tu = 1.0f; verts[i + 1].Tv = 0.0f; verts[i + 2].Tu = 1.0f; verts[i + 2].Tv = 1.0f; verts[i + 3].Tu = 0.0f; verts[i + 3].Tv = 1.0f; } } finally { vb.Unlock(); } } BoxMesh = TexturedBox; XMaterial = new NJS_MATERIAL() { DiffuseColor = xMaterials[0].Material3D.Diffuse, Exponent = 0f, UseTexture = false, IgnoreLighting = true, IgnoreSpecular = true }; YMaterial = new NJS_MATERIAL() { DiffuseColor = yMaterials[0].Material3D.Diffuse, Exponent = 0f, UseTexture = false, IgnoreLighting = true, IgnoreSpecular = true }; ZMaterial = new NJS_MATERIAL() { DiffuseColor = zMaterials[0].Material3D.Diffuse, Exponent = 0f, UseTexture = false, IgnoreLighting = true, IgnoreSpecular = true }; DoubleAxisMaterial = new NJS_MATERIAL() { DiffuseColor = doubleAxisMaterials[0].Material3D.Diffuse, Exponent = 0f, UseTexture = false, IgnoreLighting = true, IgnoreSpecular = true }; HighlightMaterial = new NJS_MATERIAL() { DiffuseColor = Color.LightGoldenrodYellow, Exponent = 0f, UseTexture = false, IgnoreLighting = true, IgnoreSpecular = true }; ATexture = Texture.FromBitmap(d3dDevice, Resources.PointATexture, Usage.AutoGenerateMipMap, Pool.Managed); BTexture = Texture.FromBitmap(d3dDevice, Resources.PointBTexture, Usage.AutoGenerateMipMap, Pool.Managed); StandardMaterial = new NJS_MATERIAL() { DiffuseColor = Color.Gray, IgnoreLighting = true, IgnoreSpecular = true, UseAlpha = false, UseTexture = true, Exponent = 100f }; #endregion #region Cleanup x_NullStream.Close(); y_NullStream.Close(); z_NullStream.Close(); x_MoveStream.Close(); y_MoveStream.Close(); z_MoveStream.Close(); x_RotationStream.Close(); y_RotationStream.Close(); z_RotationStream.Close(); #endregion }
public static RenderInfo[] RenderSprite(Device dev, MatrixStack transform, Texture texture, Vector3 center, bool selected) { List<RenderInfo> result = new List<RenderInfo>(); NJS_MATERIAL mat = new NJS_MATERIAL { DiffuseColor = Color.White }; if (texture == null) texture = QuestionMark; result.Add(new RenderInfo(SquareMesh, 0, transform.Top, mat, texture, dev.RenderState.FillMode, new BoundingSphere(center.X, center.Y, center.Z, 8))); if (selected) { mat = new NJS_MATERIAL { DiffuseColor = Color.Yellow, UseAlpha = false }; result.Add(new RenderInfo(SquareMesh, 0, transform.Top, mat, null, FillMode.WireFrame, new BoundingSphere(center.X, center.Y, center.Z, 8))); } return result.ToArray(); }
/// <summary> /// Creates meshinfo to render /// </summary> /// <param name="material">A material with the current material properties</param> /// <param name="positions">The position data</param> /// <param name="normals">The normal data</param> /// <param name="colors">The color data</param> /// <param name="uvs">The uv data</param> /// <returns>A mesh info for the mesh</returns> public MeshInfo Process(NJS_MATERIAL material, List <IOVtx> positions, List <IOVtx> normals, List <IOVtx> colors, List <IOVtx> uvs) { // setting the material properties according to the parameters foreach (GCParameter param in parameters) { switch (param.type) { case ParameterType.BlendAlpha: BlendAlphaParameter blend = param as BlendAlphaParameter; material.SourceAlpha = blend.NJSourceAlpha; material.DestinationAlpha = blend.NJDestAlpha; break; case ParameterType.AmbientColor: AmbientColorParameter ambientCol = param as AmbientColorParameter; material.DiffuseColor = ambientCol.AmbientColor.SystemCol; break; case ParameterType.Texture: TextureParameter tex = param as TextureParameter; material.TextureID = tex.TextureID; material.FlipU = tex.Tile.HasFlag(GCTileMode.MirrorU); material.FlipV = tex.Tile.HasFlag(GCTileMode.MirrorV); material.ClampU = tex.Tile.HasFlag(GCTileMode.WrapU); material.ClampV = tex.Tile.HasFlag(GCTileMode.WrapV); // no idea why, but ok material.ClampU &= tex.Tile.HasFlag(GCTileMode.Unk_1); material.ClampV &= tex.Tile.HasFlag(GCTileMode.Unk_1); break; case ParameterType.TexCoordGen: TexCoordGenParameter gen = param as TexCoordGenParameter; material.EnvironmentMap = gen.TexGenSrc == GCTexGenSrc.Normal; break; } } // filtering out the double loops List <Loop> corners = new List <Loop>(); List <Poly> polys = new List <Poly>(); foreach (GCPrimitive prim in primitives) { int j = 0; ushort[] indices = new ushort[prim.loops.Count]; foreach (Loop l in prim.loops) { ushort t = (ushort)corners.FindIndex(x => x.Equals(l)); if (t == 0xFFFF) { indices[j] = (ushort)corners.Count; corners.Add(l); } else { indices[j] = t; } j++; } // creating the polygons if (prim.primitiveType == GCPrimitiveType.Triangles) { for (int i = 0; i < indices.Length; i += 3) { Triangle t = new Triangle(); t.Indexes[0] = indices[i]; t.Indexes[1] = indices[i + 1]; t.Indexes[2] = indices[i + 2]; polys.Add(t); } } else if (prim.primitiveType == GCPrimitiveType.TriangleStrip) { polys.Add(new Strip(indices, false)); } } // creating the vertex data VertexData[] vertData = new VertexData[corners.Count]; bool hasNormals = normals != null; bool hasColors = colors != null; bool hasUVs = uvs != null; for (int i = 0; i < corners.Count; i++) { Loop l = corners[i]; vertData[i] = new SAModel.VertexData( (Vector3)positions[l.PositionIndex], hasNormals ? (Vector3)normals[l.NormalIndex] : new Vector3(0, 1, 0), hasColors ? (Color)colors[l.Color0Index] : new Color(255, 255, 255, 255), hasUVs ? (UV)uvs[l.UV0Index] : new UV(0, 0) ); } return(new MeshInfo(new NJS_MATERIAL(material), polys.ToArray(), vertData, hasUVs, hasColors)); }