private bool TryExtractTriShape(NiObject obj, Matrix4 worldMatrix, bool invertTris, bool both, ref Vector3[] vertices, ref Triangle[] outtriangles) { var shape = obj as NiTriShape; if (shape == null) { return(false); } eFaceDrawMode mode = FindDrawMode(shape); if (mode == eFaceDrawMode.DRAW_CCW_OR_BOTH) { mode = both ? eFaceDrawMode.DRAW_BOTH : eFaceDrawMode.DRAW_CCW; } Matrix4 myMatrix = ComputeWorldMatrix(shape) * worldMatrix; var data = shape.Data.Object as NiTriShapeData; if (data.Triangles.Length == 0) { return(false); } vertices = new Vector3[data.Vertices.Length]; for (int i = 0; i < data.Vertices.Length; i++) { vertices[i] = Vector3.Transform(data.Vertices[i], myMatrix); } var triangles = new List <Triangle>(); // CCW if (mode == eFaceDrawMode.DRAW_BOTH || (mode == eFaceDrawMode.DRAW_CCW) != invertTris) { for (int i = 0; i < data.Triangles.Length; i++) { triangles.Add(new Triangle(data.Triangles[i].Z, data.Triangles[i].Y, data.Triangles[i].X)); } } // CC if (mode == eFaceDrawMode.DRAW_BOTH || (mode == eFaceDrawMode.DRAW_CW) != invertTris) { triangles.AddRange(data.Triangles); } outtriangles = triangles.ToArray(); return(true); }
/// <summary> /// Initializes a new instance of the <see cref="NiStencilProperty"/> class. /// </summary> /// <param name="file">The file.</param> /// <param name="reader">The reader.</param> public NiStencilProperty(NiFile file, BinaryReader reader) : base(file, reader) { if (this.File.Header.Version <= eNifVersion.VER_10_0_1_2) { this.Flags = reader.ReadUInt16(); } if (this.File.Header.Version <= eNifVersion.VER_20_0_0_5) { this.IsStencilEnabled = reader.ReadBoolean(Version); this.StencilFunction = (eStencilCompareMode)reader.ReadUInt32(); this.StencilRef = reader.ReadUInt32(); this.StencilMask = reader.ReadUInt32(); this.FailAction = (eStencilAction)reader.ReadUInt32(); this.ZFailAction = (eStencilAction)reader.ReadUInt32(); this.PassAction = (eStencilAction)reader.ReadUInt32(); this.FaceDrawMode = (eFaceDrawMode)reader.ReadUInt32(); } if (this.File.Header.Version >= eNifVersion.VER_20_1_0_3) { this.Flags = reader.ReadUInt16(); this.StencilRef = reader.ReadUInt32(); this.StencilMask = reader.ReadUInt32(); } }
private bool TryExtractTriStrips(NiObject obj, Matrix4 worldMatrix, bool invertTris, bool both, ref Vector3[] vertices, ref Triangle[] outtriangles) { var strips = obj as NiTriStrips; if (strips == null) { return(false); } eFaceDrawMode mode = FindDrawMode(strips); if (mode == eFaceDrawMode.DRAW_CCW_OR_BOTH) { mode = both ? eFaceDrawMode.DRAW_BOTH : eFaceDrawMode.DRAW_CCW; } Matrix4 myMatrix = ComputeWorldMatrix(strips) * worldMatrix; var data = strips.Data.Object as NiTriStripsData; if (data.Vertices.Length == 0) { return(false); } vertices = new Vector3[data.Vertices.Length]; for (int i = 0; i < data.Vertices.Length; i++) { vertices[i] = Vector3.Transform(data.Vertices[i], myMatrix); } var triangles = new List <Triangle>(); foreach (var points in data.Points) { // CCW if (mode == eFaceDrawMode.DRAW_BOTH || (mode == eFaceDrawMode.DRAW_CCW) != invertTris) { ushort a = points[0]; ushort b = points[0]; ushort c = points[1]; bool flip = false; for (int s = 2; s < points.Length; s++) { a = b; b = c; c = points[s]; if (a != b && b != c && c != a) { triangles.Add(!flip ? new Triangle(a, c, b) : new Triangle(a, b, c)); } flip = !flip; } } // CC if (mode == eFaceDrawMode.DRAW_BOTH || (mode == eFaceDrawMode.DRAW_CW) != invertTris) { ushort a = points[0]; ushort b = points[0]; ushort c = points[1]; bool flip = false; for (int s = 2; s < points.Length; s++) { a = b; b = c; c = points[s]; if (a != b && b != c && c != a) { triangles.Add(!flip ? new Triangle(a, b, c) : new Triangle(a, c, b)); } flip = !flip; } } } outtriangles = triangles.ToArray(); return(true); }
public static void AddModelToObj(WavefrontObjFile objFile, NiFile model, Matrix worldMatrix, string[] filter, bool exclude) { if (model == null) { return; } bool foundMesh = false; // find all trimeshs and tristrips foreach (NiObject obj in model.ObjectsByRef.Values) { var avNode = obj as NiAVObject; if (avNode == null || ((exclude && IsFiltered(avNode, filter)) || (!exclude && !IsFiltered(avNode, filter)))) { continue; } var shape = obj as NiTriShape; if (shape != null) { eFaceDrawMode mode = FindDrawMode(shape); foundMesh = true; Matrix myMatrix = ComputeWorldMatrix(shape) * worldMatrix; var data = shape.Data.Object as NiTriShapeData; if (data.Triangles.Length == 0) { continue; } var transformedVertices = new Vector3[data.Vertices.Length]; for (int i = 0; i < data.Vertices.Length; i++) { Vector4 transformedVector = Vector3.Transform(data.Vertices[i], myMatrix); transformedVertices[i] = new Vector3(transformedVector.X, transformedVector.Y, transformedVector.Z); } var triangles = new List <Triangle>(); // CCW if (mode == eFaceDrawMode.DRAW_BOTH || mode == eFaceDrawMode.DRAW_CCW || mode == eFaceDrawMode.DRAW_CCW_OR_BOTH) { for (int i = 0; i < data.Triangles.Length; i++) { triangles.Add(new Triangle(data.Triangles[i].Z, data.Triangles[i].Y, data.Triangles[i].X)); } } // CC if (mode == eFaceDrawMode.DRAW_BOTH || mode == eFaceDrawMode.DRAW_CW) { foreach (Triangle t in data.Triangles) { triangles.Add(t); } } objFile.AddMesh(transformedVertices, triangles.ToArray()); } var strips = obj as NiTriStrips; if (strips != null) { eFaceDrawMode mode = FindDrawMode(strips); foundMesh = true; Matrix myMatrix = ComputeWorldMatrix(strips) * worldMatrix; var data = strips.Data.Object as NiTriStripsData; var transformedVertices = new Vector3[data.Vertices.Length]; for (int i = 0; i < data.Vertices.Length; i++) { Vector4 transformedVector = Vector3.Transform(data.Vertices[i], myMatrix); transformedVertices[i] = new Vector3(transformedVector.X, transformedVector.Y, transformedVector.Z); } var triangles = new List <Triangle>(); foreach (var points in data.Points) { // CCW if (mode == eFaceDrawMode.DRAW_BOTH || mode == eFaceDrawMode.DRAW_CCW || mode == eFaceDrawMode.DRAW_CCW_OR_BOTH) { for (int i = 0; i < points.Length - 2; i++) { triangles.Add(i % 2 == 0 ? new Triangle(points[i + 2], points[i + 1], points[i + 0]) : new Triangle(points[i + 2], points[i + 0], points[i + 1])); } } // CC if (mode == eFaceDrawMode.DRAW_BOTH || mode == eFaceDrawMode.DRAW_CW) { for (int i = 0; i < points.Length - 2; i++) { triangles.Add(i % 2 == 0 ? new Triangle(points[i + 0], points[i + 1], points[i + 2]) : new Triangle(points[i + 0], points[i + 2], points[i + 1])); } } } objFile.AddMesh(transformedVertices, triangles.ToArray()); } } if (!foundMesh && filter[0] == "pickee") { // no pickee found, use collide Console.WriteLine("Warning: Using collidee!"); AddModelToObj(objFile, model, worldMatrix, new[] { "collide" }, false); } }
/// <summary> /// Initializes a new instance of the <see cref="NiStencilProperty"/> class. /// </summary> /// <param name="file">The file.</param> /// <param name="reader">The reader.</param> public NiStencilProperty(NiFile file, BinaryReader reader) : base(file, reader) { if (this.File.Header.Version <= eNifVersion.VER_10_0_1_2) { this.Flags = reader.ReadUInt16(); } if (this.File.Header.Version <= eNifVersion.VER_20_0_0_5) { this.IsStencilEnabled = reader.ReadBoolean(Version); this.StencilFunction = (eStencilCompareMode)reader.ReadUInt32(); this.StencilRef = reader.ReadUInt32(); this.StencilMask = reader.ReadUInt32(); this.FailAction = (eStencilAction)reader.ReadUInt32(); this.ZFailAction = (eStencilAction)reader.ReadUInt32(); this.PassAction = (eStencilAction)reader.ReadUInt32(); this.FaceDrawMode = (eFaceDrawMode)reader.ReadUInt32(); } if (this.File.Header.Version >= eNifVersion.VER_20_1_0_3) { this.Flags = reader.ReadUInt16(); this.StencilRef = reader.ReadUInt32(); this.StencilMask = reader.ReadUInt32(); } }