public void OnRender(TriangleNet.Mesh triangleMesh) { /*data.SetMesh(mesh); * UniMesh.vertices = data.Vertices; * UniMesh.triangles = data.Triangles;*/ var _mesh = GetComponent <MeshFilter>().mesh; if (!_mesh) { _mesh = new Mesh(); GetComponent <MeshFilter>().mesh = _mesh; } _mesh.Clear(); _mesh.vertices = TriangleConverter.ConverteVertices(triangleMesh.Vertices); List <Vector3> normals = new List <Vector3>(); for (int i = 0; i < _mesh.vertices.Length; i++) { normals.Add(Vector3.back); } _mesh.normals = normals.ToArray(); _mesh.uv = TriangleConverter.ConverteUVs(triangleMesh); _mesh.triangles = TriangleConverter.ConverteTriangles(triangleMesh.Triangles); }
public void BuildMeshFromGeometry() { triMesh = new TriangleNet.Mesh(); triMesh.behavior.Quality = true; triMesh.behavior.MinAngle = 1f; triMesh.Triangulate(Geometry); // var statistic = new Statistic(); // statistic.Update(triMesh, 1); // Refine by setting a custom maximum area constraint. //triMesh.Refine(statistic.LargestArea / 4); //triMesh.Smooth(); triMesh.Renumber(); UniMesh.vertices = TriangleConverter.ConverteVertices(triMesh.Vertices); UniMesh.RecalculateNormals(); UniMesh.triangles = TriangleConverter.ConverteTriangles(triMesh.Triangles); UniMesh.uv = TriangleConverter.ConverteUVs(triMesh); Debug.Log(string.Format("width {0:0.00}, height {1:0.00}; min {2:0.00}, {3:0.00}; max {4:0.00}, {5:0.00}", triMesh.Bounds.Width, triMesh.Bounds.Height, triMesh.Bounds.Xmin, triMesh.Bounds.Ymin, triMesh.Bounds.Xmax, triMesh.Bounds.Ymax)); }
public GenericModel ToGenericModel() { var model = new GenericModel(); model.Skeleton = skeleton; var mesh = new GenericMesh(); for (int i = 0; i < PositionBuffer.Length; i++) { var vertex = new GenericVertex() { Pos = PositionBuffer[i].Xyz }; if (UV0Buffer.Length == PositionBuffer.Length) { vertex.UV0 = UV0Buffer[i]; } if (UV1Buffer.Length == PositionBuffer.Length) { vertex.UV1 = UV1Buffer[i]; } if (UV2Buffer.Length == PositionBuffer.Length) { vertex.UV2 = UV2Buffer[i]; } mesh.Vertices.Add(vertex); } List <short> tris = new List <short>(); tris.AddRange(IndexBuffer); TriangleConverter.StripToList(tris, out tris); short max = 0; foreach (var t in tris) { if (t > mesh.VertexCount) { break; } max = Math.Max(max, t); mesh.Triangles.Add((uint)t); } Console.WriteLine(max.ToString("X") + " " + mesh.VertexCount.ToString("X")); model.Meshes.Add(mesh); return(model); }
/// <summary> /// Constructor of an additive claims reserving model given a run-off triangle. /// </summary> /// <param name="triangle">Triangle to be developed.</param> /// <param name="premiums">Premiums earned ordered by accident year in ascending order.</param> /// <exception cref="DimensionMismatchException">Thrown when the count of premia does not match the number of periods observed.</exception> public AdditiveMethod(ITriangle triangle, IEnumerable <decimal> premiums) : base(TriangleConverter <IncrementalTriangle> .Convert(triangle)) { int n = premiums.Count(); if (n != Triangle.Periods) { throw new DimensionMismatchException(Triangle.Periods, n); } _premiums = premiums; _factors = new Lazy <IReadOnlyList <decimal> >(CalculateFactors); _cumulativeTriangle = TriangleConverter <CumulativeTriangle> .Convert(triangle); }
private void b_DoWork(object sender, DoWorkEventArgs e) { if (e == null) { return; } ObjectOptimizerForm form = e.Argument as ObjectOptimizerForm; form._newPointCount = 0; foreach (ObjectOptimization a in form._results) { if (a == null || a._object == null || a._object._manager == null || a._object._manager._triangles == null || a._facepoints == null) { return; } TriangleConverter triConverter = new TriangleConverter(chkUseStrips.Checked, (uint)numCacheSize.Value, (uint)numMinStripLen.Value, chkPushCacheHits.Checked); Facepoint[] points = new Facepoint[a._object._manager._triangles._indices.Length]; uint[] indices = a._object._manager._triangles._indices; bool ccw = Collada._importOptions._forceCCW; //Indices are written in reverse for each triangle, //so they need to be set to a triangle in reverse if not CCW for (int t = 0; t < a._object._manager._triangles._indices.Length; t++) { points[ccw ? t : t - t % 3 + (2 - t % 3)] = a._facepoints[indices[t]]; } List <PrimitiveGroup> p = triConverter.GroupPrimitives(points, out int pc, out int fc); if (chkAllowIncrease.Checked || pc < a._pointCount) { a._pointCount = pc; a._faceCount = fc; a._groups = p; } form._newPointCount += a._pointCount; } e.Result = form; }
public void ConvertTriangles() { var points = new List <Point> { new Point(0, 1, 0), new Point(1, 0.8f, 0), new Point(0.1f, 1, 0), new Point(0, 1.1f, 0), new Point(-0.7f, 0.7f, 0), new Point(0, -1, 0), new Point(-0.9f, -0.9f, 0), new Point(-1, 0, 0), new Point(-0.8f, 0.7f, 0) }; var converter = new TriangleConverter(); var result = converter.Convert(points); Assert.Equal(points.Count, result.Count()); }
public static void Export(string FileName, ExportSettings settings, List <STGenericMesh> Meshes, List <STGenericMaterial> Materials, List <STGenericTexture> Textures, STSkeleton skeleton = null, List <int> NodeArray = null) { if (Materials == null) { Materials = new List <STGenericMaterial>(); } if (settings.RemoveDuplicateVertices) { foreach (var mesh in Meshes) { mesh.RemoveDuplicateVertices(); } } Console.WriteLine($"DAE Materials {Materials.Count}"); List <string> failedTextureExport = new List <string>(); Dictionary <string, STGenericMaterial> MaterialRemapper = new Dictionary <string, STGenericMaterial>(); using (ColladaWriter writer = new ColladaWriter(FileName, settings)) { writer.WriteAsset(); if (Materials.Count > 0) { List <string> textureNames = new List <string>(); for (int i = 0; i < Textures?.Count; i++) { if (!textureNames.Contains(Textures[i].Name)) { textureNames.Add(Textures[i].Name); } if (settings.ExportTextures) { try { var bitmap = Textures[i].GetBitmap(); if (bitmap != null) { string textureName = Textures[i].Name; if (textureName.RemoveIllegaleFileNameCharacters() != textureName) { string properName = textureName.RemoveIllegaleFileNameCharacters(); for (int m = 0; m < Materials?.Count; m++) { foreach (var tex in Materials[m].TextureMaps) { if (tex.Name == textureName) { tex.Name = properName; } } } textureName = properName; } if (settings.ImageFolder != "") { bitmap.Save($"{settings.ImageFolder}/{textureName}.png"); } else { bitmap.Save($"{textureName}.png"); } bitmap.Dispose(); GC.Collect(); } } catch (Exception ex) { failedTextureExport.Add(Textures[i].Name); } } } for (int i = 0; i < Materials.Count; i++) { if (Materials[i].Name == null) { Materials[i].Name = $"Material{i}"; } } List <Material> materials = new List <Material>(); foreach (var mat in Materials) { Material material = new Material(); material.Name = mat.Name; if (!MaterialRemapper.ContainsKey(mat.Name)) { MaterialRemapper.Add(mat.Name, mat); } else { string name = Utils.RenameDuplicateString(mat.Name, MaterialRemapper.Keys.ToList()); MaterialRemapper.Add(name, mat); material.Name = name; } if (mat.DiffuseColor != null) { material.DiffuseColor = new float[4] { mat.DiffuseColor.R / 255.0F, mat.DiffuseColor.G / 255.0F, mat.DiffuseColor.B / 255.0F, mat.DiffuseColor.A / 255.0F } } ; materials.Add(material); foreach (var tex in mat.TextureMaps) { TextureMap texMap = new TextureMap(); texMap.Name = tex.Name; if (tex.Type == STTextureType.Diffuse) { texMap.Type = PhongTextureType.diffuse; } else if (tex.Type == STTextureType.Normal) { texMap.Type = PhongTextureType.bump; } else if (tex.Type == STTextureType.Specular) { texMap.Type = PhongTextureType.specular; } else if (tex.Type == STTextureType.Emission) { texMap.Type = PhongTextureType.emission; } else { continue; //Skip adding unknown types } if (tex.WrapU == STTextureWrapMode.Repeat) { texMap.WrapModeS = SamplerWrapMode.WRAP; } else if (tex.WrapU == STTextureWrapMode.Mirror) { texMap.WrapModeS = SamplerWrapMode.MIRROR; } else if (tex.WrapU == STTextureWrapMode.Clamp) { texMap.WrapModeS = SamplerWrapMode.CLAMP; } if (tex.WrapV == STTextureWrapMode.Repeat) { texMap.WrapModeT = SamplerWrapMode.WRAP; } else if (tex.WrapV == STTextureWrapMode.Mirror) { texMap.WrapModeT = SamplerWrapMode.MIRROR; } else if (tex.WrapV == STTextureWrapMode.Clamp) { texMap.WrapModeT = SamplerWrapMode.CLAMP; } //If no textures are saved, still keep images references //So the user can still dump textures after if (Textures?.Count == 0 && !textureNames.Contains(texMap.Name)) { textureNames.Add($"{texMap.Name}"); } material.Textures.Add(texMap); } } writer.WriteLibraryImages(textureNames.ToArray()); writer.WriteLibraryMaterials(materials); writer.WriteLibraryEffects(materials); } else { writer.WriteLibraryImages(); } if (skeleton != null) { for (int i = 0; i < skeleton.Bones.Count; i++) { if (skeleton.Bones[i].Name == null) { skeleton.Bones[i].Name = $"Bones{i}"; } } //Search for bones with rigging first List <string> riggedBones = new List <string>(); if (settings.OnlyExportRiggedBones) { for (int i = 0; i < Meshes.Count; i++) { for (int v = 0; v < Meshes[i].Vertices.Count; v++) { var vertex = Meshes[i].Vertices[v]; for (int j = 0; j < vertex.BoneIndices.Count; j++) { int id = -1; if (NodeArray != null && NodeArray.Count > vertex.BoneIndices[j]) { id = NodeArray[vertex.BoneIndices[j]]; } else { id = vertex.BoneIndices[j]; } if (id < skeleton.Bones.Count && id != -1) { riggedBones.Add(skeleton.Bones[id].Name); } } } } } foreach (var bone in skeleton.Bones) { if (settings.OnlyExportRiggedBones && !riggedBones.Contains(bone.Name)) { Console.WriteLine("Skipping " + bone.Name); continue; } //Set the inverse matrix var inverse = skeleton.GetBoneTransform(bone).Inverted(); var transform = bone.GetTransform(); float[] Transform = new float[] { transform.M11, transform.M21, transform.M31, transform.M41, transform.M12, transform.M22, transform.M32, transform.M42, transform.M13, transform.M23, transform.M33, transform.M43, transform.M14, transform.M24, transform.M34, transform.M44 }; float[] InvTransform = new float[] { inverse.M11, inverse.M21, inverse.M31, inverse.M41, inverse.M12, inverse.M22, inverse.M32, inverse.M42, inverse.M13, inverse.M23, inverse.M33, inverse.M43, inverse.M14, inverse.M24, inverse.M34, inverse.M44 }; writer.AddJoint(bone.Name, bone.ParentIndex == -1 ? "" : skeleton.Bones[bone.ParentIndex].Name, Transform, InvTransform, new float[3] { bone.Position.X, bone.Position.Y, bone.Position.Z }, new float[3] { bone.EulerRotation.X, bone.EulerRotation.Y, bone.EulerRotation.Z }, new float[3] { bone.Scale.X, bone.Scale.Y, bone.Scale.Z }); } } for (int i = 0; i < Meshes.Count; i++) { if (Meshes[i].Name == null) { Meshes[i].Name = $"Mesh{i}"; } } int meshIndex = 0; writer.StartLibraryGeometries(); foreach (var mesh in Meshes) { int[] IndexTable = null; if (NodeArray != null) { IndexTable = NodeArray.ToArray(); } writer.StartGeometry(mesh.Name); /* if (mesh.MaterialIndex != -1 && Materials.Count > mesh.MaterialIndex) * { * writer.CurrentMaterial = Materials[mesh.MaterialIndex].Text; * Console.WriteLine($"MaterialIndex {mesh.MaterialIndex } {Materials[mesh.MaterialIndex].Text}"); * }*/ if (settings.TransformColorUVs) { List <STVertex> transformedVertices = new List <STVertex>(); foreach (var poly in mesh.PolygonGroups) { var mat = poly.Material; if (mat == null) { continue; } var faces = poly.Faces; for (int v = 0; v < poly.Faces.Count; v += 3) { if (faces.Count < v + 2) { break; } var diffuse = mat.TextureMaps.FirstOrDefault(x => x.Type == STTextureType.Diffuse); STTextureTransform transform = new STTextureTransform(); if (diffuse != null) { transform = diffuse.Transform; } var vertexA = mesh.Vertices[(int)faces[v]]; var vertexB = mesh.Vertices[(int)faces[v + 1]]; var vertexC = mesh.Vertices[(int)faces[v + 2]]; if (!transformedVertices.Contains(vertexA)) { vertexA.TexCoords[0] = (vertexA.TexCoords[0] * transform.Scale) + transform.Translate; transformedVertices.Add(vertexA); } if (!transformedVertices.Contains(vertexB)) { vertexB.TexCoords[0] = (vertexB.TexCoords[0] * transform.Scale) + transform.Translate; transformedVertices.Add(vertexB); } if (!transformedVertices.Contains(vertexC)) { vertexC.TexCoords[0] = (vertexC.TexCoords[0] * transform.Scale) + transform.Translate; transformedVertices.Add(vertexC); } } } } // collect sources List <float> Position = new List <float>(); List <float> Normal = new List <float>(); List <float> UV1 = new List <float>(); List <float> UV2 = new List <float>(); List <float> UV3 = new List <float>(); List <float> Color = new List <float>(); List <float> Color2 = new List <float>(); List <int[]> BoneIndices = new List <int[]>(); List <float[]> BoneWeights = new List <float[]>(); bool HasNormals = false; bool HasColors = false; bool HasColors2 = false; bool HasUV0 = false; bool HasUV1 = false; bool HasUV2 = false; bool HasBoneIds = false; mesh.OptimizeVertices(); foreach (var vertex in mesh.Vertices) { //Remove zero weights if (settings.OptmizeZeroWeights) { float MaxWeight = 1; for (int i = 0; i < 4; i++) { if (vertex.BoneWeights.Count <= i) { continue; } if (vertex.BoneIndices.Count < i + 1) { vertex.BoneWeights[i] = 0; MaxWeight = 0; } else { float weight = vertex.BoneWeights[i]; if (vertex.BoneWeights.Count == i + 1) { weight = MaxWeight; } if (weight >= MaxWeight) { weight = MaxWeight; MaxWeight = 0; } else { MaxWeight -= weight; } vertex.BoneWeights[i] = weight; } } } if (vertex.Normal != Vector3.Zero) { HasNormals = true; } if (vertex.Colors.Length > 0 && settings.UseVertexColors) { HasColors = true; } if (vertex.Colors.Length > 1 && settings.UseVertexColors) { HasColors2 = true; } if (vertex.TexCoords.Length > 0) { HasUV0 = true; } if (vertex.TexCoords.Length > 1) { HasUV1 = true; } if (vertex.TexCoords.Length > 2) { HasUV2 = true; } if (vertex.BoneIndices.Count > 0) { HasBoneIds = true; } Position.Add(vertex.Position.X); Position.Add(vertex.Position.Y); Position.Add(vertex.Position.Z); Normal.Add(vertex.Normal.X); Normal.Add(vertex.Normal.Y); Normal.Add(vertex.Normal.Z); for (int i = 0; i < vertex.TexCoords.Length; i++) { var texCoord = vertex.TexCoords[i]; if (settings.FlipTexCoordsVertical) { texCoord = new Vector2(texCoord.X, 1 - texCoord.Y); } if (i == 0) { UV1.Add(texCoord.X); UV1.Add(texCoord.Y); } if (i == 1) { UV2.Add(texCoord.X); UV2.Add(texCoord.Y); } if (i == 2) { UV3.Add(texCoord.X); UV3.Add(texCoord.Y); } } if (vertex.Colors.Length > 0) { Color.AddRange(new float[] { vertex.Colors[0].X, vertex.Colors[0].Y, vertex.Colors[0].Z, vertex.Colors[0].W }); } if (vertex.Colors.Length > 1) { Color2.AddRange(new float[] { vertex.Colors[1].X, vertex.Colors[1].Y, vertex.Colors[1].Z, vertex.Colors[1].W }); } List <int> bIndices = new List <int>(); List <float> bWeights = new List <float>(); for (int b = 0; b < vertex.BoneIndices.Count; b++) { if (b > mesh.VertexSkinCount - 1) { continue; } if (vertex.BoneWeights.Count > b) { if (vertex.BoneWeights[b] == 0) { continue; } } int index = -1; if (IndexTable != null) { index = (int)IndexTable[vertex.BoneIndices[b]]; } else { index = (int)vertex.BoneIndices[b]; } if (index != -1 && index < skeleton?.Bones.Count) { bIndices.Add(index); } //Some models may only use indices (single bind, rigid skin) if (vertex.BoneWeights.Count > b) { bWeights.Add(vertex.BoneWeights[b]); } else { bWeights.Add(1); } } if (bIndices.Count == 0 && mesh.BoneIndex != -1) { HasBoneIds = true; bIndices.Add(mesh.BoneIndex); bWeights.Add(1); } BoneIndices.Add(bIndices.ToArray()); BoneWeights.Add(bWeights.ToArray()); } List <TriangleList> triangleLists = new List <TriangleList>(); if (mesh.PolygonGroups.Count > 0) { foreach (var group in mesh.PolygonGroups) { TriangleList triangleList = new TriangleList(); triangleLists.Add(triangleList); STGenericMaterial material = new STGenericMaterial(); if (group.MaterialIndex != -1 && Materials.Count > group.MaterialIndex) { material = Materials[group.MaterialIndex]; } if (group.Material != null) { material = group.Material; } if (MaterialRemapper.Values.Any(x => x == material)) { var key = MaterialRemapper.FirstOrDefault(x => x.Value == material).Key; triangleList.Material = key; } else if (material.Name != string.Empty) { triangleList.Material = material.Name; } List <uint> faces = new List <uint>(); if (group.PrimitiveType == STPrimitiveType.TriangleStrips) { faces = TriangleConverter.ConvertTriangleStripsToTriangles(group.Faces); } else { faces = group.Faces; } for (int i = 0; i < faces.Count; i++) { triangleList.Indices.Add(faces[i]); } } } // write sources writer.WriteGeometrySource(mesh.Name, SemanticType.POSITION, Position.ToArray(), triangleLists.ToArray()); if (HasNormals) { writer.WriteGeometrySource(mesh.Name, SemanticType.NORMAL, Normal.ToArray(), triangleLists.ToArray()); } if (HasColors) { writer.WriteGeometrySource(mesh.Name, SemanticType.COLOR, Color.ToArray(), triangleLists.ToArray(), 0); } if (HasColors2) { writer.WriteGeometrySource(mesh.Name, SemanticType.COLOR, Color2.ToArray(), triangleLists.ToArray(), 1); } Console.WriteLine($"HasUV0 {HasUV0} {UV1.Count}"); if (HasUV0) { writer.WriteGeometrySource(mesh.Name, SemanticType.TEXCOORD, UV1.ToArray(), triangleLists.ToArray(), 0); } if (HasUV1) { writer.WriteGeometrySource(mesh.Name, SemanticType.TEXCOORD, UV2.ToArray(), triangleLists.ToArray(), 1); } if (HasUV2) { writer.WriteGeometrySource(mesh.Name, SemanticType.TEXCOORD, UV3.ToArray(), triangleLists.ToArray(), 2); } if (HasBoneIds) { writer.AttachGeometryController(BoneIndices, BoneWeights); } writer.EndGeometryMesh(); } writer.EndGeometrySection(); } }
/// <summary> /// Constructor of a loss development claims reserving model given a run-off triangle. /// </summary> /// <param name="triangle">Triangle to be developed.</param> /// <param name="factors">Factors the triangle is to be developed with.</param> /// <exception cref="DimensionMismatchException">Thrown when the number of factors does not match the number of periods observed.</exception> public LossDevelopment(ITriangle triangle, IEnumerable <decimal> factors) : base(TriangleConverter <CumulativeTriangle> .Convert(triangle)) { int n = factors.Count(); if (n != Triangle.Periods) { throw new DimensionMismatchException(Triangle.Periods, n); } _factors = new Lazy <IReadOnlyList <decimal> >(() => factors.ToList().AsReadOnly()); }
/// <summary> /// Constructor of a Cape Cod model given a run-off triangle. /// </summary> /// <param name="triangle">Triangle to be developed.</param> /// <param name="factors">Factors the triangle is to be developed with.</param> /// <param name="volumeMeasures">Volume measures needed for the claims development according to the model.</param> /// <exception cref="DimensionMismatchException">Thrown when the number of factors does not match the number of periods observed.</exception> /// <exception cref="DimensionMismatchException">Thrown when the number of volume measures does not match the number of periods observed.</exception> public CapeCod(ITriangle triangle, IEnumerable <decimal> factors, IEnumerable <decimal> volumeMeasures) : base(TriangleConverter <CumulativeTriangle> .Convert(triangle)) { int factorsCount = factors.Count(); if (factorsCount != triangle.Periods) { throw new DimensionMismatchException(triangle.Periods, factorsCount); } int vmCount = volumeMeasures.Count(); if (vmCount != triangle.Periods) { throw new DimensionMismatchException(triangle.Periods, vmCount); } _factors = new Lazy <IReadOnlyList <decimal> >(() => factors.ToList().AsReadOnly()); _volumeMeasures = volumeMeasures; }
void Awake() { data = new TriangleConverter(); }
/// <summary> /// /// </summary> /// <param name="pobj"></param> private Mesh ProcessPOBJ(HSD_POBJ pobj, HSD_JOBJ parent, HSD_JOBJ singleBind) { Mesh m = new Mesh(); m.Name = "pobj"; m.PrimitiveType = PrimitiveType.Triangle; m.MaterialIndex = 0; var dl = pobj.ToDisplayList(); var envelopes = pobj.EnvelopeWeights; var parentTransform = Matrix4.Identity; if (parent != null) { parentTransform = WorldTransforms[jobjToIndex[parent]]; } var singleBindTransform = Matrix4.Identity; if (singleBind != null) { singleBindTransform = WorldTransforms[jobjToIndex[singleBind]]; } Dictionary <HSD_JOBJ, Bone> jobjToBone = new Dictionary <HSD_JOBJ, Bone>(); if (envelopes != null) { foreach (var jobj in Jobjs) { var bone = new Bone(); bone.Name = JobjNodes[jobjToIndex[jobj]].Name; bone.OffsetMatrix = Matrix4ToMatrix4x4(WorldTransforms[jobjToIndex[jobj]].Inverted()); m.Bones.Add(bone); jobjToBone.Add(jobj, bone); } } /*foreach (var en in envelopes) * { * foreach (var jobj in en.JOBJs) * { * if (!jobjToBone.ContainsKey(jobj)) * { * var bone = new Bone(); * bone.Name = JobjNodes[jobjToIndex[jobj]].Name; * bone.OffsetMatrix = Matrix4ToMatrix4x4(WorldTransforms[jobjToIndex[jobj]].Inverted()); * m.Bones.Add(bone); * jobjToBone.Add(jobj, bone); * } * } * }*/ if (singleBind != null && !jobjToBone.ContainsKey(singleBind)) { var bone = new Bone(); bone.Name = JobjNodes[jobjToIndex[singleBind]].Name; bone.OffsetMatrix = Matrix4ToMatrix4x4(WorldTransforms[jobjToIndex[singleBind]].Inverted()); m.Bones.Add(bone); jobjToBone.Add(singleBind, bone); } int offset = 0; var vIndex = -1; foreach (var prim in dl.Primitives) { var verts = dl.Vertices.GetRange(offset, prim.Count); offset += prim.Count; switch (prim.PrimitiveType) { case GXPrimitiveType.Quads: verts = TriangleConverter.QuadToList(verts); break; case GXPrimitiveType.TriangleStrip: verts = TriangleConverter.StripToList(verts); break; case GXPrimitiveType.Triangles: break; default: Console.WriteLine(prim.PrimitiveType); break; } for (int i = m.VertexCount; i < m.VertexCount + verts.Count; i += 3) { var f = new Face(); f.Indices.Add(i); f.Indices.Add(i + 1); f.Indices.Add(i + 2); m.Faces.Add(f); } foreach (var v in verts) { vIndex++; if (singleBind != null) { var vertexWeight = new VertexWeight(); vertexWeight.VertexID = vIndex; vertexWeight.Weight = 1; jobjToBone[singleBind].VertexWeights.Add(vertexWeight); } Matrix4 weight = Matrix4.Identity; foreach (var a in pobj.Attributes) { switch (a.AttributeName) { case GXAttribName.GX_VA_PNMTXIDX: var en = envelopes[v.PNMTXIDX / 3]; for (int w = 0; w < en.EnvelopeCount; w++) { var vertexWeight = new VertexWeight(); vertexWeight.VertexID = vIndex; vertexWeight.Weight = en.Weights[w]; jobjToBone[en.JOBJs[w]].VertexWeights.Add(vertexWeight); } if (en.EnvelopeCount == 1 && jobjToIndex[parent] == 0) { weight = WorldTransforms[jobjToIndex[en.JOBJs[0]]]; } break; case GXAttribName.GX_VA_POS: var vert = Vector3.TransformPosition(GXTranslator.toVector3(v.POS), parentTransform); vert = Vector3.TransformPosition(vert, weight); vert = Vector3.TransformPosition(vert, singleBindTransform); m.Vertices.Add(new Vector3D(vert.X, vert.Y, vert.Z)); break; case GXAttribName.GX_VA_NRM: var nrm = Vector3.TransformNormal(GXTranslator.toVector3(v.NRM), parentTransform); nrm = Vector3.TransformNormal(nrm, weight); nrm = Vector3.TransformNormal(nrm, singleBindTransform); m.Normals.Add(new Vector3D(nrm.X, nrm.Y, nrm.Z)); break; case GXAttribName.GX_VA_CLR0: m.VertexColorChannels[0].Add(new Color4D(v.CLR0.R, v.CLR0.G, v.CLR0.B, v.CLR0.A)); break; case GXAttribName.GX_VA_CLR1: m.VertexColorChannels[1].Add(new Color4D(v.CLR1.R, v.CLR1.G, v.CLR1.B, v.CLR1.A)); break; case GXAttribName.GX_VA_TEX0: m.TextureCoordinateChannels[0].Add(new Vector3D(v.TEX0.X, v.TEX0.Y, 1)); break; case GXAttribName.GX_VA_TEX1: m.TextureCoordinateChannels[1].Add(new Vector3D(v.TEX1.X, v.TEX1.Y, 1)); break; case GXAttribName.GX_VA_TEX2: m.TextureCoordinateChannels[2].Add(new Vector3D(v.TEX2.X, v.TEX2.Y, 1)); break; case GXAttribName.GX_VA_TEX3: m.TextureCoordinateChannels[3].Add(new Vector3D(v.TEX3.X, v.TEX3.Y, 1)); break; case GXAttribName.GX_VA_TEX4: m.TextureCoordinateChannels[4].Add(new Vector3D(v.TEX4.X, v.TEX4.Y, 1)); break; case GXAttribName.GX_VA_TEX5: m.TextureCoordinateChannels[5].Add(new Vector3D(v.TEX5.X, v.TEX5.Y, 1)); break; case GXAttribName.GX_VA_TEX6: m.TextureCoordinateChannels[6].Add(new Vector3D(v.TEX6.X, v.TEX6.Y, 1)); break; case GXAttribName.GX_VA_TEX7: m.TextureCoordinateChannels[7].Add(new Vector3D(v.TEX7.X, v.TEX7.Y, 1)); break; } } } } return(m); }
void b_DoWork(object sender, DoWorkEventArgs e) { if (e == null) return; ObjectOptimizerForm form = e.Argument as ObjectOptimizerForm; form._newPointCount = 0; foreach (ObjectOptimization a in form._results) { if (a == null || a._object == null || a._object._manager == null || a._object._manager._triangles == null || a._facepoints == null) return; TriangleConverter triConverter = new TriangleConverter(chkUseStrips.Checked, (uint)numCacheSize.Value, (uint)numMinStripLen.Value, false, chkPushCacheHits.Checked); Facepoint[] points = new Facepoint[a._object._manager._triangles._elementCount]; uint[] indices = a._object._manager._triangles._indices; bool ccw = Collada._importOptions._forceCCW; //Indices are written in reverse for each triangle, //so they need to be set to a triangle in reverse if not CCW for (int t = 0; t < a._object._manager._triangles._elementCount; t++) points[ccw ? t : (t - (t % 3)) + (2 - (t % 3))] = a._facepoints[indices[t]]; int pc, fc; List<PrimitiveGroup> p = triConverter.GroupPrimitives(points, out pc, out fc); if (chkAllowIncrease.Checked || pc < a._pointCount) { a._pointCount = pc; a._faceCount = fc; a._groups = p; } form._newPointCount += a._pointCount; } e.Result = form; }
public void Open(FileItem File) { var skelPath = File.FilePath.Replace(".mdg", ".anm"); var skelAngPath = File.FilePath.Replace(".mdg", ".ang"); var modelPath = File.FilePath.Replace(".mdg", ".mdl"); var texPath = File.FilePath.Replace(".mdg", ".tex"); if (!System.IO.File.Exists(skelPath)) { System.Windows.Forms.MessageBox.Show("Missing Skeleton File " + Path.GetFileName(skelPath)); return; } if (!System.IO.File.Exists(skelAngPath)) { System.Windows.Forms.MessageBox.Show("Missing Skeleton File " + Path.GetFileName(skelAngPath)); return; } if (!System.IO.File.Exists(modelPath)) { System.Windows.Forms.MessageBox.Show("Missing Model File " + Path.GetFileName(modelPath)); return; } Model = new GenericModel(); Model.Skeleton = new GenericSkeleton(); if (System.IO.File.Exists(texPath)) { using (DataReader r = new DataReader(new FileStream(texPath, FileMode.Open))) { r.BigEndian = true; var unk = r.ReadInt32(); var width = r.ReadInt32(); var height = r.ReadInt32(); var dataLength = r.ReadInt32(); var padding = r.ReadInt32(); var format = r.ReadByte(); var data = r.GetSection(0x20, (int)(r.BaseStream.Length - 0x20)); var bmp = HSDLib.Helpers.TPL.ConvertFromTextureMelee(data, width, height, (int)TPL_TextureFormat.CMP, null, 0, 0); GenericTexture t = new GenericTexture(); t.FromBitmap(bmp); bmp.Dispose(); Model.TextureBank.Add("texture", t); Model.MaterialBank.Add("material", new GenericMaterial() { TextureDiffuse = "texture" }); } } using (DataReader r = new DataReader(new FileStream(skelPath, FileMode.Open))) { r.BigEndian = false; r.ReadInt32(); // magic r.ReadInt32(); // header var boneCount = r.ReadInt32(); var boneOffset = r.ReadUInt32(); using (DataReader angr = new DataReader(new FileStream(skelAngPath, FileMode.Open))) { angr.BigEndian = false; for (int i = 0; i < boneCount; i++) { r.Seek(boneOffset + (uint)(i * 0x20)); var bone = new GenericBone(); bone.Position = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); r.ReadSingle(); //r.Skip(0x10); // inverted world position bone.Name = r.ReadString(r.ReadUInt32(), -1); bone.ParentIndex = r.ReadInt32(); var flags = r.ReadInt32(); var angOffset = r.ReadUInt32(); /*angr.Seek(angOffset); * angr.Skip(4); * var posOff = angr.ReadUInt32(); * var rotOff = angr.ReadUInt32(); * var scaOff = angr.ReadUInt32(); * angr.Seek(posOff); * bone.Position = new OpenTK.Vector3(angr.ReadSingle(), angr.ReadSingle(), angr.ReadSingle()); * angr.Seek(rotOff); * bone.Rotation = new OpenTK.Vector3(angr.ReadSingle(), angr.ReadSingle(), angr.ReadSingle()); * angr.Seek(scaOff); * bone.Scale = new OpenTK.Vector3(angr.ReadSingle(), angr.ReadSingle(), angr.ReadSingle());*/ Model.Skeleton.Bones.Add(bone); } } } Model.Skeleton.TransformWorldToRelative(); using (DataReader r = new DataReader(new FileStream(modelPath, FileMode.Open))) { r.BigEndian = true; r.ReadInt32(); // magic int boneCount = r.ReadInt16(); var meshCount = r.ReadInt16(); boneCount = r.ReadInt32(); var meshOffset = r.ReadUInt32(); r.ReadUInt32(); var boneOffset = r.ReadUInt32(); for (int i = 0; i < meshCount; i++) { r.Seek(meshOffset + (uint)(i * 80)); r.Skip(0x30); // bounding stuff var mesh = new GenericMesh(); mesh.MaterialName = "material"; mesh.Name = r.ReadString(r.ReadUInt32(), -1); r.Skip(4 * 4); var datInfoOffset = r.ReadUInt32(); Model.Meshes.Add(mesh); r.Seek(datInfoOffset); var flag = r.ReadInt32(); var bufferOffset = r.ReadUInt32(); var someCount = r.ReadInt32(); var primCount = r.ReadInt32(); using (DataReader buffer = new DataReader(new FileStream(File.FilePath, FileMode.Open))) { buffer.BigEndian = true; if (new string(buffer.ReadChars(4)) == "MDG5") { buffer.Seek(0x10); } else { buffer.Seek(0); } buffer.Skip(bufferOffset); for (int p = 0; p < primCount; p++) { var primitiveType = buffer.ReadInt16(); var pcount = buffer.ReadInt16(); if (primitiveType != 0x98) { throw new NotSupportedException("Unknown prim type " + primitiveType.ToString("X")); } var strip = new List <GenericVertex>(); for (int v = 0; v < pcount; v++) { var vert = new GenericVertex(); vert.Pos = new OpenTK.Vector3(buffer.ReadSingle(), buffer.ReadSingle(), buffer.ReadSingle()); vert.Nrm = new OpenTK.Vector3(buffer.ReadSByte(), buffer.ReadSByte(), buffer.ReadSByte()); vert.Nrm.Normalize(); // Color? int col = buffer.ReadInt16(); var R = (col >> 12) & 0xF; var G = (col >> 8) & 0xF; var B = (col >> 4) & 0xF; var A = (col) & 0xF; vert.Clr = new OpenTK.Vector4( (R | R << 4) / (float)0xFF, (G | G << 4) / (float)0xFF, (B | B << 4) / (float)0xFF, (A | A << 4) / (float)0xFF); vert.UV0 = new OpenTK.Vector2(buffer.ReadInt16() / (float)0xFFF, buffer.ReadInt16() / (float)0xFFF); var weight1 = buffer.ReadByte() / (float)0xFF; float weight2 = 0; if (weight1 != 1) { weight2 = 1 - weight1; } var bone1 = buffer.ReadByte(); var bone2 = buffer.ReadByte(); vert.Bones = new OpenTK.Vector4(bone1, bone2, 0, 0); vert.Weights = new OpenTK.Vector4(weight1, weight2, 0, 0); strip.Add(vert); } TriangleConverter.StripToList(strip, out strip); mesh.Vertices.AddRange(strip); } } mesh.Optimize(); } } }
/// <summary> /// Constructor of a chain-ladder model given a run-off triangle. /// </summary> /// <param name="triangle">Cumulative triangle to be developed.</param> public ChainLadder(ITriangle triangle) : base(TriangleConverter <CumulativeTriangle> .Convert(triangle)) { _factors = new Lazy <IReadOnlyList <decimal> >(CalculateFactors); }
public static void RebuildPOBJs(HSD_JOBJ rootJOBJ) { var compressor = new POBJ_Generator(); foreach (var jobj in rootJOBJ.BreathFirstList) { if (jobj.Dobj != null) { foreach (var dobj in jobj.Dobj.List) { if (dobj.Pobj != null) { List <GX_Vertex> triList = new List <GX_Vertex>(); List <HSD_JOBJ[]> bones = new List <HSD_JOBJ[]>(); List <float[]> weights = new List <float[]>(); foreach (var pobj in dobj.Pobj.List) { var dl = pobj.ToDisplayList(); int off = 0; foreach (var pri in dl.Primitives) { var strip = dl.Vertices.GetRange(off, pri.Count); if (pri.PrimitiveType == GXPrimitiveType.TriangleStrip) { TriangleConverter.StripToList(strip, out strip); } if (pri.PrimitiveType == GXPrimitiveType.Quads) { TriangleConverter.QuadToList(strip, out strip); } off += pri.Count; //if(pobj.Flags.HasFlag(POBJ_FLAG.ENVELOPE)) { triList.AddRange(strip); foreach (var v in strip) { if (dl.Envelopes.Count > 0) { var en = dl.Envelopes[v.PNMTXIDX / 3]; HSD_JOBJ[] b = en.JOBJs; float[] w = en.Weights; bones.Add(b); weights.Add(w); } else { bones.Add(new HSD_JOBJ[0]); weights.Add(new float[0]); } } } } } dobj.Pobj = compressor.CreatePOBJsFromTriangleList(triList, dobj.Pobj.Attributes.Select(e => e.AttributeName).ToArray(), bones, weights); } } } } compressor.SaveChanges(); }
public static HSD_DOBJ GenerateOutlineMesh(HSD_DOBJ DOBJ) { var settings = new OutlineSettings(); using (PropertyDialog d = new PropertyDialog("Outline Settings", settings)) { if (d.ShowDialog() != DialogResult.OK) { return(null); } } var pobjGen = new POBJ_Generator(); pobjGen.UseTriangleStrips = settings.UseStrips; var newDOBJ = new HSD_DOBJ(); newDOBJ.Mobj = new HSD_MOBJ() { Material = new HSD_Material() { AmbientColor = Color.White, SpecularColor = Color.Black, DiffuseColor = settings.Color, DIF_A = 255, SPC_A = 255, AMB_A = 255, Shininess = 50, Alpha = 1 }, RenderFlags = RENDER_MODE.CONSTANT }; foreach (var pobj in DOBJ.Pobj.List) { var dl = pobj.ToDisplayList(); var vertices = dl.Vertices; GXAttribName[] attrs = new GXAttribName[] { GXAttribName.GX_VA_POS, GXAttribName.GX_VA_NULL }; if (pobj.HasAttribute(GXAttribName.GX_VA_PNMTXIDX)) { attrs = new GXAttribName[] { GXAttribName.GX_VA_PNMTXIDX, GXAttribName.GX_VA_POS, GXAttribName.GX_VA_NULL }; } List <GX_Vertex> newVerties = new List <GX_Vertex>(); var offset = 0; foreach (var prim in dl.Primitives) { var verts = vertices.GetRange(offset, prim.Count); offset += prim.Count; switch (prim.PrimitiveType) { case GXPrimitiveType.Quads: verts = TriangleConverter.QuadToList(verts); break; case GXPrimitiveType.TriangleStrip: verts = TriangleConverter.StripToList(verts); break; case GXPrimitiveType.Triangles: break; default: Console.WriteLine(prim.PrimitiveType); break; } newVerties.AddRange(verts); } // extrude for (int i = 0; i < newVerties.Count; i++) { var v = newVerties[i]; v.POS.X += v.NRM.X * settings.Size; v.POS.Y += v.NRM.Y * settings.Size; v.POS.Z += v.NRM.Z * settings.Size; //v.CLR0.R = settings.Color.R / 255f; //v.CLR0.G = settings.Color.G / 255f; //v.CLR0.B = settings.Color.B / 255f; //v.CLR0.A = settings.Color.A / 255f; newVerties[i] = v; } // invert faces for (int i = 0; i < newVerties.Count; i += 3) { var temp = newVerties[i]; newVerties[i] = newVerties[i + 2]; newVerties[i + 2] = temp; } var newpobj = pobjGen.CreatePOBJsFromTriangleList(newVerties, attrs, dl.Envelopes); foreach (var p in newpobj.List) { p.Flags |= POBJ_FLAG.CULLBACK | POBJ_FLAG.UNKNOWN1; } if (newDOBJ.Pobj == null) { newDOBJ.Pobj = newpobj; } else { newDOBJ.Pobj.Add(newpobj); } } pobjGen.SaveChanges(); return(newDOBJ); }
/// <summary> /// Test for rebuilding pobjs from scratch /// </summary> /// <param name="path"></param> public static void RebuildPOBJs(string path) { HSDRawFile file = new HSDRawFile(path); var rootJOBJ = (HSD_JOBJ)(file.Roots[0].Data); var compressor = new POBJ_Generator(); foreach (var jobj in rootJOBJ.BreathFirstSearch) { if (jobj.Dobj != null) { foreach (var dobj in jobj.Dobj.List) { if (dobj.Pobj != null) { GXAttribName[] attributes = null; if (attributes == null) { attributes = new GXAttribName[dobj.Pobj.Attributes.Length - 1]; for (int i = 0; i < attributes.Length; i++) { attributes[i] = dobj.Pobj.Attributes[i].AttributeName; } } List <GX_Vertex> triList = new List <GX_Vertex>(); List <HSD_JOBJ[]> bones = new List <HSD_JOBJ[]>(); List <float[]> weights = new List <float[]>(); foreach (var pobj in dobj.Pobj.List) { var dl = pobj.ToDisplayList(); int off = 0; foreach (var pri in dl.Primitives) { var strip = dl.Vertices.GetRange(off, pri.Count); if (pri.PrimitiveType == GXPrimitiveType.TriangleStrip) { TriangleConverter.StripToList(strip, out strip); } if (pri.PrimitiveType == GXPrimitiveType.Quads) { TriangleConverter.QuadToList(strip, out strip); } off += pri.Count; //if(pobj.Flags.HasFlag(POBJ_FLAG.ENVELOPE)) { triList.AddRange(strip); foreach (var v in strip) { if (dl.Envelopes.Count > 0) { var en = dl.Envelopes[v.PNMTXIDX / 3]; HSD_JOBJ[] b = en.JOBJs; float[] w = en.Weights; bones.Add(b); weights.Add(w); } else { bones.Add(new HSD_JOBJ[0]); weights.Add(new float[0]); } } } } } dobj.Pobj = compressor.CreatePOBJsFromTriangleList(triList, attributes, bones, weights); /*List<GX_Vertex> triList = new List<GX_Vertex>(); * foreach (var pobj in dobj.Pobj.List) * { * var dl = pobj.DisplayList; * var newPrimGroup = new List<GX_PrimitiveGroup>(); * int offset = 0; * foreach (var g in dl.Primitives) * { * GX_Vertex[] strip = new GX_Vertex[g.Count]; * for (int i = 0; i < g.Count; i++) * strip[i] = dl.Vertices[offset + i]; * newPrimGroup.Add(compressor.Compress(g.PrimitiveType, strip, pobj.Attributes)); * offset += g.Count; * } * dl.Primitives = newPrimGroup; * pobj.DisplayList = dl; * }*/ } } } } compressor.SaveChanges(); file.Save(path + "_rebuilt.dat"); }
/// <summary> /// /// </summary> /// <param name="rootJOBJ"></param> private static Vector3 RegenerateIcon(HSD_JOBJ rootJOBJ) { Vector3 Min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); Vector3 Max = new Vector3(float.MinValue, float.MinValue, float.MinValue); foreach (var jobj in rootJOBJ.BreathFirstList) { if (jobj.Dobj != null) { foreach (var dobj in jobj.Dobj.List) { if (dobj.Pobj != null) { foreach (var pobj in dobj.Pobj.List) { foreach (var v in pobj.ToDisplayList().Vertices) { Min.X = Math.Min(Min.X, v.POS.X); Min.Y = Math.Min(Min.Y, v.POS.Y); Min.Z = Math.Min(Min.Z, v.POS.Z); Max.X = Math.Max(Max.X, v.POS.X); Max.Y = Math.Max(Max.Y, v.POS.Y); Max.Z = Math.Max(Max.Z, v.POS.Z); } } } } } } var center = (Min + Max) / 2; var compressor = new POBJ_Generator(); foreach (var jobj in rootJOBJ.BreathFirstList) { if (jobj.Dobj != null) { foreach (var dobj in jobj.Dobj.List) { if (dobj.Pobj != null) { List <GX_Vertex> triList = new List <GX_Vertex>(); foreach (var pobj in dobj.Pobj.List) { var dl = pobj.ToDisplayList(); int off = 0; foreach (var pri in dl.Primitives) { var strip = dl.Vertices.GetRange(off, pri.Count); if (pri.PrimitiveType == GXPrimitiveType.TriangleStrip) { TriangleConverter.StripToList(strip, out strip); } if (pri.PrimitiveType == GXPrimitiveType.Quads) { TriangleConverter.QuadToList(strip, out strip); } off += pri.Count; for (int i = 0; i < strip.Count; i++) { var v = strip[i]; v.POS.X -= center.X; v.POS.Y -= center.Y; v.POS.Z -= center.Z; strip[i] = v; } triList.AddRange(strip); } } dobj.Pobj = compressor.CreatePOBJsFromTriangleList(triList, dobj.Pobj.Attributes.Select(e => e.AttributeName).ToArray(), null, null); } } } } compressor.SaveChanges(); center.X *= rootJOBJ.SX; center.Y *= rootJOBJ.SY; center.Z *= rootJOBJ.SZ; return(center); }
/// <summary> /// Constructor of a Bornhuetter-Ferguson model given a run-off triangle. /// </summary> /// <param name="triangle">Triangle to be developed.</param> /// <param name="factors">Factors the triangle is to be developed with.</param> /// <param name="alpha">Ex-ante expected final claim levels.</param> /// <exception cref="DimensionMismatchException">Thrown when the count of factors does not match the number of periods observed.</exception> /// <exception cref="DimensionMismatchException">Thrown when the number of expected final claim levels does not match the number of periods observed.</exception> public BornhuetterFerguson(ITriangle triangle, IEnumerable <decimal> factors, IEnumerable <decimal> alpha) : base(TriangleConverter <CumulativeTriangle> .Convert(triangle)) { int factorsCount = factors.Count(); if (factorsCount != Triangle.Periods) { throw new DimensionMismatchException(Triangle.Periods, factorsCount); } int alphaCount = alpha.Count(); if (alphaCount != Triangle.Periods) { throw new DimensionMismatchException(Triangle.Periods, alphaCount); } _factors = new Lazy <IReadOnlyList <decimal> >(() => factors.ToList().AsReadOnly()); _alpha = alpha.ToArray(); }