├── .gitignore ├── KMPExpander.sln ├── KMPExpander ├── App.config ├── Class │ ├── CDAB.cs │ ├── CMDL.cs │ ├── Description.cs │ ├── EndianBinaryReaderExtensions.cs │ ├── Extensions.cs │ ├── KMP.cs │ ├── KMPs │ │ ├── AREA.cs │ │ ├── CAME.cs │ │ ├── CKPH.cs │ │ ├── CKPT.cs │ │ ├── CNPT.cs │ │ ├── CORS.cs │ │ ├── ENPH.cs │ │ ├── ENPT.cs │ │ ├── GLPH.cs │ │ ├── GLPT.cs │ │ ├── GOBJ.cs │ │ ├── ITPH.cs │ │ ├── ITPT.cs │ │ ├── JGPT.cs │ │ ├── KTPT.cs │ │ ├── MSPT.cs │ │ ├── POTI.cs │ │ └── STGI.cs │ ├── OBJWrapper.cs │ ├── ObjInfo.cs │ ├── Picking.cs │ ├── SimpleKMP.cs │ ├── SimpleKMPs │ │ ├── Area.cs │ │ ├── CamePlayer.cs │ │ ├── Camera.cs │ │ ├── CheckPoints.cs │ │ ├── EnemyRoutes.cs │ │ ├── Generic.cs │ │ ├── GliderRoutes.cs │ │ ├── ItemRoutes.cs │ │ ├── Objects.cs │ │ ├── RespawnPoints.cs │ │ ├── Routes.cs │ │ ├── StageInformation.cs │ │ └── StartPositions.cs │ ├── TreeViewFix.cs │ ├── UIMapPos.cs │ ├── Vector.cs │ ├── VisualSettings.cs │ └── Wavefront │ │ ├── MTL.cs │ │ └── OBJ.cs ├── ErrorCheck.Designer.cs ├── ErrorCheck.cs ├── ErrorCheck.resx ├── Form1.Designer.cs ├── Form1.cs ├── Form1.resx ├── FormOBJ.Designer.cs ├── FormOBJ.cs ├── FormOBJ.resx ├── FormObjectList.Designer.cs ├── FormObjectList.cs ├── FormObjectList.resx ├── FormSettings.Designer.cs ├── FormSettings.cs ├── FormSettings.resx ├── FormTransform.Designer.cs ├── FormTransform.cs ├── FormTransform.resx ├── Icons │ ├── KMP_Expander_App_Icon.ico │ ├── KMP_File_Icon.ico │ ├── area │ │ ├── 1.png │ │ └── 1_original.png │ ├── came │ │ ├── 1.png │ │ └── 1_original.png │ ├── checkpoint │ │ ├── 1.png │ │ └── 1_original.png │ ├── div │ │ ├── child.png │ │ └── parent.png │ ├── enm │ │ ├── 1.png │ │ ├── 1_original.png │ │ ├── 2.png │ │ ├── 2_original.png │ │ ├── 3.png │ │ ├── 3_original.png │ │ ├── 4.png │ │ ├── 4_original.png │ │ ├── 5.png │ │ └── 5_original.png │ ├── error.png │ ├── glider │ │ ├── 1.png │ │ └── 1_original.png │ ├── info.png │ ├── item │ │ ├── 1.png │ │ ├── 1_original.png │ │ ├── 2.png │ │ ├── 2_original.png │ │ ├── 3.png │ │ ├── 3_original.png │ │ ├── 4.png │ │ ├── 4_original.png │ │ ├── 5.png │ │ ├── 5_original.png │ │ ├── 6.png │ │ └── 6_original.png │ ├── other │ │ ├── empty.png │ │ ├── gcheckpoint.png │ │ ├── genm.png │ │ ├── gglider.png │ │ ├── gitem.png │ │ └── groutes.png │ ├── respawn │ │ ├── 1.png │ │ └── 1_original.png │ ├── routes │ │ ├── 1.png │ │ └── 1_original.png │ ├── startpos │ │ ├── 1.png │ │ ├── 1_original.png │ │ ├── 2.png │ │ └── 2_original.png │ ├── stgi │ │ └── 1.png │ └── warning.png ├── KMPExpander.csproj ├── KMP_Expander_App_Icon.ico ├── LibEndianBinaryIO.dll ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ ├── Settings.settings │ └── app.manifest ├── Resources │ ├── div.bmp │ └── error.bmp ├── TestFormOBJ.Designer.cs ├── TestFormOBJ.cs └── TestFormOBJ.resx ├── README.md ├── geometry3Sharp ├── .gitignore ├── LICENSE ├── Properties │ └── AssemblyInfo.cs ├── README.md ├── approximation │ ├── BiArcFit2.cs │ ├── GaussPointsFit3.cs │ ├── OrthogonalPlaneFit3.cs │ └── QuadraticFit2.cs ├── appveyor.yml ├── color │ ├── ColorHSV.cs │ ├── ColorMap.cs │ ├── ColorMixer.cs │ ├── Colorb.cs │ └── Colorf.cs ├── comp_geom │ ├── Arrangement2d.cs │ ├── ConvexHull2.cs │ ├── GraphCells2d.cs │ ├── GraphSplitter2d.cs │ └── SphericalFibonacciPointSet.cs ├── containment │ ├── ContBox3.cs │ ├── ContMinBox2.cs │ ├── ContMinCircle2.cs │ └── TilingUtil.cs ├── core │ ├── BufferUtil.cs │ ├── CommandArgumentSet.cs │ ├── DVector.cs │ ├── DVectorArray.cs │ ├── DeepCopy.cs │ ├── DijkstraGraphDistance.cs │ ├── DynamicPriorityQueue.cs │ ├── FileSystemUtils.cs │ ├── HBitArray.cs │ ├── HashUtil.cs │ ├── IndexPriorityQueue.cs │ ├── Indexing.cs │ ├── MemoryPool.cs │ ├── ProfileUtil.cs │ ├── ProgressCancel.cs │ ├── RefCountVector.cs │ ├── SafeCollections.cs │ ├── SmallListSet.cs │ ├── Snapping.cs │ ├── SparseList.cs │ ├── TagSet.cs │ ├── Units.cs │ ├── Util.cs │ ├── VectorArray.cs │ ├── g3Interfaces.cs │ ├── g3Iterators.cs │ └── gParallel.cs ├── curve │ ├── Arc2.cs │ ├── ArcLengthParam.cs │ ├── BSplineBasis.cs │ ├── BaseCurve2.cs │ ├── Circle2.cs │ ├── CurveGenerators.cs │ ├── CurveResampler.cs │ ├── CurveSampler2.cs │ ├── CurveUtils.cs │ ├── CurveUtils2.cs │ ├── DCurve3.cs │ ├── DGraph.cs │ ├── DGraph2.cs │ ├── DGraph2Resampler.cs │ ├── DGraph2Util.cs │ ├── DGraph3.cs │ ├── DGraph3Util.cs │ ├── Ellipse2.cs │ ├── EllipseArc2.cs │ ├── GeneralPolygon2d.cs │ ├── Hexagon2.cs │ ├── ICurve.cs │ ├── NURBSCurve2.cs │ ├── ParametricCurveSequence2.cs │ ├── PlanarComplex.cs │ ├── PlanarSolid2d.cs │ ├── PolyLine2d.cs │ ├── PolyLine2f.cs │ ├── PolyLine3d.cs │ ├── PolySimplification2.cs │ ├── Polygon2d.cs │ ├── PolygonFont2d.cs │ ├── SculptCurveDeformers.cs │ └── SimpleCurveDeformers.cs ├── distance │ ├── DistLine2Line2.cs │ ├── DistLine2Segment2.cs │ ├── DistLine3Ray3.cs │ ├── DistLine3Segment3.cs │ ├── DistLine3Triangle3.cs │ ├── DistPoint2Box2.cs │ ├── DistPoint2Circle2.cs │ ├── DistPoint3Circle3.cs │ ├── DistPoint3Cylinder3.cs │ ├── DistPoint3Triangle3.cs │ ├── DistRay3Ray3.cs │ ├── DistRay3Segment3.cs │ ├── DistSegment2Segment2.cs │ ├── DistSegment3Triangle3.cs │ ├── DistTriangle3Triangle3.cs │ └── Distance.cs ├── geometry3Sharp.asmdef ├── geometry3Sharp.csproj ├── geometry3Sharp_netstandard.csproj ├── implicit │ ├── GridImplicits3d.cs │ ├── Implicit2d.cs │ ├── Implicit3d.cs │ ├── ImplicitFieldSampler3d.cs │ ├── ImplicitOperators.cs │ └── MarchingQuads.cs ├── intersection │ ├── Intersector1.cs │ ├── IntrLine2Line2.cs │ ├── IntrLine2Segment2.cs │ ├── IntrLine2Triangle2.cs │ ├── IntrLine3AxisAlignedBox3.cs │ ├── IntrLine3Box3.cs │ ├── IntrRay3AxisAlignedBox3.cs │ ├── IntrRay3Box3.cs │ ├── IntrRay3Triangle3.cs │ ├── IntrSegment2Segment2.cs │ ├── IntrSegment2Triangle2.cs │ ├── IntrSegment3Box3.cs │ ├── IntrTriangle2Triangle2.cs │ └── IntrTriangle3Triangle3.cs ├── io │ ├── BinaryG3ReaderWriter.cs │ ├── MaterialTypes.cs │ ├── MeshIO.cs │ ├── MeshIOUtil.cs │ ├── OBJReader.cs │ ├── OBJWriter.cs │ ├── OFFReader.cs │ ├── OFFWriter.cs │ ├── STLReader.cs │ ├── STLWriter.cs │ ├── SVGWriter.cs │ ├── StandardMeshReader.cs │ ├── StandardMeshWriter.cs │ └── gSerialization.cs ├── math │ ├── AxisAlignedBox2d.cs │ ├── AxisAlignedBox2f.cs │ ├── AxisAlignedBox2i.cs │ ├── AxisAlignedBox3d.cs │ ├── AxisAlignedBox3f.cs │ ├── AxisAlignedBox3i.cs │ ├── BoundsUtil.cs │ ├── Box2.cs │ ├── Box3.cs │ ├── Frame3f.cs │ ├── IndexTypes.cs │ ├── IndexUtil.cs │ ├── Integrate1d.cs │ ├── Interval1d.cs │ ├── Interval1i.cs │ ├── Line2.cs │ ├── Line3.cs │ ├── MathUtil.cs │ ├── Matrix2d.cs │ ├── Matrix2f.cs │ ├── Matrix3d.cs │ ├── Matrix3f.cs │ ├── MatrixUtil.cs │ ├── Plane3.cs │ ├── PrimalQuery2d.cs │ ├── Quaterniond.cs │ ├── Quaternionf.cs │ ├── Query2.cs │ ├── Query2Integer.cs │ ├── QueryTuple2d.cs │ ├── Ray3.cs │ ├── ScalarMap.cs │ ├── Segment2.cs │ ├── Segment3.cs │ ├── TransformSequence.cs │ ├── TransformSequence2.cs │ ├── Triangle2.cs │ ├── Triangle3.cs │ ├── Vector2d.cs │ ├── Vector2f.cs │ ├── Vector2i.cs │ ├── Vector3d.cs │ ├── Vector3f.cs │ ├── Vector3i.cs │ ├── Vector4d.cs │ ├── Vector4f.cs │ └── VectorTuple.cs ├── mesh │ ├── DMesh3.cs │ ├── DMesh3Builder.cs │ ├── DMesh3Changes.cs │ ├── DMesh3_debug.cs │ ├── DMesh3_edge_operators.cs │ ├── DSubmesh3.cs │ ├── DSubmesh3Set.cs │ ├── EdgeLoop.cs │ ├── EdgeLoopRemesher.cs │ ├── EdgeSpan.cs │ ├── FaceGroupOptimizer.cs │ ├── FaceGroupUtil.cs │ ├── IMesh.cs │ ├── MeshConstraintUtil.cs │ ├── MeshConstraints.cs │ ├── MeshDecomposition.cs │ ├── MeshEditor.cs │ ├── MeshIndexUtil.cs │ ├── MeshIterators.cs │ ├── MeshMeasurements.cs │ ├── MeshNormals.cs │ ├── MeshPointSets.cs │ ├── MeshRefinerBase.cs │ ├── MeshTransforms.cs │ ├── MeshUVSet.cs │ ├── MeshUtil.cs │ ├── MeshWeights.cs │ ├── NTMesh3.cs │ ├── Reducer.cs │ ├── RegionRemesher.cs │ ├── Remesher.cs │ ├── SimpleMesh.cs │ └── SimpleQuadMesh.cs ├── mesh_generators │ ├── ArrowGenerators.cs │ ├── BoxGenerators.cs │ ├── CylinderGenerators.cs │ ├── DiscGenerators.cs │ ├── GenCylGenerators.cs │ ├── MarchingCubes.cs │ ├── MeshGenerators.cs │ ├── PlaneGenerators.cs │ ├── PointsMeshGenerators.cs │ ├── RevolveGenerator.cs │ ├── SphereGenerators.cs │ ├── TriangulatedPolygonGenerator.cs │ └── VoxelSurfaceGenerator.cs ├── mesh_ops │ ├── LaplacianMeshDeformer.cs │ ├── LaplacianMeshSmoother.cs │ ├── MeshExtrudeFaces.cs │ ├── MeshExtrudeLoop.cs │ ├── MeshExtrudeMesh.cs │ ├── MeshICP.cs │ ├── MeshInsertPolygon.cs │ ├── MeshInsertUVPolyCurve.cs │ ├── MeshIsoCurves.cs │ ├── MeshIterativeSmooth.cs │ ├── MeshLocalParam.cs │ ├── MeshLoopClosure.cs │ ├── MeshLoopSmooth.cs │ ├── MeshOps.cs │ ├── MeshPlaneCut.cs │ ├── PlanarHoleFiller.cs │ ├── RegionOperator.cs │ └── SimpleHoleFiller.cs ├── mesh_selection │ ├── MeshBoundaryLoops.cs │ ├── MeshConnectedComponents.cs │ ├── MeshEdgeSelection.cs │ ├── MeshFaceSelection.cs │ ├── MeshFacesFromLoop.cs │ ├── MeshRegionBoundaryLoops.cs │ └── MeshVertexSelection.cs ├── queries │ ├── IntersectionUtil.cs │ ├── MeshQueries.cs │ ├── MeshValidation.cs │ └── RayIntersection.cs ├── shapes3 │ ├── Circle3.cs │ └── Cylinder3.cs ├── solvers │ ├── CholeskyDecomposition.cs │ ├── DenseMatrix.cs │ ├── DenseVector.cs │ ├── FastQuaternionSVD.cs │ ├── IMatrix.cs │ ├── PackedSparseMatrix.cs │ ├── SingularValueDecomposition.cs │ ├── SparseMatrix.cs │ ├── SparseSymmetricCG.cs │ └── SymmetricEigenSolver.cs └── spatial │ ├── BasicIntersectionTargets.cs │ ├── BasicProjectionTargets.cs │ ├── BiGrid3.cs │ ├── Bitmap2.cs │ ├── Bitmap3.cs │ ├── DCurveBoxTree.cs │ ├── DCurveProjection.cs │ ├── DMeshAABBTree.cs │ ├── DSparseGrid3.cs │ ├── DenseGrid2.cs │ ├── DenseGrid3.cs │ ├── GridIndexing.cs │ ├── GridIndexing2.cs │ ├── MeshSignedDistanceGrid.cs │ ├── NormalHistogram.cs │ ├── PointAABBTree3.cs │ ├── PointHashGrid2d.cs │ ├── PointHashGrid3d.cs │ ├── Polygon2dBoxTree.cs │ ├── SegmentHashGrid.cs │ ├── SegmentSet2d.cs │ ├── SpatialFunctions.cs │ ├── SpatialInterfaces.cs │ └── TriangleBinsGrid2d.cs └── help ├── KMPExpander.chm ├── KMPExpander.hhp ├── Table of Contents.hhc └── htm ├── DIV_File.htm ├── File_types.htm ├── KMP ├── areas.htm ├── camera_settings.htm ├── checkpoints.htm ├── enemy_points.htm ├── glider_routes.htm ├── item_points.htm ├── objects.htm ├── respawn_points.htm ├── routes.htm └── start_positions.htm ├── KMP_expander.htm ├── OBJ_Manager.htm ├── Options.htm ├── UIMapPos.htm ├── User Interface.htm └── kmp_file.htm /KMPExpander.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27703.2042 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KMPExpander", "KMPExpander\KMPExpander.csproj", "{85FFF84A-E5DA-4D42-A3C0-75968E004694}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "geometry3Sharp", "geometry3Sharp\geometry3Sharp.csproj", "{0C518DDA-28FE-44CA-9AB0-F9773974F13A}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {85FFF84A-E5DA-4D42-A3C0-75968E004694}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {85FFF84A-E5DA-4D42-A3C0-75968E004694}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {85FFF84A-E5DA-4D42-A3C0-75968E004694}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {85FFF84A-E5DA-4D42-A3C0-75968E004694}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {0C518DDA-28FE-44CA-9AB0-F9773974F13A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {0C518DDA-28FE-44CA-9AB0-F9773974F13A}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {0C518DDA-28FE-44CA-9AB0-F9773974F13A}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {0C518DDA-28FE-44CA-9AB0-F9773974F13A}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {2DBE2720-F9F3-45F3-9F90-B049E6F9CD6F} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /KMPExpander/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /KMPExpander/Class/EndianBinaryReaderExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using LibCTR.Collections; 6 | using LibEndianBinaryIO; 7 | 8 | namespace LibCTR.IO 9 | { 10 | public static class EndianBinaryReaderExtensions 11 | { 12 | public static Single ReadFx16(this EndianBinaryReader er) 13 | { 14 | return er.ReadInt16() / 4096f; 15 | } 16 | 17 | public static Vector3 ReadVecFx16(this EndianBinaryReader er) 18 | { 19 | return new Vector3(er.ReadFx16(), er.ReadFx16(), er.ReadFx16()); 20 | } 21 | 22 | public static Single[] ReadFx16s(this EndianBinaryReader er, int Count) 23 | { 24 | float[] result = new float[Count]; 25 | for (int i = 0; i < Count; i++) 26 | { 27 | result[i] = er.ReadFx16(); 28 | } 29 | return result; 30 | } 31 | 32 | public static Single ReadFx32(this EndianBinaryReader er) 33 | { 34 | return er.ReadInt32() / 4096f; 35 | } 36 | 37 | public static Vector3 ReadVecFx32(this EndianBinaryReader er) 38 | { 39 | return new Vector3(er.ReadFx32(), er.ReadFx32(), er.ReadFx32()); 40 | } 41 | 42 | public static Single[] ReadFx32s(this EndianBinaryReader er, int Count) 43 | { 44 | float[] result = new float[Count]; 45 | for (int i = 0; i < Count; i++) 46 | { 47 | result[i] = er.ReadFx32(); 48 | } 49 | return result; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /KMPExpander/Class/KMPs/AREA.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using LibCTR.Collections; 7 | using LibEndianBinaryIO; 8 | using LibEndianBinaryIO.Serialization; 9 | using Extensions; 10 | 11 | namespace KMPSections 12 | { 13 | public class AREA 14 | { 15 | public AREA() { Signature = "AERA"; } 16 | public AREA(EndianBinaryReaderEx er) 17 | { 18 | Signature = er.ReadString(Encoding.ASCII, 4); 19 | if (Signature != "AERA") throw new SignatureNotCorrectException(Signature, "AERA", er.BaseStream.Position - 4); 20 | NrEntries = er.ReadUInt32(); 21 | for (int i = 0; i < NrEntries; i++) Entries.Add(new AREAEntry(er)); 22 | } 23 | 24 | public void Write(EndianBinaryWriter er) 25 | { 26 | er.Write(Signature, Encoding.ASCII, false); 27 | NrEntries = (uint)Entries.Count; 28 | er.Write(NrEntries); 29 | for (int i = 0; i < NrEntries; i++) Entries[i].Write(er); 30 | } 31 | public String Signature; 32 | public UInt32 NrEntries; 33 | public List Entries = new List(); 34 | 35 | public class AREAEntry 36 | { 37 | public AREAEntry() 38 | { 39 | 40 | } 41 | public AREAEntry(EndianBinaryReaderEx er) 42 | { 43 | er.ReadObject(this); 44 | Rotation = new Vector3(RadianDegree.ToDegrees(Rotation.X), RadianDegree.ToDegrees(Rotation.Y), RadianDegree.ToDegrees(Rotation.Z)); 45 | } 46 | 47 | public void Write(EndianBinaryWriter er) 48 | { 49 | er.Write(Mode); 50 | er.Write(Type); 51 | er.Write(CAMEIndex); 52 | er.Write(Unknown1); 53 | er.Write(Position.X); 54 | er.Write(Position.Y); 55 | er.Write(Position.Z); 56 | er.Write(RadianDegree.ToRadians(Rotation.X)); 57 | er.Write(RadianDegree.ToRadians(Rotation.Y)); 58 | er.Write(RadianDegree.ToRadians(Rotation.Z)); 59 | er.Write(Scale.X); 60 | er.Write(Scale.Y); 61 | er.Write(Scale.Z); 62 | er.Write(Settings1); 63 | er.Write(Settings2); 64 | er.Write(RouteID); 65 | er.Write(EnemyID); 66 | er.Write(Unknown5); 67 | } 68 | public Byte Mode { get; set; } 69 | public Byte Type { get; set; } 70 | public SByte CAMEIndex { get; set; } 71 | public Byte Unknown1 { get; set; } 72 | public Vector3 Position { get; set; } 73 | public Vector3 Rotation { get; set; } 74 | public Vector3 Scale { get; set; } 75 | public UInt16 Settings1 { get; set; } 76 | public UInt16 Settings2 { get; set; } 77 | public sbyte RouteID { get; set; } 78 | public sbyte EnemyID { get; set; } 79 | public UInt16 Unknown5 { get; set; } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /KMPExpander/Class/KMPs/CKPH.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using LibCTR.Collections; 7 | using LibEndianBinaryIO; 8 | using LibEndianBinaryIO.Serialization; 9 | 10 | namespace KMPSections 11 | { 12 | public class CKPH 13 | { 14 | public CKPH() { Signature = "HPKC"; } 15 | public CKPH(EndianBinaryReaderEx er) 16 | { 17 | Signature = er.ReadString(Encoding.ASCII, 4); 18 | if (Signature != "HPKC") throw new SignatureNotCorrectException(Signature, "HPKC", er.BaseStream.Position - 4); 19 | NrEntries = er.ReadUInt32(); 20 | for (int i = 0; i < NrEntries; i++) Entries.Add(new CKPHEntry(er)); 21 | } 22 | 23 | 24 | public void Write(EndianBinaryWriter er) 25 | { 26 | er.Write(Signature, Encoding.ASCII, false); 27 | NrEntries = (uint)Entries.Count; 28 | er.Write(NrEntries); 29 | for (int i = 0; i < NrEntries; i++) Entries[i].Write(er); 30 | } 31 | public String Signature; 32 | public UInt32 NrEntries; 33 | public List Entries = new List(); 34 | 35 | public class CKPHEntry 36 | { 37 | public CKPHEntry() 38 | { 39 | Previous = new sbyte[] { -1, -1, -1, -1, -1, -1 }; 40 | Next = new sbyte[] { -1, -1, -1, -1, -1, -1 }; 41 | } 42 | public CKPHEntry(EndianBinaryReaderEx er) 43 | { 44 | er.ReadObject(this); 45 | } 46 | 47 | public void Write(EndianBinaryWriter er) 48 | { 49 | er.Write(Start); 50 | er.Write(Length); 51 | for (int i = 0; i < 6; i++) 52 | { 53 | er.Write(Previous[i]); 54 | } 55 | for (int i = 0; i < 6; i++) 56 | { 57 | er.Write(Next[i]); 58 | } 59 | er.Write(Unknown); 60 | } 61 | public Byte Start { get; set; } 62 | public Byte Length { get; set; } 63 | [BinaryFixedSize(6)] 64 | public SByte[] Previous { get; set; } 65 | [BinaryFixedSize(6)] 66 | public SByte[] Next { get; set; } 67 | public UInt16 Unknown { get; set; } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /KMPExpander/Class/KMPs/CKPT.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using LibCTR.Collections; 7 | using LibEndianBinaryIO; 8 | using LibEndianBinaryIO.Serialization; 9 | 10 | namespace KMPSections 11 | { 12 | public class CKPT 13 | { 14 | public CKPT() { Signature = "TPKC"; } 15 | public CKPT(EndianBinaryReaderEx er) 16 | { 17 | Signature = er.ReadString(Encoding.ASCII, 4); 18 | if (Signature != "TPKC") throw new SignatureNotCorrectException(Signature, "TPKC", er.BaseStream.Position - 4); 19 | NrEntries = er.ReadUInt32(); 20 | for (int i = 0; i < NrEntries; i++) Entries.Add(new CKPTEntry(er)); 21 | } 22 | 23 | public void Write(EndianBinaryWriter er) 24 | { 25 | er.Write(Signature, Encoding.ASCII, false); 26 | NrEntries = (uint)Entries.Count; 27 | er.Write(NrEntries); 28 | for (int i = 0; i < NrEntries; i++) Entries[i].Write(er); 29 | } 30 | public String Signature; 31 | public UInt32 NrEntries; 32 | public List Entries = new List(); 33 | 34 | public class CKPTEntry 35 | { 36 | public CKPTEntry() 37 | { 38 | Key = -1; 39 | Section = -1; 40 | } 41 | public CKPTEntry(EndianBinaryReaderEx er) 42 | { 43 | er.ReadObject(this); 44 | } 45 | 46 | public void Write(EndianBinaryWriter er) 47 | { 48 | er.Write(Point1.X); 49 | er.Write(Point1.Z); 50 | er.Write(Point2.X); 51 | er.Write(Point2.Z); 52 | er.Write(RespawnId); 53 | er.Write(Key); 54 | er.Write(Previous); 55 | er.Write(Next); 56 | er.Write(ClipID); 57 | er.Write(Section); 58 | er.Write(Unknown3); 59 | er.Write(Unknown4); 60 | } 61 | public Vector2 Point1 { get; set; } 62 | public Vector2 Point2 { get; set; } 63 | public Byte RespawnId { get; set; } 64 | public SByte Key { get; set; } 65 | public Byte Previous { get; set; } 66 | public Byte Next { get; set; } 67 | public SByte ClipID { get; set; } 68 | public SByte Section { get; set; } 69 | public Byte Unknown3 { get; set; } 70 | public Byte Unknown4 { get; set; } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /KMPExpander/Class/KMPs/CNPT.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using LibCTR.Collections; 7 | using LibEndianBinaryIO; 8 | using LibEndianBinaryIO.Serialization; 9 | 10 | namespace KMPSections 11 | { 12 | public class CNPT 13 | { 14 | public CNPT() { Signature = "TPNC"; } 15 | public CNPT(EndianBinaryReaderEx er) 16 | { 17 | Signature = er.ReadString(Encoding.ASCII, 4); 18 | if (Signature != "TPNC") throw new SignatureNotCorrectException(Signature, "TPNC", er.BaseStream.Position - 4); 19 | NrEntries = er.ReadUInt32(); 20 | //for (int i = 0; i < NrEntries; i++) Entries.Add(new AREAEntry(er)); 21 | } 22 | 23 | public void Write(EndianBinaryWriter er) 24 | { 25 | er.Write(Signature, Encoding.ASCII, false); 26 | //NrEntries = (uint)Entries.Count; 27 | er.Write(NrEntries); 28 | //for (int i = 0; i < NrEntries; i++) Entries[i].Write(er); 29 | } 30 | public String Signature; 31 | public UInt32 NrEntries; 32 | //public List Entries = new List(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /KMPExpander/Class/KMPs/CORS.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using LibCTR.Collections; 7 | using LibEndianBinaryIO; 8 | using LibEndianBinaryIO.Serialization; 9 | 10 | namespace KMPSections 11 | { 12 | public class CORS 13 | { 14 | public CORS() { Signature = "SROC"; } 15 | public CORS(EndianBinaryReaderEx er) 16 | { 17 | Signature = er.ReadString(Encoding.ASCII, 4); 18 | if (Signature != "SROC") throw new SignatureNotCorrectException(Signature, "SROC", er.BaseStream.Position - 4); 19 | NrEntries = er.ReadUInt32(); 20 | //for (int i = 0; i < NrEntries; i++) Entries.Add(new AREAEntry(er)); 21 | } 22 | 23 | public void Write(EndianBinaryWriter er) 24 | { 25 | er.Write(Signature, Encoding.ASCII, false); 26 | //NrEntries = (uint)Entries.Count; 27 | er.Write(NrEntries); 28 | //for (int i = 0; i < NrEntries; i++) Entries[i].Write(er); 29 | } 30 | public String Signature; 31 | public UInt32 NrEntries; 32 | //public List Entries = new List(); 33 | } 34 | } -------------------------------------------------------------------------------- /KMPExpander/Class/KMPs/ENPH.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using LibCTR.Collections; 7 | using LibEndianBinaryIO; 8 | using LibEndianBinaryIO.Serialization; 9 | 10 | namespace KMPSections 11 | { 12 | public class ENPH 13 | { 14 | public ENPH() 15 | { 16 | Signature = "HPNE"; 17 | } 18 | public ENPH(EndianBinaryReaderEx er) 19 | { 20 | Signature = er.ReadString(Encoding.ASCII, 4); 21 | if (Signature != "HPNE") throw new SignatureNotCorrectException(Signature, "HPNE", er.BaseStream.Position - 4); 22 | NrEntries = er.ReadUInt32(); 23 | for (int i = 0; i < NrEntries; i++) Entries.Add(new ENPHEntry(er)); 24 | } 25 | 26 | public void Write(EndianBinaryWriter er) 27 | { 28 | er.Write(Signature, Encoding.ASCII, false); 29 | NrEntries = (uint)Entries.Count; 30 | er.Write(NrEntries); 31 | for (int i = 0; i < NrEntries; i++) Entries[i].Write(er); 32 | } 33 | public String Signature; 34 | public UInt32 NrEntries; 35 | public List Entries = new List(); 36 | public class ENPHEntry 37 | { 38 | public ENPHEntry() 39 | { 40 | Previous = new short[] { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; 41 | Next = new short[] { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; 42 | } 43 | public ENPHEntry(EndianBinaryReaderEx er) 44 | { 45 | er.ReadObject(this); 46 | } 47 | 48 | public void Write(EndianBinaryWriter er) 49 | { 50 | er.Write(Start); 51 | er.Write(Length); 52 | for (int i = 0; i < 16; i++) 53 | { 54 | er.Write(Previous[i]); 55 | } 56 | for (int i = 0; i < 16; i++) 57 | { 58 | er.Write(Next[i]); 59 | } 60 | er.Write(Unknown); 61 | } 62 | 63 | public UInt16 Start { get; set; } 64 | public UInt16 Length { get; set; } 65 | [BinaryFixedSize(16)] 66 | public Int16[] Previous { get; set; } 67 | [BinaryFixedSize(16)] 68 | public Int16[] Next { get; set; } 69 | public UInt32 Unknown { get; set; } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /KMPExpander/Class/KMPs/ENPT.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows.Forms; 7 | using LibCTR.Collections; 8 | using LibEndianBinaryIO; 9 | using LibEndianBinaryIO.Serialization; 10 | using Tao.OpenGl; 11 | 12 | namespace KMPSections 13 | { 14 | public class ENPT 15 | { 16 | public ENPT() 17 | { 18 | Signature = "TPNE"; 19 | } 20 | public ENPT(EndianBinaryReaderEx er) 21 | { 22 | Signature = er.ReadString(Encoding.ASCII, 4); 23 | if (Signature != "TPNE") throw new SignatureNotCorrectException(Signature, "TPNE", er.BaseStream.Position - 4); 24 | NrEntries = er.ReadUInt32(); 25 | for (int i = 0; i < NrEntries; i++) Entries.Add(new ENPTEntry(er)); 26 | } 27 | 28 | public void Write(EndianBinaryWriter er) 29 | { 30 | er.Write(Signature, Encoding.ASCII, false); 31 | NrEntries = (uint)Entries.Count; 32 | er.Write(NrEntries); 33 | for (int i = 0; i < NrEntries; i++) Entries[i].Write(er); 34 | } 35 | public String Signature; 36 | public UInt32 NrEntries; 37 | public List Entries = new List(); 38 | public class ENPTEntry 39 | { 40 | public ENPTEntry() 41 | { 42 | Scale = 1f; 43 | } 44 | public ENPTEntry(EndianBinaryReaderEx er) 45 | { 46 | er.ReadObject(this); 47 | } 48 | public void Write(EndianBinaryWriter er) 49 | { 50 | er.Write(Position.X); 51 | er.Write(Position.Y); 52 | er.Write(Position.Z); 53 | er.Write(Scale); 54 | er.Write(MushSettingsVal); 55 | er.Write(DriftSettingsVal); 56 | er.Write(Flags); 57 | er.Write(Unknown2); 58 | er.Write(Unknown3); 59 | } 60 | public Vector3 Position { get; set; } 61 | public Single Scale { get; set; } 62 | public UInt16 MushSettingsVal { get; set; } 63 | public byte DriftSettingsVal { get; set; } 64 | public byte Flags { get; set; } 65 | public Int16 Unknown2 { get; set; } 66 | public Int16 Unknown3 { get; set; } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /KMPExpander/Class/KMPs/GLPH.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using LibCTR.Collections; 7 | using LibEndianBinaryIO; 8 | using LibEndianBinaryIO.Serialization; 9 | 10 | namespace KMPSections 11 | { 12 | public class GLPH 13 | { 14 | public GLPH() { Signature = "HPLG"; } 15 | public GLPH(EndianBinaryReaderEx er) 16 | { 17 | Signature = er.ReadString(Encoding.ASCII, 4); 18 | if (Signature != "HPLG") throw new SignatureNotCorrectException(Signature, "HPLG", er.BaseStream.Position - 4); 19 | NrEntries = er.ReadUInt32(); 20 | for (int i = 0; i < NrEntries; i++) Entries.Add(new GLPHEntry(er)); 21 | } 22 | public void Write(EndianBinaryWriter er) 23 | { 24 | er.Write(Signature, Encoding.ASCII, false); 25 | NrEntries = (uint)Entries.Count; 26 | er.Write(NrEntries); 27 | for (int i = 0; i < NrEntries; i++) Entries[i].Write(er); 28 | } 29 | public String Signature; 30 | public UInt32 NrEntries; 31 | public List Entries = new List(); 32 | public class GLPHEntry 33 | { 34 | public GLPHEntry() 35 | { 36 | Previous = new sbyte[] { -1, -1, -1, -1, -1, -1,}; 37 | Next = new sbyte[] { -1, -1, -1, -1, -1, -1, }; 38 | } 39 | public GLPHEntry(EndianBinaryReaderEx er) 40 | { 41 | er.ReadObject(this); 42 | } 43 | 44 | public void Write(EndianBinaryWriter er) 45 | { 46 | er.Write(Start); 47 | er.Write(Length); 48 | for (int i = 0; i < 6; i++) 49 | { 50 | er.Write(Previous[i]); 51 | } 52 | for (int i = 0; i < 6; i++) 53 | { 54 | er.Write(Next[i]); 55 | } 56 | er.Write(Unknown1); 57 | er.Write(Unknown2); 58 | } 59 | public Byte Start { get; set; } 60 | public Byte Length { get; set; } 61 | [BinaryFixedSize(6)] 62 | public SByte[] Previous { get; set; } 63 | [BinaryFixedSize(6)] 64 | public SByte[] Next { get; set; } 65 | public UInt32 Unknown1 { get; set; } 66 | public UInt32 Unknown2 { get; set; } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /KMPExpander/Class/KMPs/GLPT.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using LibCTR.Collections; 7 | using LibEndianBinaryIO; 8 | using LibEndianBinaryIO.Serialization; 9 | 10 | namespace KMPSections 11 | { 12 | public class GLPT 13 | { 14 | public GLPT() 15 | { 16 | Signature = "TPLG"; 17 | } 18 | public GLPT(EndianBinaryReaderEx er) 19 | { 20 | Signature = er.ReadString(Encoding.ASCII, 4); 21 | if (Signature != "TPLG") throw new SignatureNotCorrectException(Signature, "TPLG", er.BaseStream.Position - 4); 22 | NrEntries = er.ReadUInt32(); 23 | for (int i = 0; i < NrEntries; i++) Entries.Add(new GLPTEntry(er)); 24 | } 25 | public void Write(EndianBinaryWriter er) 26 | { 27 | er.Write(Signature, Encoding.ASCII, false); 28 | NrEntries = (uint)Entries.Count; 29 | er.Write(NrEntries); 30 | for (int i = 0; i < NrEntries; i++) Entries[i].Write(er); 31 | } 32 | public String Signature; 33 | public UInt32 NrEntries; 34 | public List Entries = new List(); 35 | public class GLPTEntry 36 | { 37 | public GLPTEntry() { } 38 | public GLPTEntry(EndianBinaryReaderEx er) 39 | { 40 | er.ReadObject(this); 41 | } 42 | 43 | public void Write(EndianBinaryWriter er) 44 | { 45 | er.Write(Position.X); 46 | er.Write(Position.Y); 47 | er.Write(Position.Z); 48 | er.Write(Scale); 49 | er.Write(Unknown1); 50 | er.Write(Unknown2); 51 | } 52 | public Vector3 Position { get; set; } 53 | public Single Scale { get; set; } 54 | public UInt32 Unknown1 { get; set; } 55 | public UInt32 Unknown2 { get; set; } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /KMPExpander/Class/KMPs/ITPH.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using LibCTR.Collections; 7 | using LibEndianBinaryIO; 8 | using LibEndianBinaryIO.Serialization; 9 | 10 | namespace KMPSections 11 | { 12 | public class ITPH 13 | { 14 | public ITPH() 15 | { 16 | Signature = "HPTI"; 17 | } 18 | public ITPH(EndianBinaryReaderEx er) 19 | { 20 | Signature = er.ReadString(Encoding.ASCII, 4); 21 | if (Signature != "HPTI") throw new SignatureNotCorrectException(Signature, "HPTI", er.BaseStream.Position - 4); 22 | NrEntries = er.ReadUInt32(); 23 | for (int i = 0; i < NrEntries; i++) Entries.Add(new ITPHEntry(er)); 24 | } 25 | 26 | public void Write(EndianBinaryWriter er) 27 | { 28 | er.Write(Signature, Encoding.ASCII, false); 29 | NrEntries = (uint)Entries.Count; 30 | er.Write(NrEntries); 31 | for (int i = 0; i < NrEntries; i++) Entries[i].Write(er); 32 | } 33 | public String Signature; 34 | public UInt32 NrEntries; 35 | public List Entries = new List(); 36 | public class ITPHEntry 37 | { 38 | public ITPHEntry() 39 | { 40 | Previous = new short[] { -1, -1, -1, -1, -1, -1 }; 41 | Next = new short[] { -1, -1, -1, -1, -1, -1 }; 42 | } 43 | public ITPHEntry(EndianBinaryReaderEx er) 44 | { 45 | er.ReadObject(this); 46 | } 47 | 48 | public void Write(EndianBinaryWriter er) 49 | { 50 | er.Write(Start); 51 | er.Write(Length); 52 | for (int i = 0; i < 6; i++) 53 | { 54 | er.Write(Previous[i]); 55 | } 56 | for (int i = 0; i < 6; i++) 57 | { 58 | er.Write(Next[i]); 59 | } 60 | } 61 | public UInt16 Start { get; set; } 62 | public UInt16 Length { get; set; } 63 | [BinaryFixedSize(6)] 64 | public Int16[] Previous { get; set; } 65 | [BinaryFixedSize(6)] 66 | public Int16[] Next { get; set; } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /KMPExpander/Class/KMPs/ITPT.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using LibCTR.Collections; 7 | using LibEndianBinaryIO; 8 | using LibEndianBinaryIO.Serialization; 9 | 10 | namespace KMPSections 11 | { 12 | public class ITPT 13 | { 14 | 15 | public ITPT() 16 | { 17 | Signature = "TPTI"; 18 | } 19 | public ITPT(EndianBinaryReaderEx er) 20 | { 21 | Signature = er.ReadString(Encoding.ASCII, 4); 22 | if (Signature != "TPTI") throw new SignatureNotCorrectException(Signature, "TPTI", er.BaseStream.Position - 4); 23 | NrEntries = er.ReadUInt32(); 24 | for (int i = 0; i < NrEntries; i++) Entries.Add(new ITPTEntry(er)); 25 | } 26 | 27 | public void Write(EndianBinaryWriter er) 28 | { 29 | er.Write(Signature, Encoding.ASCII, false); 30 | NrEntries = (uint)Entries.Count; 31 | er.Write(NrEntries); 32 | for (int i = 0; i < NrEntries; i++) Entries[i].Write(er); 33 | } 34 | public String Signature; 35 | public UInt32 NrEntries; 36 | public List Entries = new List(); 37 | public class ITPTEntry 38 | { 39 | public ITPTEntry() 40 | { 41 | Scale = 1f; 42 | } 43 | public ITPTEntry(EndianBinaryReaderEx er) 44 | { 45 | er.ReadObject(this); 46 | } 47 | 48 | public void Write(EndianBinaryWriter er) 49 | { 50 | er.Write(Position.X); 51 | er.Write(Position.Y); 52 | er.Write(Position.Z); 53 | er.Write(Scale); 54 | er.Write(FlyModeVal); 55 | er.Write(PlayerScanRadiusVal); 56 | } 57 | public Vector3 Position { get; set; } 58 | public Single Scale { get; set; } 59 | public UInt16 FlyModeVal { get; set; } 60 | public UInt16 PlayerScanRadiusVal { get; set;} 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /KMPExpander/Class/KMPs/JGPT.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using LibCTR.Collections; 7 | using LibEndianBinaryIO; 8 | using LibEndianBinaryIO.Serialization; 9 | using Extensions; 10 | 11 | namespace KMPSections 12 | { 13 | public class JGPT 14 | { 15 | public JGPT() { Signature = "TPGJ"; } 16 | public JGPT(EndianBinaryReaderEx er) 17 | { 18 | Signature = er.ReadString(Encoding.ASCII, 4); 19 | if (Signature != "TPGJ") throw new SignatureNotCorrectException(Signature, "TPGJ", er.BaseStream.Position - 4); 20 | NrEntries = er.ReadUInt32(); 21 | for (int i = 0; i < NrEntries; i++) Entries.Add(new JGPTEntry(er)); 22 | } 23 | 24 | public void Write(EndianBinaryWriter er) 25 | { 26 | er.Write(Signature, Encoding.ASCII, false); 27 | NrEntries = (uint)Entries.Count; 28 | er.Write(NrEntries); 29 | for (int i = 0; i < NrEntries; i++) Entries[i].Write(er); 30 | } 31 | public String Signature; 32 | public UInt32 NrEntries; 33 | public List Entries = new List(); 34 | public class JGPTEntry 35 | { 36 | public JGPTEntry() 37 | { 38 | Index = 0; 39 | Unknown = 0xFFFF; 40 | } 41 | public JGPTEntry(EndianBinaryReaderEx er) 42 | { 43 | er.ReadObject(this); 44 | Rotation = new Vector3(RadianDegree.ToDegrees(Rotation.X), RadianDegree.ToDegrees(Rotation.Y), RadianDegree.ToDegrees(Rotation.Z)); 45 | } 46 | public void Write(EndianBinaryWriter er) 47 | { 48 | er.Write(Position.X); 49 | er.Write(Position.Y); 50 | er.Write(Position.Z); 51 | er.Write(RadianDegree.ToRadians(Rotation.X)); 52 | er.Write(RadianDegree.ToRadians(Rotation.Y)); 53 | er.Write(RadianDegree.ToRadians(Rotation.Z)); 54 | er.Write(Index); 55 | er.Write(Unknown); 56 | } 57 | public Vector3 Position { get; set; } 58 | public Vector3 Rotation { get; set; } 59 | public UInt16 Index { get; set; } 60 | public UInt16 Unknown { get; set; } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /KMPExpander/Class/KMPs/KTPT.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using LibCTR.Collections; 7 | using LibEndianBinaryIO; 8 | using LibEndianBinaryIO.Serialization; 9 | using Extensions; 10 | 11 | namespace KMPSections 12 | { 13 | public class KTPT 14 | { 15 | public KTPT() 16 | { 17 | Signature = "TPTK"; 18 | } 19 | 20 | public KTPT(EndianBinaryReaderEx er) 21 | { 22 | Signature = er.ReadString(Encoding.ASCII, 4); 23 | if (Signature != "TPTK") throw new SignatureNotCorrectException(Signature, "TPTK", er.BaseStream.Position - 4); 24 | NrEntries = er.ReadUInt32(); 25 | for (int i = 0; i < NrEntries; i++) Entries.Add(new KTPTEntry(er)); 26 | } 27 | 28 | public void Write(EndianBinaryWriter er) 29 | { 30 | er.Write(Signature, Encoding.ASCII, false); 31 | NrEntries = (uint)Entries.Count; 32 | er.Write(NrEntries); 33 | for (int i = 0; i < NrEntries; i++) Entries[i].Write(er); 34 | } 35 | 36 | public String Signature; 37 | public UInt32 NrEntries; 38 | public List Entries = new List(); 39 | public class KTPTEntry 40 | { 41 | public KTPTEntry() { } 42 | public KTPTEntry(EndianBinaryReaderEx er) 43 | { 44 | er.ReadObject(this); 45 | Rotation = new Vector3(RadianDegree.ToDegrees(Rotation.X), RadianDegree.ToDegrees(Rotation.Y), RadianDegree.ToDegrees(Rotation.Z)); 46 | } 47 | 48 | public void Write(EndianBinaryWriter er) 49 | { 50 | er.Write(Position.X); 51 | er.Write(Position.Y); 52 | er.Write(Position.Z); 53 | er.Write(RadianDegree.ToRadians(Rotation.X)); 54 | er.Write(RadianDegree.ToRadians(Rotation.Y)); 55 | er.Write(RadianDegree.ToRadians(Rotation.Z)); 56 | er.Write(Index); 57 | } 58 | public Vector3 Position { get; set; } 59 | public Vector3 Rotation { get; set; } 60 | public UInt32 Index { get; set; } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /KMPExpander/Class/KMPs/MSPT.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using LibCTR.Collections; 7 | using LibEndianBinaryIO; 8 | using LibEndianBinaryIO.Serialization; 9 | 10 | namespace KMPSections 11 | { 12 | public class MSPT 13 | { 14 | public MSPT() { Signature = "TPSM"; } 15 | public MSPT(EndianBinaryReaderEx er) 16 | { 17 | Signature = er.ReadString(Encoding.ASCII, 4); 18 | if (Signature != "TPSM") throw new SignatureNotCorrectException(Signature, "TPSM", er.BaseStream.Position - 4); 19 | NrEntries = er.ReadUInt32(); 20 | //for (int i = 0; i < NrEntries; i++) Entries.Add(new AREAEntry(er)); 21 | } 22 | 23 | public void Write(EndianBinaryWriter er) 24 | { 25 | er.Write(Signature, Encoding.ASCII, false); 26 | //NrEntries = (uint)Entries.Count; 27 | er.Write(NrEntries); 28 | //for (int i = 0; i < NrEntries; i++) Entries[i].Write(er); 29 | } 30 | public String Signature; 31 | public UInt32 NrEntries; 32 | //public List Entries = new List(); 33 | } 34 | } -------------------------------------------------------------------------------- /KMPExpander/Class/KMPs/STGI.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using LibCTR.Collections; 7 | using LibEndianBinaryIO; 8 | using LibEndianBinaryIO.Serialization; 9 | 10 | namespace KMPSections 11 | { 12 | public class STGI 13 | { 14 | public STGI() { 15 | Signature = "IGTS"; 16 | } 17 | public STGI(EndianBinaryReaderEx er) 18 | { 19 | Signature = er.ReadString(Encoding.ASCII, 4); 20 | if (Signature != "IGTS") throw new SignatureNotCorrectException(Signature, "IGTS", er.BaseStream.Position - 4); 21 | NrEntries = er.ReadUInt32(); 22 | for (int i = 0; i < NrEntries; i++) Entries.Add(new STGIEntry(er)); 23 | } 24 | 25 | public void Write(EndianBinaryWriter er) 26 | { 27 | er.Write(Signature, Encoding.ASCII, false); 28 | NrEntries = (uint)Entries.Count; 29 | er.Write(NrEntries); 30 | for (int i = 0; i < NrEntries; i++) Entries[i].Write(er); 31 | } 32 | public String Signature; 33 | public UInt32 NrEntries; 34 | public List Entries = new List(); 35 | public class STGIEntry 36 | { 37 | public STGIEntry() { } 38 | public STGIEntry(EndianBinaryReaderEx er) 39 | { 40 | er.ReadObject(this); 41 | } 42 | 43 | public void Write(EndianBinaryWriter er) 44 | { 45 | er.Write(NrLaps); 46 | er.Write(Unknown1); 47 | er.Write(Unknown2); 48 | er.Write(Unknown3); 49 | er.Write(Unknown4); 50 | er.Write(Unknown5); 51 | } 52 | public Byte NrLaps { get; set; } 53 | public Byte Unknown1 { get; set; } 54 | public Byte Unknown2 { get; set; } 55 | public Byte Unknown3 { get; set; } 56 | public Int32 Unknown4 { get; set; } 57 | public Int32 Unknown5 { get; set; } 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /KMPExpander/Class/Picking.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace KMPExpander.Class 9 | { 10 | public enum Sections 11 | { 12 | None=0, StartPositions = 1,EnemyRoutes = 2,ItemRoutes = 3,GliderRoutes=4,CheckPoints=5,Objects=6,RespawnPoints=7,Routes=8,Area=9,Camera=10,GlobalMap=11,LocalMap=12,StageInformation=13 13 | } 14 | 15 | public enum PointID 16 | { 17 | None = 0, Left = 1, Right = 2 18 | } 19 | 20 | public static class ModelPicking 21 | { 22 | public static Color GetColor(int face_id) 23 | { 24 | return Color.FromArgb(255,Color.FromArgb(face_id)); 25 | } 26 | 27 | public static int FromRgb(int red, int green, int blue) 28 | { 29 | return FromColor(Color.FromArgb(0,red,green,blue)); 30 | } 31 | 32 | public static int FromColor(Color color) 33 | { 34 | return color.ToArgb(); 35 | } 36 | 37 | } 38 | 39 | public static class SectionPicking 40 | { 41 | public static Color GetColor(Sections section,int group_id,int entry_id,PointID point=PointID.None) 42 | { 43 | int Red = (((int)section)<<2) | ((int)point&3); 44 | int Green = group_id; 45 | int Blue = entry_id; 46 | 47 | return Color.FromArgb(255, Red, Green, Blue); 48 | } 49 | 50 | public static PickingInfo FromColor(Color color) 51 | { 52 | return FromRgb(color.R, color.G, color.B); 53 | } 54 | 55 | public static PickingInfo FromRgb(int red,int green,int blue) 56 | { 57 | PickingInfo info = new PickingInfo(); 58 | 59 | info.Section = (Sections)((red & 0xFC) >> 2); 60 | info.PointID = (PointID)(red & 3); 61 | info.GroupID = green; 62 | info.EntryID = blue; 63 | 64 | return info; 65 | } 66 | public struct PickingInfo 67 | { 68 | public Sections Section; 69 | public PointID PointID; 70 | public int GroupID; 71 | public int EntryID; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /KMPExpander/Class/SimpleKMPs/Generic.cs: -------------------------------------------------------------------------------- 1 | using LibCTR.Collections; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Xml.Serialization; 8 | 9 | namespace KMPExpander.Class.SimpleKMPs 10 | { 11 | public interface ISectionBase 12 | { 13 | object Add(); 14 | void Add(object entry); 15 | void Remove(object entry); 16 | object Insert(int row); 17 | void Insert(int row, object entry); 18 | object GetEntries(); 19 | void New(); 20 | int IndexOf(object entry); 21 | int GetCount(); 22 | bool GetVisibility(); 23 | void SetVisibility(bool visible); 24 | } 25 | 26 | 27 | public class SectionBase : ISectionBase where T : new() 28 | { 29 | public List Entries = new List(); 30 | [XmlIgnore] 31 | public bool Visible = true; 32 | 33 | public object Add() 34 | { 35 | T entry = new T(); 36 | Entries.Add(entry); 37 | return entry; 38 | } 39 | 40 | public void Remove(object entry) 41 | { 42 | Entries.Remove((T)entry); 43 | } 44 | 45 | public void New() 46 | { 47 | Entries = new List(); 48 | } 49 | 50 | public void Add(object entry) 51 | { 52 | Entries.Add((T)entry); 53 | } 54 | 55 | public object GetEntries() 56 | { 57 | return Entries; 58 | } 59 | 60 | public void Insert(int row, object entry) 61 | { 62 | Entries.Insert(row, (T)entry); 63 | } 64 | 65 | public object Insert(int row) 66 | { 67 | T entry = new T(); 68 | Entries.Insert(row,entry); 69 | return entry; 70 | } 71 | 72 | public int IndexOf(object entry) 73 | { 74 | return Entries.IndexOf((T)entry); 75 | } 76 | 77 | public int GetCount() 78 | { 79 | return Entries.Count; 80 | } 81 | 82 | public bool GetVisibility() 83 | { 84 | return Visible; 85 | } 86 | 87 | public void SetVisibility(bool visible) 88 | { 89 | Visible = visible; 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /KMPExpander/Class/TreeViewFix.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows.Forms; 7 | 8 | namespace KMPExpander.Class 9 | { 10 | //You cannot activate the doubleclick event anymore 11 | public class TreeViewFix : TreeView 12 | { 13 | protected override void WndProc(ref Message m) 14 | { 15 | if (m.Msg == 0x0203) 16 | { 17 | m.Result = IntPtr.Zero; 18 | } 19 | else 20 | { 21 | base.WndProc(ref m); 22 | } 23 | } 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /KMPExpander/FormOBJ.cs: -------------------------------------------------------------------------------- 1 | using KMPExpander.Class; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Data; 6 | using System.Drawing; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using System.Windows.Forms; 11 | 12 | namespace KMPExpander 13 | { 14 | public partial class FormOBJ : Form 15 | { 16 | public Form1 form1; 17 | 18 | public FormOBJ(Form1 form1) 19 | { 20 | InitializeComponent(); 21 | this.form1 = form1; 22 | } 23 | 24 | private void loadWavefrontToolStripMenuItem_Click(object sender, EventArgs e) 25 | { 26 | if (openFileDialogOBJ.ShowDialog() == DialogResult.OK) 27 | { 28 | try 29 | { 30 | form1.OBJModel = new OBJWrapper(openFileDialogOBJ.FileName); 31 | comboBox1.DataSource = form1.OBJModel.Materials; 32 | checkBox1.Enabled = true; 33 | checkBox2.Enabled = true; 34 | } 35 | catch (Exception ex) 36 | { 37 | MessageBox.Show(ex.ToString()); 38 | } 39 | } 40 | form1.Render(); 41 | } 42 | private void closeWavefrontToolStripMenuItem_Click(object sender, EventArgs e) 43 | { 44 | form1.OBJModel = null; 45 | comboBox1.DataSource = null; 46 | propertyGrid1.SelectedObject = null; 47 | pictureBoxTex.Image = null; 48 | checkBox1.Enabled = false; 49 | checkBox2.Enabled = false; 50 | form1.Render(); 51 | } 52 | 53 | private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 54 | { 55 | if (form1.OBJModel == null) return; 56 | OBJWrapper.MaterialInfo matInfo = ((OBJWrapper.MaterialInfo)comboBox1.Items[comboBox1.SelectedIndex]); 57 | propertyGrid1.SelectedObject = matInfo; 58 | pictureBoxTex.Image = matInfo.Texture; 59 | form1.Render(); 60 | } 61 | 62 | private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) 63 | { 64 | form1.Render(); 65 | } 66 | 67 | private void checkBox1_CheckedChanged(object sender, EventArgs e) 68 | { 69 | form1.OBJModel.Visible = (sender as CheckBox).Checked; 70 | form1.Render(); 71 | } 72 | 73 | private void checkBox2_CheckedChanged(object sender, EventArgs e) 74 | { 75 | form1.OBJModel.Wireframe = (sender as CheckBox).Checked; 76 | form1.Render(); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /KMPExpander/FormSettings.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace KMPExpander 2 | { 3 | partial class FormSettings 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.propertyGrid1 = new System.Windows.Forms.PropertyGrid(); 32 | this.SuspendLayout(); 33 | // 34 | // propertyGrid1 35 | // 36 | this.propertyGrid1.Dock = System.Windows.Forms.DockStyle.Fill; 37 | this.propertyGrid1.Location = new System.Drawing.Point(0, 0); 38 | this.propertyGrid1.Name = "propertyGrid1"; 39 | this.propertyGrid1.Size = new System.Drawing.Size(343, 331); 40 | this.propertyGrid1.TabIndex = 0; 41 | this.propertyGrid1.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.propertyGrid1_PropertyValueChanged); 42 | // 43 | // FormSettings 44 | // 45 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 46 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 47 | this.ClientSize = new System.Drawing.Size(343, 331); 48 | this.Controls.Add(this.propertyGrid1); 49 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; 50 | this.Name = "FormSettings"; 51 | this.Text = "Settings"; 52 | this.ResumeLayout(false); 53 | 54 | } 55 | 56 | #endregion 57 | 58 | private System.Windows.Forms.PropertyGrid propertyGrid1; 59 | } 60 | } -------------------------------------------------------------------------------- /KMPExpander/FormSettings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace KMPExpander 12 | { 13 | public partial class FormSettings : Form 14 | { 15 | Form1 form1; 16 | 17 | public FormSettings(Form1 form1) 18 | { 19 | InitializeComponent(); 20 | this.form1 = form1; 21 | propertyGrid1.SelectedObject = form1.Settings; 22 | } 23 | 24 | private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) 25 | { 26 | form1.Render(); 27 | form1.Settings.ToXML(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /KMPExpander/FormTransform.cs: -------------------------------------------------------------------------------- 1 | using LibCTR.Collections; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Data; 6 | using System.Drawing; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using System.Windows.Forms; 11 | 12 | namespace KMPExpander 13 | { 14 | public partial class FormTransform : Form 15 | { 16 | public FormTransform() 17 | { 18 | InitializeComponent(); 19 | 20 | KMPTranslation = new Vector3(0f, 0f, 0f); 21 | KMPScale = new Vector3(1f, 1f, 1f); 22 | } 23 | 24 | private void button_cancel_Click(object sender, EventArgs e) 25 | { 26 | Close(); 27 | } 28 | 29 | private void button_ok_Click(object sender, EventArgs e) 30 | { 31 | Confirmed = true; 32 | Close(); 33 | } 34 | 35 | public bool Confirmed = false; 36 | 37 | public Vector3 KMPTranslation 38 | { 39 | get 40 | { 41 | return new Vector3((float)translation_X.Value, (float)translation_Y.Value, (float)translation_Z.Value); 42 | } 43 | set 44 | { 45 | translation_X.Value = (decimal)value.X; 46 | translation_Y.Value = (decimal)value.Y; 47 | translation_Z.Value = (decimal)value.Z; 48 | } 49 | } 50 | 51 | public Vector3 KMPScale 52 | { 53 | get 54 | { 55 | return new Vector3((float)scale_X.Value, (float)scale_Y.Value, (float)scale_Z.Value); 56 | } 57 | set 58 | { 59 | scale_X.Value = (decimal)value.X; 60 | scale_Y.Value = (decimal)value.Y; 61 | scale_Z.Value = (decimal)value.Z; 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /KMPExpander/Icons/KMP_Expander_App_Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/KMP_Expander_App_Icon.ico -------------------------------------------------------------------------------- /KMPExpander/Icons/KMP_File_Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/KMP_File_Icon.ico -------------------------------------------------------------------------------- /KMPExpander/Icons/area/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/area/1.png -------------------------------------------------------------------------------- /KMPExpander/Icons/area/1_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/area/1_original.png -------------------------------------------------------------------------------- /KMPExpander/Icons/came/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/came/1.png -------------------------------------------------------------------------------- /KMPExpander/Icons/came/1_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/came/1_original.png -------------------------------------------------------------------------------- /KMPExpander/Icons/checkpoint/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/checkpoint/1.png -------------------------------------------------------------------------------- /KMPExpander/Icons/checkpoint/1_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/checkpoint/1_original.png -------------------------------------------------------------------------------- /KMPExpander/Icons/div/child.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/div/child.png -------------------------------------------------------------------------------- /KMPExpander/Icons/div/parent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/div/parent.png -------------------------------------------------------------------------------- /KMPExpander/Icons/enm/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/enm/1.png -------------------------------------------------------------------------------- /KMPExpander/Icons/enm/1_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/enm/1_original.png -------------------------------------------------------------------------------- /KMPExpander/Icons/enm/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/enm/2.png -------------------------------------------------------------------------------- /KMPExpander/Icons/enm/2_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/enm/2_original.png -------------------------------------------------------------------------------- /KMPExpander/Icons/enm/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/enm/3.png -------------------------------------------------------------------------------- /KMPExpander/Icons/enm/3_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/enm/3_original.png -------------------------------------------------------------------------------- /KMPExpander/Icons/enm/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/enm/4.png -------------------------------------------------------------------------------- /KMPExpander/Icons/enm/4_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/enm/4_original.png -------------------------------------------------------------------------------- /KMPExpander/Icons/enm/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/enm/5.png -------------------------------------------------------------------------------- /KMPExpander/Icons/enm/5_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/enm/5_original.png -------------------------------------------------------------------------------- /KMPExpander/Icons/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/error.png -------------------------------------------------------------------------------- /KMPExpander/Icons/glider/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/glider/1.png -------------------------------------------------------------------------------- /KMPExpander/Icons/glider/1_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/glider/1_original.png -------------------------------------------------------------------------------- /KMPExpander/Icons/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/info.png -------------------------------------------------------------------------------- /KMPExpander/Icons/item/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/item/1.png -------------------------------------------------------------------------------- /KMPExpander/Icons/item/1_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/item/1_original.png -------------------------------------------------------------------------------- /KMPExpander/Icons/item/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/item/2.png -------------------------------------------------------------------------------- /KMPExpander/Icons/item/2_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/item/2_original.png -------------------------------------------------------------------------------- /KMPExpander/Icons/item/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/item/3.png -------------------------------------------------------------------------------- /KMPExpander/Icons/item/3_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/item/3_original.png -------------------------------------------------------------------------------- /KMPExpander/Icons/item/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/item/4.png -------------------------------------------------------------------------------- /KMPExpander/Icons/item/4_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/item/4_original.png -------------------------------------------------------------------------------- /KMPExpander/Icons/item/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/item/5.png -------------------------------------------------------------------------------- /KMPExpander/Icons/item/5_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/item/5_original.png -------------------------------------------------------------------------------- /KMPExpander/Icons/item/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/item/6.png -------------------------------------------------------------------------------- /KMPExpander/Icons/item/6_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/item/6_original.png -------------------------------------------------------------------------------- /KMPExpander/Icons/other/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/other/empty.png -------------------------------------------------------------------------------- /KMPExpander/Icons/other/gcheckpoint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/other/gcheckpoint.png -------------------------------------------------------------------------------- /KMPExpander/Icons/other/genm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/other/genm.png -------------------------------------------------------------------------------- /KMPExpander/Icons/other/gglider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/other/gglider.png -------------------------------------------------------------------------------- /KMPExpander/Icons/other/gitem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/other/gitem.png -------------------------------------------------------------------------------- /KMPExpander/Icons/other/groutes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/other/groutes.png -------------------------------------------------------------------------------- /KMPExpander/Icons/respawn/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/respawn/1.png -------------------------------------------------------------------------------- /KMPExpander/Icons/respawn/1_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/respawn/1_original.png -------------------------------------------------------------------------------- /KMPExpander/Icons/routes/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/routes/1.png -------------------------------------------------------------------------------- /KMPExpander/Icons/routes/1_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/routes/1_original.png -------------------------------------------------------------------------------- /KMPExpander/Icons/startpos/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/startpos/1.png -------------------------------------------------------------------------------- /KMPExpander/Icons/startpos/1_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/startpos/1_original.png -------------------------------------------------------------------------------- /KMPExpander/Icons/startpos/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/startpos/2.png -------------------------------------------------------------------------------- /KMPExpander/Icons/startpos/2_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/startpos/2_original.png -------------------------------------------------------------------------------- /KMPExpander/Icons/stgi/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/stgi/1.png -------------------------------------------------------------------------------- /KMPExpander/Icons/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Icons/warning.png -------------------------------------------------------------------------------- /KMPExpander/KMP_Expander_App_Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/KMP_Expander_App_Icon.ico -------------------------------------------------------------------------------- /KMPExpander/LibEndianBinaryIO.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/LibEndianBinaryIO.dll -------------------------------------------------------------------------------- /KMPExpander/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | namespace KMPExpander 8 | { 9 | static class Program 10 | { 11 | /// 12 | /// The main entry point for the application. 13 | /// 14 | [STAThread] 15 | static void Main(string[] args) 16 | { 17 | 18 | Application.EnableVisualStyles(); 19 | Application.SetCompatibleTextRenderingDefault(false); 20 | if (args.Length > 0) Application.Run(new Form1(args[0])); 21 | else Application.Run(new Form1()); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /KMPExpander/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("KMPExpander")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("KMPExpander")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("85fff84a-e5da-4d42-a3c0-75968e004694")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /KMPExpander/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Este código fue generado por una herramienta. 4 | // Versión de runtime:4.0.30319.42000 5 | // 6 | // Los cambios en este archivo podrían causar un comportamiento incorrecto y se perderán si 7 | // se vuelve a generar el código. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace KMPExpander.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.3.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /KMPExpander/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /KMPExpander/Resources/div.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Resources/div.bmp -------------------------------------------------------------------------------- /KMPExpander/Resources/error.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/KMPExpander/Resources/error.bmp -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KMPExpander 2 | Mario Kart 7 KMP editor made by Ermelber and PabloMK7. 3 | -------------------------------------------------------------------------------- /geometry3Sharp/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | *.smod 19 | 20 | # Compiled Static libraries 21 | *.lai 22 | *.la 23 | *.a 24 | *.lib 25 | 26 | # Executables 27 | *.exe 28 | *.out 29 | *.app 30 | geometry3Sharp/bin 31 | geometry3Sharp/obj 32 | geometry3Sharp.csproj.user 33 | bin 34 | obj 35 | *.meta 36 | -------------------------------------------------------------------------------- /geometry3Sharp/LICENSE: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /geometry3Sharp/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | #if !G3_USING_UNITY 2 | 3 | using System.Reflection; 4 | using System.Runtime.CompilerServices; 5 | using System.Runtime.InteropServices; 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("geometry3Sharp")] 11 | [assembly: AssemblyDescription("C# library for 3D geometric computation, mesh algorithms, etc.")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("Ryan Schmidt/gradientspace")] 14 | [assembly: AssemblyProduct("geometry3Sharp")] 15 | [assembly: AssemblyCopyright("Copyright © Ryan Schmidt/gradientspace 2016")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(false)] 23 | 24 | // The following GUID is for the ID of the typelib if this project is exposed to COM 25 | [assembly: Guid("0c518dda-28fe-44ca-9ab0-f9773974f13a")] 26 | 27 | // Version information for an assembly consists of the following four values: 28 | // 29 | // Major Version 30 | // Minor Version 31 | // Build Number 32 | // Revision 33 | // 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | 37 | #endif -------------------------------------------------------------------------------- /geometry3Sharp/approximation/OrthogonalPlaneFit3.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace g3 5 | { 6 | // Ported from WildMagic5 Wm5ApprPlaneFit3 7 | // Least-squares fit of a plane to (x,y,z) data by using distance measurements 8 | // orthogonal to the proposed plane. 9 | public class OrthogonalPlaneFit3 10 | { 11 | public Vector3d Origin; 12 | public Vector3d Normal; 13 | public bool ResultValid = false; 14 | 15 | public OrthogonalPlaneFit3(IEnumerable points) 16 | { 17 | // Compute the mean of the points. 18 | Origin = Vector3d.Zero; 19 | int numPoints = 0; 20 | foreach (Vector3d v in points) { 21 | Origin += v; 22 | numPoints++; 23 | } 24 | double invNumPoints = (1.0) / numPoints; 25 | Origin *= invNumPoints; 26 | 27 | // Compute the covariance matrix of the points. 28 | double sumXX = (double)0, sumXY = (double)0, sumXZ = (double)0; 29 | double sumYY = (double)0, sumYZ = (double)0, sumZZ = (double)0; 30 | foreach (Vector3d p in points) { 31 | Vector3d diff = p - Origin; 32 | sumXX += diff[0] * diff[0]; 33 | sumXY += diff[0] * diff[1]; 34 | sumXZ += diff[0] * diff[2]; 35 | sumYY += diff[1] * diff[1]; 36 | sumYZ += diff[1] * diff[2]; 37 | sumZZ += diff[2] * diff[2]; 38 | } 39 | 40 | sumXX *= invNumPoints; 41 | sumXY *= invNumPoints; 42 | sumXZ *= invNumPoints; 43 | sumYY *= invNumPoints; 44 | sumYZ *= invNumPoints; 45 | sumZZ *= invNumPoints; 46 | 47 | double[] matrix = new double[] { 48 | sumXX, sumXY, sumXZ, 49 | sumXY, sumYY, sumYZ, 50 | sumXZ, sumYZ, sumZZ 51 | }; 52 | 53 | // Setup the eigensolver. 54 | SymmetricEigenSolver solver = new SymmetricEigenSolver(3, 4096); 55 | int iters = solver.Solve(matrix, SymmetricEigenSolver.SortType.Decreasing); 56 | ResultValid = (iters > 0 && iters < SymmetricEigenSolver.NO_CONVERGENCE); 57 | 58 | Normal = new Vector3d(solver.GetEigenvector(2)); 59 | } 60 | 61 | 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /geometry3Sharp/appveyor.yml: -------------------------------------------------------------------------------- 1 | version: '1.0.{build}' 2 | image: Visual Studio 2017 3 | 4 | #patch version in csproj file 5 | dotnet_csproj: 6 | patch: true 7 | file: '**\*.csproj' 8 | version: '{version}' 9 | package_version: '{version}' 10 | assembly_version: '{version}' 11 | file_version: '{version}' 12 | informational_version: '{version}' 13 | 14 | build_script: 15 | - cmd: >- 16 | dotnet restore geometry3Sharp_netstandard.csproj 17 | 18 | dotnet build geometry3Sharp_netstandard.csproj -c Release 19 | 20 | dotnet pack geometry3Sharp_netstandard.csproj -c Release 21 | test: off 22 | artifacts: 23 | - path: bin\Release\*.nupkg 24 | deploy: 25 | provider: NuGet 26 | # server: # remove to push to NuGet.org 27 | api_key: 28 | secure: NwCvdkjy/Jpu+Cev4PeXnCdyEtf5F5O4bDtBoXisEKkez6R+U5Wk12hdHNa1NTFT 29 | on: 30 | appveyor_repo_tag: true 31 | skip_symbols: false 32 | symbol_server: # remove to push symbols to SymbolSource.org 33 | artifact: /.*\.nupkg/ -------------------------------------------------------------------------------- /geometry3Sharp/color/ColorMap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace g3 5 | { 6 | public class ColorMap 7 | { 8 | struct ColorPoint 9 | { 10 | public float t; 11 | public Colorf c; 12 | } 13 | 14 | List points = new List(); 15 | Interval1d validRange; 16 | 17 | public ColorMap() 18 | { 19 | validRange = Interval1d.Empty; 20 | } 21 | 22 | public ColorMap(float[] t, Colorf[] c) 23 | { 24 | validRange = Interval1d.Empty; 25 | for (int i = 0; i < t.Length; ++i) 26 | AddPoint(t[i], c[i]); 27 | } 28 | 29 | public void AddPoint(float t, Colorf c) 30 | { 31 | ColorPoint cp = new ColorPoint() { t = t, c = c }; 32 | if ( points.Count == 0 ) { 33 | points.Add(cp); 34 | validRange.Contain(t); 35 | } else if ( t < points[0].t ) { 36 | points.Insert(0, cp); 37 | validRange.Contain(t); 38 | } else { 39 | for ( int k = 0; k < points.Count; ++k ) { 40 | if ( points[k].t == t ) { 41 | points[k] = cp; 42 | return; 43 | } else if ( points[k].t > t ) { 44 | points.Insert(k, cp); 45 | return; 46 | } 47 | } 48 | points.Add(cp); 49 | validRange.Contain(t); 50 | } 51 | } 52 | 53 | 54 | 55 | 56 | public Colorf Linear(float t) 57 | { 58 | if (t <= points[0].t) 59 | return points[0].c; 60 | int N = points.Count; 61 | if (t >= points[N - 1].t) 62 | return points[N - 1].c; 63 | for ( int k = 1; k < points.Count; ++k ) { 64 | if ( points[k].t > t ) { 65 | ColorPoint prev = points[k - 1], next = points[k]; 66 | float a = (t - prev.t) / (next.t - prev.t); 67 | return (1.0f - a) * prev.c + (a) * next.c; 68 | } 69 | } 70 | return points[N - 1].c; // should never get here... 71 | } 72 | 73 | 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /geometry3Sharp/color/ColorMixer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | 5 | namespace g3 6 | { 7 | public static class ColorMixer 8 | { 9 | 10 | public static Colorf Lighten(Colorf baseColor, float fValueMult = 1.25f) 11 | { 12 | ColorHSV baseHSV = new ColorHSV(baseColor); 13 | baseHSV.v = MathUtil.Clamp(baseHSV.v * fValueMult, 0.0f, 1.0f); 14 | return baseHSV.ConvertToRGB(); 15 | } 16 | 17 | public static Colorf Darken(Colorf baseColor, float fValueMult = 0.75f) 18 | { 19 | ColorHSV baseHSV = new ColorHSV(baseColor); 20 | baseHSV.v *= fValueMult; 21 | return baseHSV.ConvertToRGB(); 22 | } 23 | 24 | 25 | public static Colorf CopyHue(Colorf BaseColor, Colorf TakeHue, float fBlendAlpha) 26 | { 27 | ColorHSV baseHSV = new ColorHSV(BaseColor); 28 | ColorHSV takeHSV = new ColorHSV(TakeHue); 29 | baseHSV.h = takeHSV.h; 30 | baseHSV.s = MathUtil.Lerp(baseHSV.s, takeHSV.s, fBlendAlpha); 31 | baseHSV.v = MathUtil.Lerp(baseHSV.v, takeHSV.v, fBlendAlpha); 32 | return baseHSV.ConvertToRGB(); 33 | } 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /geometry3Sharp/color/Colorb.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | #if G3_USING_UNITY 4 | using UnityEngine; 5 | #endif 6 | 7 | namespace g3 8 | { 9 | public struct Colorb 10 | { 11 | public byte r; 12 | public byte g; 13 | public byte b; 14 | public byte a; 15 | 16 | public Colorb(byte greylevel, byte a = 1) { r = g = b = greylevel; this.a = a; } 17 | public Colorb(byte r, byte g, byte b, byte a = 1) { this.r = r; this.g = g; this.b = b; this.a = a; } 18 | public Colorb(float r, float g, float b, float a = 1.0f) { 19 | this.r = (byte)MathUtil.Clamp((int)(r * 255.0f), 0, 255); 20 | this.g = (byte)MathUtil.Clamp((int)(g * 255.0f), 0, 255); 21 | this.b = (byte)MathUtil.Clamp((int)(b * 255.0f), 0, 255); 22 | this.a = (byte)MathUtil.Clamp((int)(a * 255.0f), 0, 255); 23 | } 24 | public Colorb(byte[] v2) { r = v2[0]; g = v2[1]; b = v2[2]; a = v2[3]; } 25 | public Colorb(Colorb copy) { r = copy.r; g = copy.g; b = copy.b; a = copy.a; } 26 | public Colorb(Colorb copy, byte newAlpha) { r = copy.r; g = copy.g; b = copy.b; a = newAlpha; } 27 | 28 | 29 | public byte this[int key] 30 | { 31 | get { if (key == 0) return r; else if (key == 1) return g; else if (key == 2) return b; else return a; } 32 | set { if (key == 0) r = value; else if (key == 1) g = value; else if (key == 2) b = value; else a = value; } 33 | } 34 | 35 | 36 | #if G3_USING_UNITY 37 | public static implicit operator Colorb(UnityEngine.Color32 c) 38 | { 39 | return new Colorb(c.r, c.g, c.b, c.a); 40 | } 41 | public static implicit operator Color32(Colorb c) 42 | { 43 | return new Color32(c.r, c.g, c.b, c.a); 44 | } 45 | #endif 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /geometry3Sharp/containment/ContBox3.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace g3 8 | { 9 | 10 | // ported from GTEngine GteContOrientedBox3.h 11 | // (2017) url: https://www.geometrictools.com/GTEngine/Include/Mathematics/GteContOrientedBox3.h 12 | public class ContOrientedBox3 13 | { 14 | public Box3d Box; 15 | public bool ResultValid = false; 16 | 17 | public ContOrientedBox3(IEnumerable points) 18 | { 19 | // Fit the points with a Gaussian distribution. 20 | GaussPointsFit3 fitter = new GaussPointsFit3(points); 21 | if (fitter.ResultValid == false) 22 | return; 23 | this.Box = fitter.Box; 24 | this.Box.Contain(points); 25 | } 26 | 27 | public ContOrientedBox3(IEnumerable points, IEnumerable pointWeights) 28 | { 29 | // Fit the points with a Gaussian distribution. 30 | GaussPointsFit3 fitter = new GaussPointsFit3(points, pointWeights); 31 | if (fitter.ResultValid == false) 32 | return; 33 | this.Box = fitter.Box; 34 | this.Box.Contain(points); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /geometry3Sharp/core/DeepCopy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace g3 6 | { 7 | 8 | /// 9 | /// Collection of utility functions for one-line deep copies of lists 10 | /// 11 | public static class DeepCopy 12 | { 13 | 14 | public static List List(IEnumerable Input) where T: IDuplicatable { 15 | List result = new List(); 16 | foreach ( T val in Input ) { 17 | result.Add(val.Duplicate()); 18 | } 19 | return result; 20 | } 21 | 22 | 23 | public static T[] Array(IEnumerable Input) where T: IDuplicatable { 24 | int count = Input.Count(); 25 | T[] a = new T[count]; 26 | int i = 0; 27 | foreach (T val in Input) 28 | a[i++] = val.Duplicate(); 29 | return a; 30 | } 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /geometry3Sharp/core/FileSystemUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.IO; 4 | 5 | namespace g3 6 | { 7 | public static class FileSystemUtils 8 | { 9 | static public bool CanAccessFolder(string sPath) 10 | { 11 | try { 12 | Directory.GetDirectories(sPath); 13 | } catch (Exception) { 14 | return false; 15 | } 16 | return true; 17 | } 18 | 19 | 20 | static public bool IsValidFilenameCharacter(char c) 21 | { 22 | return Path.GetInvalidPathChars().Contains(c) == false; 23 | } 24 | static public bool IsValidFilenameString(string s) 25 | { 26 | for (int i = 0; i < s.Length; ++i) 27 | if (Path.GetInvalidPathChars().Contains(s[i])) 28 | return false; 29 | return true; 30 | } 31 | 32 | 33 | static public bool IsWebURL(string s) 34 | { 35 | Uri uriResult; 36 | bool bResult = Uri.TryCreate(s, UriKind.Absolute, out uriResult) 37 | && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps); 38 | return bResult; 39 | } 40 | 41 | static public bool IsFullFilesystemPath(string s) 42 | { 43 | return Path.IsPathRooted(s); 44 | } 45 | 46 | 47 | public static string GetTempFilePathWithExtension(string extension) 48 | { 49 | var path = Path.GetTempPath(); 50 | var fileName = Guid.NewGuid().ToString() + extension; 51 | return Path.Combine(path, fileName); 52 | } 53 | 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /geometry3Sharp/core/MemoryPool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace g3 5 | { 6 | /// 7 | /// Very basic object pool class. 8 | /// 9 | public class MemoryPool where T : class, new() 10 | { 11 | DVector Allocated; 12 | DVector Free; 13 | 14 | public MemoryPool() 15 | { 16 | Allocated = new DVector(); 17 | Free = new DVector(); 18 | } 19 | 20 | public T Allocate() 21 | { 22 | if ( Free.size > 0 ) { 23 | T allocated = Free[Free.size - 1]; 24 | Free.pop_back(); 25 | return allocated; 26 | } else { 27 | T newval = new T(); 28 | Allocated.Add(newval); 29 | return newval; 30 | } 31 | } 32 | 33 | public void Return(T obj) { 34 | Free.Add(obj); 35 | } 36 | 37 | 38 | public void ReturnAll() 39 | { 40 | Free = new DVector(Allocated); 41 | } 42 | 43 | 44 | public void FreeAll() 45 | { 46 | Allocated = new DVector(); 47 | Free = new DVector(); 48 | } 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /geometry3Sharp/core/ProgressCancel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace g3 4 | { 5 | /// 6 | /// interface that provides a cancel function 7 | /// 8 | public interface ICancelSource 9 | { 10 | bool Cancelled(); 11 | } 12 | 13 | 14 | /// 15 | /// Just wraps a func as an ICancelSource 16 | /// 17 | public class CancelFunction : ICancelSource 18 | { 19 | public Func CancelF; 20 | public CancelFunction(Func cancelF) { 21 | CancelF = cancelF; 22 | } 23 | public bool Cancelled() { return CancelF(); } 24 | } 25 | 26 | 27 | /// 28 | /// This class is intended to be passed to long-running computes to 29 | /// 1) provide progress info back to caller (not implemented yet) 30 | /// 2) allow caller to cancel the computation 31 | /// 32 | public class ProgressCancel 33 | { 34 | public ICancelSource Source; 35 | 36 | bool WasCancelled = false; // will be set to true if CancelF() ever returns true 37 | 38 | public ProgressCancel(ICancelSource source) 39 | { 40 | Source = source; 41 | } 42 | public ProgressCancel(Func cancelF) 43 | { 44 | Source = new CancelFunction(cancelF); 45 | } 46 | 47 | /// 48 | /// Check if client would like to cancel 49 | /// 50 | public bool Cancelled() 51 | { 52 | if (WasCancelled) 53 | return true; 54 | WasCancelled = Source.Cancelled(); 55 | return WasCancelled; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /geometry3Sharp/core/SafeCollections.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | 7 | namespace g3 8 | { 9 | 10 | /// 11 | /// A simple wrapper around a List that supports multi-threaded construction. 12 | /// Basically intended for use within things like a Parallel.ForEach 13 | /// 14 | public class SafeListBuilder 15 | { 16 | public List List; 17 | public SpinLock spinlock; 18 | 19 | public SafeListBuilder() 20 | { 21 | List = new List(); 22 | spinlock = new SpinLock(); 23 | } 24 | 25 | public void SafeAdd(T value) 26 | { 27 | bool lockTaken = false; 28 | while (lockTaken == false) 29 | spinlock.Enter(ref lockTaken); 30 | 31 | List.Add(value); 32 | 33 | spinlock.Exit(); 34 | } 35 | 36 | 37 | public void SafeOperation(Action> opF) 38 | { 39 | bool lockTaken = false; 40 | while (lockTaken == false) 41 | spinlock.Enter(ref lockTaken); 42 | 43 | opF(List); 44 | 45 | spinlock.Exit(); 46 | } 47 | 48 | 49 | public List Result { 50 | get { return List; } 51 | } 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /geometry3Sharp/core/Snapping.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace g3 4 | { 5 | public class Snapping 6 | { 7 | 8 | public static double SnapToIncrement(double fValue, double fIncrement) 9 | { 10 | if (!MathUtil.IsFinite(fValue)) 11 | return 0; 12 | double sign = Math.Sign(fValue); 13 | fValue = Math.Abs(fValue); 14 | int nInc = (int)(fValue / fIncrement); 15 | double fRem = fValue % fIncrement; 16 | if (fRem > fIncrement / 2) 17 | ++nInc; 18 | return sign * (double)nInc * fIncrement; 19 | } 20 | 21 | 22 | 23 | 24 | public static double SnapToNearbyIncrement(double fValue, double fIncrement, double fTolerance) 25 | { 26 | double snapped = SnapToIncrement(fValue, fIncrement); 27 | if (Math.Abs(snapped - fValue) < fTolerance) 28 | return snapped; 29 | return fValue; 30 | } 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /geometry3Sharp/core/TagSet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace g3 5 | { 6 | 7 | /// 8 | /// Basic object->integer mapping 9 | /// 10 | public class IntTagSet 11 | { 12 | public const int InvalidTag = int.MaxValue; 13 | 14 | public IntTagSet() 15 | { 16 | } 17 | 18 | 19 | Dictionary tags; 20 | void create() { 21 | if (tags == null) 22 | tags = new Dictionary(); 23 | } 24 | 25 | public void Add(T reference, int tag) { 26 | create(); 27 | tags.Add(reference, tag); 28 | } 29 | public bool Has(T reference) 30 | { 31 | int tag = 0; 32 | if (tags != null && tags.TryGetValue(reference, out tag)) 33 | return true; 34 | return false; 35 | } 36 | public int Get(T reference) 37 | { 38 | int tag = 0; 39 | if (tags != null && tags.TryGetValue(reference, out tag)) 40 | return tag; 41 | return InvalidTag; 42 | } 43 | } 44 | 45 | 46 | /// 47 | /// integer type/value pair, packed into 32 bits - 8 for type, 24 for value 48 | /// 49 | public struct IntTagPair 50 | { 51 | public byte type; 52 | public int value; 53 | public IntTagPair(byte type, int value) { 54 | Util.gDevAssert(value < 1 << 24); 55 | this.type = type; 56 | this.value = value; 57 | } 58 | public IntTagPair(int combined) 59 | { 60 | type = (byte)(combined >> 24); 61 | value = combined & 0xFFFFFF; 62 | } 63 | public int intValue { get { return ((int)type) << 24 | value; } } 64 | } 65 | 66 | 67 | 68 | 69 | /// 70 | /// Basic object->string mapping 71 | /// 72 | public class StringTagSet 73 | { 74 | public const string InvalidTag = ""; 75 | 76 | public StringTagSet() 77 | { 78 | } 79 | 80 | 81 | Dictionary tags; 82 | void create() { 83 | if (tags == null) 84 | tags = new Dictionary(); 85 | } 86 | 87 | public void Add(T reference, string tag) { 88 | create(); 89 | tags.Add(reference, tag); 90 | } 91 | public bool Has(T reference) 92 | { 93 | string tag = InvalidTag; 94 | if (tags != null && tags.TryGetValue(reference, out tag)) 95 | return true; 96 | return false; 97 | } 98 | public string Get(T reference) 99 | { 100 | string tag = InvalidTag; 101 | if (tags != null && tags.TryGetValue(reference, out tag)) 102 | return tag; 103 | return InvalidTag; 104 | } 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /geometry3Sharp/core/g3Interfaces.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace g3 4 | { 5 | 6 | /// 7 | /// Deep-copy cloning interface. Duplicate() *must* return 8 | /// a full deep copy of object, including all internal data structures. 9 | /// 10 | public interface IDuplicatable 11 | { 12 | T Duplicate(); 13 | } 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /geometry3Sharp/curve/CurveGenerators.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace g3 7 | { 8 | abstract public class CurveGenerator 9 | { 10 | public VectorArray3d vertices; 11 | public bool closed = false; 12 | 13 | abstract public void Generate(); 14 | 15 | public void Make(DCurve3 c) { 16 | int nV = vertices.Count; 17 | for (int i = 0; i < nV; ++i) { 18 | c.AppendVertex(vertices[i]); 19 | } 20 | c.Closed = closed; 21 | } 22 | } 23 | 24 | 25 | 26 | public class LineGenerator : CurveGenerator 27 | { 28 | public Vector3d Start = Vector3d.Zero; 29 | public Vector3d End = Vector3d.AxisX; 30 | 31 | // must set one of these, otherwise we use default 32 | public int Subdivisions = -1; 33 | public double StepSize = 0.0; 34 | 35 | 36 | public override void Generate() 37 | { 38 | double fLen = (Start - End).Length; 39 | 40 | int nSteps = 10; 41 | if (Subdivisions > 0) 42 | nSteps = Subdivisions; 43 | else if (StepSize > 0) 44 | nSteps = (int)MathUtil.Clamp( (int)(fLen / StepSize), 2, 10000); 45 | 46 | vertices = new VectorArray3d(nSteps+1); 47 | 48 | for ( int i = 0; i < nSteps; ++i ) { 49 | double t = (double)i / (double)nSteps; 50 | Vector3d v = (1.0 - t) * Start + (t) * End; 51 | vertices[i] = (v); 52 | } 53 | vertices[nSteps] = End; 54 | 55 | closed = false; 56 | } 57 | 58 | } 59 | 60 | } -------------------------------------------------------------------------------- /geometry3Sharp/curve/ICurve.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace g3 8 | { 9 | 10 | public interface IParametricCurve3d 11 | { 12 | bool IsClosed {get;} 13 | 14 | // can call SampleT in range [0,ParamLength] 15 | double ParamLength {get;} 16 | Vector3d SampleT(double t); 17 | Vector3d TangentT(double t); // returns normalized vector 18 | 19 | bool HasArcLength {get;} 20 | double ArcLength {get;} 21 | Vector3d SampleArcLength(double a); 22 | 23 | void Reverse(); 24 | 25 | IParametricCurve3d Clone(); 26 | } 27 | 28 | 29 | 30 | 31 | public interface ISampledCurve3d 32 | { 33 | int VertexCount { get; } 34 | int SegmentCount { get; } 35 | bool Closed { get; } 36 | 37 | Vector3d GetVertex(int i); 38 | Segment3d GetSegment(int i); 39 | 40 | IEnumerable Vertices { get; } 41 | } 42 | 43 | 44 | 45 | 46 | 47 | public interface IParametricCurve2d 48 | { 49 | bool IsClosed {get;} 50 | 51 | // can call SampleT in range [0,ParamLength] 52 | double ParamLength {get;} 53 | Vector2d SampleT(double t); 54 | Vector2d TangentT(double t); // returns normalized vector 55 | 56 | bool HasArcLength {get;} 57 | double ArcLength {get;} 58 | Vector2d SampleArcLength(double a); 59 | 60 | void Reverse(); 61 | 62 | bool IsTransformable { get; } 63 | void Transform(ITransform2 xform); 64 | 65 | IParametricCurve2d Clone(); 66 | } 67 | 68 | 69 | public interface IMultiCurve2d 70 | { 71 | ReadOnlyCollection Curves { get; } 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /geometry3Sharp/curve/PolyLine3d.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Collections.ObjectModel; 5 | 6 | namespace g3 7 | { 8 | public class PolyLine3d : IEnumerable 9 | { 10 | protected List vertices; 11 | public int Timestamp; 12 | 13 | public PolyLine3d() { 14 | vertices = new List(); 15 | Timestamp = 0; 16 | } 17 | 18 | public PolyLine3d(PolyLine3d copy) 19 | { 20 | vertices = new List(copy.vertices); 21 | Timestamp = 0; 22 | } 23 | 24 | public PolyLine3d(Vector3d[] v) 25 | { 26 | vertices = new List(v); 27 | Timestamp = 0; 28 | } 29 | public PolyLine3d(VectorArray3d v) 30 | { 31 | vertices = new List(v.AsVector3d()); 32 | Timestamp = 0; 33 | } 34 | 35 | 36 | public Vector3d this[int key] 37 | { 38 | get { return vertices[key]; } 39 | set { vertices[key] = value; Timestamp++; } 40 | } 41 | 42 | public Vector3d Start { 43 | get { return vertices[0]; } 44 | } 45 | public Vector3d End { 46 | get { return vertices[vertices.Count-1]; } 47 | } 48 | 49 | 50 | public ReadOnlyCollection Vertices { 51 | get { return vertices.AsReadOnly(); } 52 | } 53 | 54 | public int VertexCount 55 | { 56 | get { return vertices.Count; } 57 | } 58 | 59 | public void AppendVertex(Vector3d v) 60 | { 61 | vertices.Add(v); 62 | Timestamp++; 63 | } 64 | 65 | 66 | public Vector3d GetTangent(int i) 67 | { 68 | if (i == 0) 69 | return (vertices[1] - vertices[0]).Normalized; 70 | else if (i == vertices.Count - 1) 71 | return (vertices[vertices.Count - 1] - vertices[vertices.Count - 2]).Normalized; 72 | else 73 | return (vertices[i + 1] - vertices[i - 1]).Normalized; 74 | } 75 | 76 | 77 | public AxisAlignedBox3d GetBounds() { 78 | if ( vertices.Count == 0 ) 79 | return AxisAlignedBox3d.Empty; 80 | AxisAlignedBox3d box = new AxisAlignedBox3d(vertices[0]); 81 | for ( int i = 1; i < vertices.Count; ++i ) 82 | box.Contain(vertices[i]); 83 | return box; 84 | } 85 | 86 | 87 | public IEnumerable SegmentItr() { 88 | for ( int i = 0; i < vertices.Count-1; ++i ) 89 | yield return new Segment3d( vertices[i], vertices[i+1] ); 90 | } 91 | 92 | public IEnumerator GetEnumerator() { 93 | return vertices.GetEnumerator(); 94 | } 95 | IEnumerator IEnumerable.GetEnumerator() { 96 | return vertices.GetEnumerator(); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /geometry3Sharp/distance/DistLine2Line2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace g3 7 | { 8 | // ported from WildMagic 5 9 | // https://www.geometrictools.com/Downloads/Downloads.html 10 | 11 | public class DistLine2Line2 12 | { 13 | Line2d line1; 14 | public Line2d Line 15 | { 16 | get { return line1; } 17 | set { line1 = value; DistanceSquared = -1.0; } 18 | } 19 | 20 | Line2d line2; 21 | public Line2d Line2 22 | { 23 | get { return line2; } 24 | set { line2 = value; DistanceSquared = -1.0; } 25 | } 26 | 27 | public double DistanceSquared = -1.0; 28 | 29 | public Vector2d Line1Closest; 30 | public Vector2d Line2Closest; 31 | public double Line1Parameter; 32 | public double Line2Parameter; 33 | 34 | 35 | public DistLine2Line2( Line2d Line1, Line2d Line2) 36 | { 37 | this.line2 = Line2; this.line1 = Line1; 38 | } 39 | 40 | static public double MinDistance(Line2d line1, Line2d line2) 41 | { 42 | return new DistLine2Line2( line1, line2 ).Get(); 43 | } 44 | 45 | 46 | public DistLine2Line2 Compute() 47 | { 48 | GetSquared(); 49 | return this; 50 | } 51 | 52 | public double Get() 53 | { 54 | return Math.Sqrt( GetSquared() ); 55 | } 56 | 57 | 58 | public double GetSquared() 59 | { 60 | if (DistanceSquared >= 0) 61 | return DistanceSquared; 62 | 63 | Vector2d diff = line1.Origin - line2.Origin; 64 | double a01 = -line1.Direction.Dot(line2.Direction); 65 | double b0 = diff.Dot(line1.Direction); 66 | double c = diff.LengthSquared; 67 | double det = Math.Abs(1.0 - a01*a01); 68 | double b1, s0, s1, sqrDist; 69 | 70 | if (det >= MathUtil.ZeroTolerance) 71 | { 72 | // Lines are not parallel. 73 | b1 = -diff.Dot(line2.Direction); 74 | double invDet = ((double)1)/det; 75 | s0 = (a01*b1 - b0)*invDet; 76 | s1 = (a01*b0 - b1)*invDet; 77 | sqrDist = (double)0; 78 | } 79 | else 80 | { 81 | // Lines are parallel, select any closest pair of points. 82 | s0 = -b0; 83 | s1 = (double)0; 84 | sqrDist = b0*s0 + c; 85 | 86 | // Account for numerical round-off errors. 87 | if (sqrDist < (double)0) 88 | sqrDist = (double)0; 89 | } 90 | 91 | Line1Parameter = s0; 92 | Line1Closest = line1.Origin + s0*line1.Direction; 93 | Line2Parameter = s1; 94 | Line2Closest = line2.Origin + s1*line2.Direction; 95 | 96 | DistanceSquared = sqrDist; 97 | return sqrDist; 98 | } 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /geometry3Sharp/distance/DistPoint2Box2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace g3 7 | { 8 | // ported from WildMagic 5's DistPoint2Box2 9 | // https://www.geometrictools.com/Downloads/Downloads.html 10 | 11 | public class DistPoint2Box2 12 | { 13 | Vector2d point; 14 | public Vector2d Point 15 | { 16 | get { return point; } 17 | set { point = value; DistanceSquared = -1.0; } 18 | } 19 | 20 | Box2d box; 21 | public Box2d Box 22 | { 23 | get { return box; } 24 | set { box = value; DistanceSquared = -1.0; } 25 | } 26 | 27 | public double DistanceSquared = -1.0; 28 | 29 | public Vector2d BoxClosest; 30 | 31 | 32 | public DistPoint2Box2(Vector2d PointIn, Box2d boxIn ) 33 | { 34 | point = PointIn; box = boxIn; 35 | } 36 | 37 | public DistPoint2Box2 Compute() 38 | { 39 | GetSquared(); 40 | return this; 41 | } 42 | 43 | public double Get() 44 | { 45 | return Math.Sqrt(GetSquared()); 46 | } 47 | 48 | 49 | public double GetSquared() 50 | { 51 | if (DistanceSquared >= 0) 52 | return DistanceSquared; 53 | 54 | // Work in the box's coordinate system. 55 | Vector2d diff = point - box.Center; 56 | 57 | // Compute squared distance and closest point on box. 58 | double sqrDistance = (double)0; 59 | double delta; 60 | Vector2d closest = Vector2d.Zero; 61 | int i; 62 | for (i = 0; i < 2; ++i) { 63 | closest[i] = diff.Dot(box.Axis(i)); 64 | if (closest[i] < -box.Extent[i]) { 65 | delta = closest[i] + box.Extent[i]; 66 | sqrDistance += delta * delta; 67 | closest[i] = -box.Extent[i]; 68 | } else if (closest[i] > box.Extent[i]) { 69 | delta = closest[i] - box.Extent[i]; 70 | sqrDistance += delta * delta; 71 | closest[i] = box.Extent[i]; 72 | } 73 | } 74 | 75 | BoxClosest = box.Center; 76 | for (i = 0; i < 2; ++i) { 77 | BoxClosest += closest[i] * box.Axis(i); 78 | } 79 | 80 | DistanceSquared = sqrDistance; 81 | return sqrDistance; 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /geometry3Sharp/distance/DistPoint2Circle2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace g3 7 | { 8 | // ported from WildMagic 5's DistPoint3Circle3 (didn't have point2circle2) 9 | // https://www.geometrictools.com/Downloads/Downloads.html 10 | 11 | public class DistPoint2Circle2 12 | { 13 | Vector2d point; 14 | public Vector2d Point 15 | { 16 | get { return point; } 17 | set { point = value; DistanceSquared = -1.0; } 18 | } 19 | 20 | Circle2d circle; 21 | public Circle2d Circle 22 | { 23 | get { return circle; } 24 | set { circle = value; DistanceSquared = -1.0; } 25 | } 26 | 27 | public double DistanceSquared = -1.0; 28 | 29 | public Vector2d CircleClosest; 30 | public bool AllCirclePointsEquidistant; 31 | 32 | 33 | public DistPoint2Circle2(Vector2d PointIn, Circle2d circleIn ) 34 | { 35 | point = PointIn; circle = circleIn; 36 | } 37 | 38 | public DistPoint2Circle2 Compute() 39 | { 40 | GetSquared(); 41 | return this; 42 | } 43 | 44 | public double Get() 45 | { 46 | return Math.Sqrt(GetSquared()); 47 | } 48 | 49 | 50 | public double GetSquared() 51 | { 52 | if (DistanceSquared >= 0) 53 | return DistanceSquared; 54 | 55 | // Projection of P-C onto plane is Q-C = P-C - Dot(N,P-C)*N. 56 | Vector2d PmC = point - circle.Center; 57 | double lengthPmC = PmC.Length; 58 | if (lengthPmC > MathUtil.Epsilon) { 59 | CircleClosest = circle.Center + circle.Radius * PmC / lengthPmC; 60 | AllCirclePointsEquidistant = false; 61 | } else { 62 | // All circle points are equidistant from P. Return one of them. 63 | CircleClosest = circle.Center + circle.Radius; 64 | AllCirclePointsEquidistant = true; 65 | } 66 | 67 | Vector2d diff = point - CircleClosest; 68 | double sqrDistance = diff.Dot(diff); 69 | 70 | // Account for numerical round-off error. 71 | if (sqrDistance < 0) { 72 | sqrDistance = 0; 73 | } 74 | DistanceSquared = sqrDistance; 75 | return sqrDistance; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /geometry3Sharp/distance/DistPoint3Circle3.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace g3 7 | { 8 | // ported from WildMagic 5 9 | // https://www.geometrictools.com/Downloads/Downloads.html 10 | 11 | public class DistPoint3Circle3 12 | { 13 | Vector3d point; 14 | public Vector3d Point 15 | { 16 | get { return point; } 17 | set { point = value; DistanceSquared = -1.0; } 18 | } 19 | 20 | Circle3d circle; 21 | public Circle3d Circle 22 | { 23 | get { return circle; } 24 | set { circle = value; DistanceSquared = -1.0; } 25 | } 26 | 27 | public double DistanceSquared = -1.0; 28 | 29 | public Vector3d CircleClosest; 30 | public bool AllCirclePointsEquidistant; 31 | 32 | 33 | public DistPoint3Circle3(Vector3d PointIn, Circle3d circleIn ) 34 | { 35 | point = PointIn; circle = circleIn; 36 | } 37 | 38 | public DistPoint3Circle3 Compute() 39 | { 40 | GetSquared(); 41 | return this; 42 | } 43 | 44 | public double Get() 45 | { 46 | return Math.Sqrt(GetSquared()); 47 | } 48 | 49 | 50 | public double GetSquared() 51 | { 52 | if (DistanceSquared >= 0) 53 | return DistanceSquared; 54 | 55 | // Projection of P-C onto plane is Q-C = P-C - Dot(N,P-C)*N. 56 | Vector3d PmC = point - circle.Center; 57 | Vector3d QmC = PmC - circle.Normal.Dot(PmC) * circle.Normal; 58 | double lengthQmC = QmC.Length; 59 | if (lengthQmC > MathUtil.Epsilon) { 60 | CircleClosest = circle.Center + circle.Radius * QmC / lengthQmC; 61 | AllCirclePointsEquidistant = false; 62 | } else { 63 | // All circle points are equidistant from P. Return one of them. 64 | CircleClosest = circle.Center + circle.Radius * circle.PlaneX; 65 | AllCirclePointsEquidistant = true; 66 | } 67 | 68 | Vector3d diff = point - CircleClosest; 69 | double sqrDistance = diff.Dot(diff); 70 | 71 | // Account for numerical round-off error. 72 | if (sqrDistance < 0) { 73 | sqrDistance = 0; 74 | } 75 | DistanceSquared = sqrDistance; 76 | return sqrDistance; 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /geometry3Sharp/distance/DistSegment3Triangle3.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace g3 7 | { 8 | // ported from WildMagic 5 9 | // https://www.geometrictools.com/Downloads/Downloads.html 10 | 11 | public class DistSegment3Triangle3 12 | { 13 | Segment3d segment; 14 | public Segment3d Segment 15 | { 16 | get { return segment; } 17 | set { segment = value; DistanceSquared = -1.0; } 18 | } 19 | 20 | Triangle3d triangle; 21 | public Triangle3d Triangle 22 | { 23 | get { return triangle; } 24 | set { triangle = value; DistanceSquared = -1.0; } 25 | } 26 | 27 | public double DistanceSquared = -1.0; 28 | 29 | public Vector3d SegmentClosest; 30 | public double SegmentParam; 31 | public Vector3d TriangleClosest; 32 | public Vector3d TriangleBaryCoords; 33 | 34 | public DistSegment3Triangle3(Segment3d SegmentIn, Triangle3d TriangleIn) 35 | { 36 | this.triangle = TriangleIn; this.segment = SegmentIn; 37 | } 38 | 39 | 40 | public DistSegment3Triangle3 Compute() 41 | { 42 | GetSquared(); 43 | return this; 44 | } 45 | 46 | public double Get() 47 | { 48 | return Math.Sqrt(GetSquared()); 49 | } 50 | 51 | 52 | public double GetSquared() 53 | { 54 | if (DistanceSquared >= 0) 55 | return DistanceSquared; 56 | Line3d line = new Line3d(segment.Center, segment.Direction); 57 | DistLine3Triangle3 queryLT = new DistLine3Triangle3(line, triangle); 58 | double sqrDist = queryLT.GetSquared(); 59 | SegmentParam = queryLT.LineParam; 60 | 61 | if (SegmentParam >= -segment.Extent) { 62 | if (SegmentParam <= segment.Extent) { 63 | SegmentClosest = queryLT.LineClosest; 64 | TriangleClosest = queryLT.TriangleClosest; 65 | TriangleBaryCoords = queryLT.TriangleBaryCoords; 66 | } else { 67 | SegmentClosest = segment.P1; 68 | DistPoint3Triangle3 queryPT = new DistPoint3Triangle3(SegmentClosest, triangle); 69 | sqrDist = queryPT.GetSquared(); 70 | TriangleClosest = queryPT.TriangleClosest; 71 | SegmentParam = segment.Extent; 72 | TriangleBaryCoords = queryPT.TriangleBaryCoords; 73 | } 74 | } else { 75 | SegmentClosest = segment.P0; 76 | DistPoint3Triangle3 queryPT = new DistPoint3Triangle3(SegmentClosest, triangle); 77 | sqrDist = queryPT.GetSquared(); 78 | TriangleClosest = queryPT.TriangleClosest; 79 | SegmentParam = -segment.Extent; 80 | TriangleBaryCoords = queryPT.TriangleBaryCoords; 81 | } 82 | 83 | DistanceSquared = sqrDist; 84 | return DistanceSquared; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /geometry3Sharp/distance/Distance.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace g3 7 | { 8 | // [TODO] get rid of this!! 9 | public static class Distance 10 | { 11 | public static float ClosestPointOnLineT(Vector3f p0, Vector3f dir, Vector3f pt) 12 | { 13 | float t = (pt - p0).Dot(dir); 14 | return t; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /geometry3Sharp/geometry3Sharp.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "geometry3Sharp", 3 | "references": [], 4 | "optionalUnityReferences": [], 5 | "includePlatforms": [], 6 | "excludePlatforms": [], 7 | "allowUnsafeCode": true 8 | } -------------------------------------------------------------------------------- /geometry3Sharp/geometry3Sharp_netstandard.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 1.0.0.0 5 | geometry3Sharp 6 | Ryan Schmidt 7 | gradientspace 8 | C# library for 2D/3D geometric computing and triangle mesh processing 9 | Copyright © Ryan Schmidt 2016 10 | https://github.com/gradientspace/geometry3Sharp/blob/master/LICENSE 11 | https://github.com/gradientspace/geometry3Sharp 12 | geometry3;graphics;math;approximation;solvers;color;convexhull;meshes;spatial;curves;solids;3d;unity 13 | https://github.com/gradientspace/geometry3Sharp 14 | git 15 | 16 | 17 | 18 | netstandard2.0;net45 19 | Library 20 | False 21 | g3 22 | geometry3Sharp 23 | true 24 | geometry3Sharp 25 | geometry3Sharp 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /geometry3Sharp/implicit/Implicit2d.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace g3 5 | { 6 | /// 7 | /// Summary description for ImplicitField2D. 8 | /// 9 | public interface ImplicitField2d 10 | { 11 | float Value( float fX, float fY ); 12 | 13 | void Gradient( float fX, float fY, ref float fGX, ref float fGY ); 14 | 15 | AxisAlignedBox2f Bounds { get; } 16 | } 17 | 18 | public interface ImplicitOperator2d : ImplicitField2d 19 | { 20 | void AddChild( ImplicitField2d field ); 21 | } 22 | 23 | 24 | 25 | 26 | public class ImplicitPoint2d : ImplicitField2d 27 | { 28 | Vector2f m_vCenter; 29 | private float m_radius; 30 | 31 | public ImplicitPoint2d( float x, float y ) { 32 | m_vCenter = new Vector2f(x, y); 33 | m_radius = 1; 34 | } 35 | public ImplicitPoint2d( float x, float y, float radius ) { 36 | m_vCenter = new Vector2f(x, y); 37 | m_radius = radius; 38 | } 39 | 40 | public float Value( float fX, float fY ) { 41 | 42 | float tx = (fX - m_vCenter.x); 43 | float ty = (fY - m_vCenter.y); 44 | float fDist2 = tx*tx + ty*ty; 45 | fDist2 /= (m_radius*m_radius); 46 | fDist2 = 1.0f - fDist2; 47 | if ( fDist2 < 0.0f) 48 | return 0.0f; 49 | else 50 | return fDist2 * fDist2 * fDist2; 51 | } 52 | 53 | public AxisAlignedBox2f Bounds { 54 | get { 55 | return new AxisAlignedBox2f(LowX, LowY, HighX, HighY); 56 | } 57 | } 58 | 59 | public void Gradient( float fX, float fY, ref float fGX, ref float fGY ) { 60 | float tx = (fX - m_vCenter.x); 61 | float ty = (fY - m_vCenter.y); 62 | float fDist2 = (tx*tx + ty*ty); 63 | float fTmp = 1.0f - fDist2; 64 | if ( fTmp < 0.0f) { 65 | fGX = fGY = 0; 66 | } else { 67 | float fSqrt = (float)Math.Sqrt(fDist2); 68 | float fGradMag = -6.0f * fSqrt * fTmp*fTmp; 69 | fGradMag /= fSqrt; 70 | fGX = tx * fGradMag; 71 | fGY = ty * fGradMag; 72 | } 73 | } 74 | 75 | public bool InBounds( float x, float y ) { 76 | return (x >= LowX && x <= HighX && x >= LowY && x <= HighY); 77 | } 78 | 79 | public float LowX { 80 | get { return m_vCenter.x - radius; } 81 | } 82 | 83 | public float LowY { 84 | get { return m_vCenter.y - radius; } 85 | } 86 | 87 | public float HighX { 88 | get { return m_vCenter.x + radius; } 89 | } 90 | 91 | public float HighY { 92 | get { return m_vCenter.y + radius; } 93 | } 94 | 95 | public float radius { 96 | get { return m_radius; } 97 | set { m_radius = value; } 98 | } 99 | 100 | public float x { 101 | get { return m_vCenter.x; } 102 | set { m_vCenter.x = value; } 103 | } 104 | 105 | public float y { 106 | get { return m_vCenter.y; } 107 | set { m_vCenter.y = value; } 108 | } 109 | 110 | public Vector2f Center { 111 | get { return m_vCenter; } 112 | set { m_vCenter = value; } 113 | } 114 | } 115 | 116 | 117 | 118 | } 119 | -------------------------------------------------------------------------------- /geometry3Sharp/implicit/ImplicitFieldSampler3d.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace g3 7 | { 8 | /// 9 | /// Sample implicit fields into a dense grid 10 | /// 11 | public class ImplicitFieldSampler3d 12 | { 13 | public DenseGrid3f Grid; 14 | public double CellSize; 15 | public Vector3d GridOrigin; 16 | public ShiftGridIndexer3 Indexer; 17 | public AxisAlignedBox3i GridBounds; 18 | 19 | public float BackgroundValue; 20 | 21 | 22 | public enum CombineModes 23 | { 24 | DistanceMinUnion = 0 25 | } 26 | public CombineModes CombineMode = CombineModes.DistanceMinUnion; 27 | 28 | 29 | public ImplicitFieldSampler3d(AxisAlignedBox3d fieldBounds, double cellSize) 30 | { 31 | CellSize = cellSize; 32 | GridOrigin = fieldBounds.Min; 33 | Indexer = new ShiftGridIndexer3(GridOrigin, CellSize); 34 | 35 | Vector3d max = fieldBounds.Max; max += cellSize; 36 | int ni = (int)((max.x - GridOrigin.x) / CellSize) + 1; 37 | int nj = (int)((max.y - GridOrigin.y) / CellSize) + 1; 38 | int nk = (int)((max.z - GridOrigin.z) / CellSize) + 1; 39 | 40 | GridBounds = new AxisAlignedBox3i(0, 0, 0, ni, nj, nk); 41 | 42 | BackgroundValue = (float)((ni + nj + nk) * CellSize); 43 | Grid = new DenseGrid3f(ni, nj, nk, BackgroundValue); 44 | } 45 | 46 | 47 | 48 | public DenseGridTrilinearImplicit ToImplicit() { 49 | return new DenseGridTrilinearImplicit(Grid, GridOrigin, CellSize); 50 | } 51 | 52 | 53 | 54 | public void Clear(float f) 55 | { 56 | BackgroundValue = f; 57 | Grid.assign(BackgroundValue); 58 | } 59 | 60 | 61 | 62 | public void Sample(BoundedImplicitFunction3d f, double expandRadius = 0) 63 | { 64 | AxisAlignedBox3d bounds = f.Bounds(); 65 | 66 | Vector3d expand = expandRadius * Vector3d.One; 67 | Vector3i gridMin = Indexer.ToGrid(bounds.Min-expand), 68 | gridMax = Indexer.ToGrid(bounds.Max+expand) + Vector3i.One; 69 | gridMin = GridBounds.ClampExclusive(gridMin); 70 | gridMax = GridBounds.ClampExclusive(gridMax); 71 | 72 | AxisAlignedBox3i gridbox = new AxisAlignedBox3i(gridMin, gridMax); 73 | switch (CombineMode) { 74 | case CombineModes.DistanceMinUnion: 75 | sample_min(f, gridbox.IndicesInclusive()); 76 | break; 77 | } 78 | } 79 | 80 | 81 | void sample_min(BoundedImplicitFunction3d f, IEnumerable indices) 82 | { 83 | gParallel.ForEach(indices, (idx) => { 84 | Vector3d v = Indexer.FromGrid(idx); 85 | double d = f.Value(ref v); 86 | Grid.set_min(ref idx, (float)d); 87 | }); 88 | } 89 | 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /geometry3Sharp/intersection/Intersector1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace g3 4 | { 5 | // ported from WildMagic5 6 | // 7 | // A class for intersection of intervals [u0,u1] and [v0,v1]. The end 8 | // points must be ordered: u0 <= u1 and v0 <= v1. Values of MAX_REAL 9 | // and -MAX_REAL are allowed, and degenerate intervals are allowed: 10 | // u0 = u1 or v0 = v1. 11 | // 12 | // [TODO] could this be struct? is not used in contexts where we necessarily need a new object... 13 | // 14 | public class Intersector1 15 | { 16 | // intervals to intersect 17 | public Interval1d U; 18 | public Interval1d V; 19 | 20 | 21 | // Information about the intersection set. The number of intersections 22 | // is 0 (intervals do not overlap), 1 (intervals are just touching), or 23 | // 2 (intervals intersect in an inteval). 24 | public int NumIntersections = 0; 25 | 26 | // intersection point/interval, access via GetIntersection 27 | private Interval1d Intersections = Interval1d.Zero; 28 | 29 | public Intersector1(double u0, double u1, double v0, double v1) { 30 | // [TODO] validate 0 < 1 31 | U = new Interval1d(u0,u1); 32 | V = new Interval1d(v0,v1); 33 | } 34 | public Intersector1(Interval1d u, Interval1d v) { 35 | U = u; 36 | V = v; 37 | } 38 | 39 | public bool Test { 40 | get { return U.a <= V.b && U.b >= V.a; } 41 | } 42 | 43 | 44 | public double GetIntersection(int i) { 45 | return Intersections[i]; 46 | } 47 | 48 | public bool Find() 49 | { 50 | if (U.b < V.a || U.a > V.b) { 51 | NumIntersections = 0; 52 | } else if (U.b > V.a) { 53 | if (U.a < V.b) { 54 | NumIntersections = 2; 55 | Intersections.a = (U.a < V.a ? V.a : U.a); 56 | Intersections.b = (U.b > V.b ? V.b : U.b); 57 | if (Intersections.a == Intersections.b) { 58 | NumIntersections = 1; 59 | } 60 | } else { 61 | // U.a == V.b 62 | NumIntersections = 1; 63 | Intersections.a = U.a; 64 | } 65 | } else { 66 | // U.b == V.a 67 | NumIntersections = 1; 68 | Intersections.a = U.b; 69 | } 70 | 71 | return NumIntersections > 0; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /geometry3Sharp/io/BinaryG3ReaderWriter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Runtime.InteropServices; 7 | using System.Threading; 8 | 9 | namespace g3 10 | { 11 | 12 | public class BinaryG3Writer : IMeshWriter 13 | { 14 | public IOWriteResult Write(BinaryWriter writer, List vMeshes, WriteOptions options) 15 | { 16 | int nMeshes = vMeshes.Count; 17 | writer.Write(nMeshes); 18 | for (int k = 0; k < vMeshes.Count; ++k) { 19 | DMesh3 mesh = vMeshes[k].Mesh as DMesh3; 20 | if (mesh == null) 21 | throw new NotImplementedException("BinaryG3Writer.Write: can only write DMesh3 meshes"); 22 | gSerialization.Store(mesh, writer); 23 | } 24 | 25 | return new IOWriteResult(IOCode.Ok, ""); 26 | } 27 | 28 | public IOWriteResult Write(TextWriter writer, List vMeshes, WriteOptions options) 29 | { 30 | throw new NotSupportedException("BinaryG3 Writer does not support ascii mode"); 31 | } 32 | 33 | } 34 | 35 | 36 | 37 | public class BinaryG3Reader : IMeshReader 38 | { 39 | public IOReadResult Read(BinaryReader reader, ReadOptions options, IMeshBuilder builder) 40 | { 41 | int nMeshes = reader.ReadInt32(); 42 | for (int k = 0; k < nMeshes; ++k) { 43 | DMesh3 m = new DMesh3(); 44 | gSerialization.Restore(m, reader); 45 | builder.AppendNewMesh(m); 46 | } 47 | 48 | return new IOReadResult(IOCode.Ok, ""); 49 | } 50 | 51 | public IOReadResult Read(TextReader reader, ReadOptions options, IMeshBuilder builder) 52 | { 53 | throw new NotSupportedException("BinaryG3Reader Writer does not support ascii mode"); 54 | } 55 | 56 | } 57 | 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /geometry3Sharp/io/MaterialTypes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | 4 | namespace g3 5 | { 6 | // Very hard to abstract material definitions from different formats. 7 | // basically we just have a generic top-level class and then completely different subclasses... 8 | 9 | public abstract class GenericMaterial 10 | { 11 | public static readonly float Invalidf = float.MinValue; 12 | public static readonly Vector3f Invalid = new Vector3f(-1, -1, -1); 13 | 14 | public string name; 15 | public int id; 16 | 17 | 18 | abstract public Vector3f DiffuseColor { get; set; } 19 | abstract public float Alpha { get; set; } 20 | 21 | 22 | public enum KnownMaterialTypes 23 | { 24 | OBJ_MTL_Format 25 | } 26 | public KnownMaterialTypes Type { get; set; } 27 | } 28 | 29 | 30 | 31 | // details: http://www.fileformat.info/format/material/ 32 | // Note: if value is initialized to Invalid vector, -1, or NaN, it was not defined in material file 33 | public class OBJMaterial : GenericMaterial 34 | { 35 | public Vector3f Ka; // rgb ambient reflectivity 36 | public Vector3f Kd; // rgb diffuse reflectivity 37 | public Vector3f Ks; // rgb specular reflectivity 38 | public Vector3f Ke; // rgb emissive 39 | public Vector3f Tf; // rgb transmission filter 40 | public int illum; // illumination model 0-10 41 | public float d; // dissolve (alpha) 42 | public float Ns; // specular exponent (shininess) 43 | public float sharpness; // reflection sharpness 44 | public float Ni; // index of refraction / optical density 45 | 46 | public string map_Ka; 47 | public string map_Kd; 48 | public string map_Ks; 49 | public string map_Ke; 50 | public string map_d; 51 | public string map_Ns; 52 | 53 | public string bump; 54 | public string disp; 55 | public string decal; 56 | public string refl; 57 | 58 | // [TODO] texture materials 59 | 60 | 61 | public OBJMaterial() 62 | { 63 | Type = KnownMaterialTypes.OBJ_MTL_Format; 64 | id = -1; 65 | name = "///INVALID_NAME"; 66 | Ka = Kd = Ks = Ke = Tf = Invalid; 67 | illum = -1; 68 | d = Ns = sharpness = Ni = Invalidf; 69 | } 70 | 71 | override public Vector3f DiffuseColor { 72 | get { return (Kd == Invalid) ? new Vector3f(1, 1, 1) : Kd; } 73 | set { Kd = value; } 74 | } 75 | override public float Alpha { 76 | get { return (d == Invalidf) ? 1.0f : d; } 77 | set { d = value; } 78 | } 79 | 80 | 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /geometry3Sharp/io/MeshIOUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace g3 5 | { 6 | public static class MeshIOUtil 7 | { 8 | 9 | public static List FindUniqueMaterialList(List meshes) 10 | { 11 | List unique = new List(); 12 | foreach (WriteMesh mesh in meshes) { 13 | if (mesh.Materials == null ) 14 | continue; 15 | foreach ( GenericMaterial mat in mesh.Materials ) { 16 | if ( unique.Contains(mat) == false ) 17 | unique.Add(mat); 18 | } 19 | } 20 | return unique; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /geometry3Sharp/io/OFFWriter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Runtime.InteropServices; 7 | using System.Threading; 8 | 9 | namespace g3 10 | { 11 | // 12 | // Write OFF mesh format 13 | // https://en.wikipedia.org/wiki/OFF_(file_format) 14 | // 15 | public class OFFWriter : IMeshWriter 16 | { 17 | 18 | 19 | public IOWriteResult Write(BinaryWriter writer, List vMeshes, WriteOptions options) 20 | { 21 | return new IOWriteResult(IOCode.FormatNotSupportedError, "binary write not supported for OFF format"); 22 | } 23 | 24 | 25 | 26 | public IOWriteResult Write(TextWriter writer, List vMeshes, WriteOptions options) 27 | { 28 | int N = vMeshes.Count; 29 | 30 | writer.WriteLine("OFF"); 31 | 32 | string three_floats = Util.MakeVec3FormatString(0, 1, 2, options.RealPrecisionDigits); 33 | 34 | int nTotalV = 0, nTotalT = 0, nTotalE = 0; 35 | 36 | // OFF only supports one mesh, so have to collapse all input meshes 37 | // into a single list, with mapping for triangles 38 | // [TODO] can skip this if input is a single mesh! 39 | int[][] mapV = new int[N][]; 40 | for ( int mi = 0; mi < N; ++mi ) { 41 | nTotalV += vMeshes[mi].Mesh.VertexCount; 42 | nTotalT += vMeshes[mi].Mesh.TriangleCount; 43 | nTotalE += 0; 44 | mapV[mi] = new int[vMeshes[mi].Mesh.MaxVertexID]; 45 | } 46 | writer.WriteLine(string.Format("{0} {1} {2}", nTotalV, nTotalT, nTotalE)); 47 | 48 | 49 | // write all vertices, and construct vertex re-map 50 | int vi = 0; 51 | for (int mi = 0; mi < N; ++mi) { 52 | IMesh mesh = vMeshes[mi].Mesh; 53 | if (options.ProgressFunc != null) 54 | options.ProgressFunc(mi, 2*(N - 1)); 55 | foreach (int vid in mesh.VertexIndices()) { 56 | Vector3d v = mesh.GetVertex(vid); 57 | writer.WriteLine(three_floats, v.x, v.y, v.z); 58 | mapV[mi][vid] = vi; 59 | vi++; 60 | } 61 | } 62 | 63 | // write all triangles 64 | for (int mi = 0; mi < N; ++mi) { 65 | IMesh mesh = vMeshes[mi].Mesh; 66 | if (options.ProgressFunc != null) 67 | options.ProgressFunc(N + mi, 2*(N - 1)); 68 | 69 | foreach ( int ti in mesh.TriangleIndices() ) { 70 | Index3i t = mesh.GetTriangle(ti); 71 | t[0] = mapV[mi][t[0]]; 72 | t[1] = mapV[mi][t[1]]; 73 | t[2] = mapV[mi][t[2]]; 74 | writer.WriteLine(string.Format("3 {0} {1} {2}", t[0], t[1], t[2])); 75 | } 76 | } 77 | 78 | return new IOWriteResult(IOCode.Ok, ""); 79 | } 80 | 81 | 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /geometry3Sharp/math/Line3.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace g3 7 | { 8 | public struct Line3d 9 | { 10 | public Vector3d Origin; 11 | public Vector3d Direction; 12 | 13 | public Line3d(Vector3d origin, Vector3d direction) 14 | { 15 | this.Origin = origin; 16 | this.Direction = direction; 17 | } 18 | 19 | // parameter is distance along Line 20 | public Vector3d PointAt(double d) { 21 | return Origin + d * Direction; 22 | } 23 | 24 | public double Project(Vector3d p) 25 | { 26 | return (p - Origin).Dot(Direction); 27 | } 28 | 29 | public double DistanceSquared(Vector3d p) 30 | { 31 | double t = (p - Origin).Dot(Direction); 32 | Vector3d proj = Origin + t * Direction; 33 | return (proj - p).LengthSquared; 34 | } 35 | 36 | public Vector3d ClosestPoint(Vector3d p) 37 | { 38 | double t = (p - Origin).Dot(Direction); 39 | return Origin + t * Direction; 40 | } 41 | 42 | // conversion operators 43 | public static implicit operator Line3d(Line3f v) 44 | { 45 | return new Line3d(v.Origin, v.Direction); 46 | } 47 | public static explicit operator Line3f(Line3d v) 48 | { 49 | return new Line3f((Vector3f)v.Origin, (Vector3f)v.Direction); 50 | } 51 | 52 | 53 | } 54 | 55 | 56 | public struct Line3f 57 | { 58 | public Vector3f Origin; 59 | public Vector3f Direction; 60 | 61 | public Line3f(Vector3f origin, Vector3f direction) 62 | { 63 | this.Origin = origin; 64 | this.Direction = direction; 65 | } 66 | 67 | // parameter is distance along Line 68 | public Vector3f PointAt(float d) 69 | { 70 | return Origin + d * Direction; 71 | } 72 | 73 | public float Project(Vector3f p) 74 | { 75 | return (p - Origin).Dot(Direction); 76 | } 77 | 78 | public float DistanceSquared(Vector3f p) 79 | { 80 | float t = (p - Origin).Dot(Direction); 81 | Vector3f proj = Origin + t * Direction; 82 | return (proj - p).LengthSquared; 83 | } 84 | 85 | public Vector3f ClosestPoint(Vector3f p) 86 | { 87 | float t = (p - Origin).Dot(Direction); 88 | return Origin + t * Direction; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /geometry3Sharp/math/MatrixUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace g3 5 | { 6 | public static class MatrixUtil 7 | { 8 | 9 | public static double[] MakeIdentity3x3(double a, double b, double c) 10 | { 11 | return new double[9] { 1, 0, 0, 0, 1, 0, 0, 0, 1 }; 12 | } 13 | public static void SetIdentity3x3(double[] M, double a, double b, double c) 14 | { 15 | Array.Clear(M, 0, 9); 16 | M[0] = M[4] = M[8] = 1; 17 | } 18 | 19 | 20 | public static double[] MakeDiagonal3x3(double a, double b, double c) 21 | { 22 | return new double[9] { a, 0, 0, 0, b, 0, 0, 0, c }; 23 | } 24 | public static void SetDiagonal3x3(double[] M, double a, double b, double c) 25 | { 26 | Array.Clear(M, 0, 9); 27 | M[0] = a; M[4] = b; M[8] = c; 28 | } 29 | 30 | // assumption is matrix is row-major 31 | public static double Determinant3x3(double[] M) 32 | { 33 | double co00 = M[4] * M[8] - M[5] * M[7]; 34 | double co10 = M[5] * M[6] - M[3] * M[8]; 35 | double co20 = M[3] * M[7] - M[4] * M[6]; 36 | double det = M[0] * co00 + M[1] * co10 + M[2] * co20; 37 | return det; 38 | } 39 | 40 | 41 | public static void Transpose3x3(double[] M) 42 | { 43 | double tmp = M[1]; M[1] = M[3]; M[3] = tmp; 44 | tmp = M[2]; M[2] = M[6]; M[6] = tmp; 45 | tmp = M[5]; M[5] = M[7]; M[7] = tmp; 46 | } 47 | public static void Transpose3x3(double[] M, double[] MTranspose) 48 | { 49 | MTranspose[0] = M[0]; 50 | MTranspose[1] = M[3]; 51 | MTranspose[2] = M[6]; 52 | MTranspose[3] = M[1]; 53 | MTranspose[4] = M[4]; 54 | MTranspose[5] = M[7]; 55 | MTranspose[6] = M[2]; 56 | MTranspose[7] = M[5]; 57 | } 58 | 59 | // C = A * B 60 | public static void Multiply3x3(double[] A, double[] B, double[] C) 61 | { 62 | C[0] = A[0] * B[0] + A[1] * B[3] + A[2] * B[6]; 63 | C[1] = A[0] * B[1] + A[1] * B[4] + A[2] * B[7]; 64 | C[2] = A[0] * B[2] + A[1] * B[5] + A[2] * B[8]; 65 | C[3] = A[3] * B[0] + A[4] * B[3] + A[5] * B[6]; 66 | C[4] = A[3] * B[1] + A[4] * B[4] + A[5] * B[7]; 67 | C[5] = A[3] * B[2] + A[4] * B[5] + A[5] * B[8]; 68 | C[6] = A[6] * B[0] + A[7] * B[3] + A[8] * B[6]; 69 | C[7] = A[6] * B[1] + A[7] * B[4] + A[8] * B[7]; 70 | C[8] = A[6] * B[2] + A[7] * B[5] + A[8] * B[8]; 71 | } 72 | 73 | 74 | public static Vector3d Multiply3x3(double[] M, Vector3d vec) 75 | { 76 | return new Vector3d( 77 | M[0] * vec.x + M[1] * vec.y + M[2] * vec.z, 78 | M[3] * vec.x + M[4] * vec.y + M[5] * vec.z, 79 | M[6] * vec.x + M[7] * vec.y + M[8] * vec.z 80 | ); 81 | } 82 | 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /geometry3Sharp/math/Query2Integer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace g3 7 | { 8 | // Port of Wm5Query2Int64 from WildMagic5 library by David Eberly / geometrictools.com 9 | 10 | /// 11 | /// 2D queries for integer coordinates. 12 | /// Note that input Vector2d values are directly cast to int64 - you must 13 | /// scale them to suitable coordinates yourself! 14 | /// 15 | public class Query2Int64 : Query2d 16 | { 17 | 18 | public Query2Int64(IList Vertices) : base(Vertices) 19 | { 20 | } 21 | 22 | 23 | public override int ToLine(ref Vector2d test, int v0, int v1) 24 | { 25 | Vector2d vec0 = mVertices[v0]; 26 | Vector2d vec1 = mVertices[v1]; 27 | 28 | long x0 = (long)test.x - (long)vec0.x; 29 | long y0 = (long)test.y - (long)vec0.y; 30 | long x1 = (long)vec1.x - (long)vec0.x; 31 | long y1 = (long)vec1.y - (long)vec0.y; 32 | 33 | long det = Det2(x0, y0, x1, y1); 34 | return (det > 0 ? +1 : (det < 0 ? -1 : 0)); 35 | } 36 | 37 | 38 | public override int ToCircumcircle(ref Vector2d test, int v0, int v1, int v2) 39 | { 40 | Vector2d vec0 = mVertices[v0]; 41 | Vector2d vec1 = mVertices[v1]; 42 | Vector2d vec2 = mVertices[v2]; 43 | 44 | Vector2l iTest = new Vector2l( (long)test.x, (long)test.y); 45 | Vector2l iV0 = new Vector2l((long)vec0.x, (long)vec0.y); 46 | Vector2l iV1 = new Vector2l((long)vec1.x, (long)vec1.y); 47 | Vector2l iV2 = new Vector2l((long)vec2.x, (long)vec2.y); 48 | 49 | long s0x = iV0.x + iTest.x; 50 | long d0x = iV0.x - iTest.x; 51 | long s0y = iV0.y + iTest.y; 52 | long d0y = iV0.y - iTest.y; 53 | long s1x = iV1.x + iTest.x; 54 | long d1x = iV1.x - iTest.x; 55 | long s1y = iV1.y + iTest.y; 56 | long d1y = iV1.y - iTest.y; 57 | long s2x = iV2.x + iTest.x; 58 | long d2x = iV2.x - iTest.x; 59 | long s2y = iV2.y + iTest.y; 60 | long d2y = iV2.y - iTest.y; 61 | long z0 = s0x * d0x + s0y * d0y; 62 | long z1 = s1x * d1x + s1y * d1y; 63 | long z2 = s2x * d2x + s2y * d2y; 64 | long det = Det3(d0x, d0y, z0, d1x, d1y, z1, d2x, d2y, z2); 65 | return (det < 0 ? 1 : (det > 0 ? -1 : 0)); 66 | } 67 | 68 | 69 | long Dot(long x0, long y0, long x1, long y1) 70 | { 71 | return x0 * x1 + y0 * y1; 72 | } 73 | 74 | 75 | long Det2(long x0, long y0, long x1, long y1) 76 | { 77 | return x0 * y1 - x1 * y0; 78 | } 79 | 80 | 81 | long Det3(long x0, long y0, long z0, long x1, long y1, long z1, long x2, long y2, long z2) 82 | { 83 | long c00 = y1 * z2 - y2 * z1; 84 | long c01 = y2 * z0 - y0 * z2; 85 | long c02 = y0 * z1 - y1 * z0; 86 | return x0 * c00 + x1 * c01 + x2 * c02; 87 | } 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /geometry3Sharp/math/ScalarMap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace g3 5 | { 6 | /// 7 | /// Scalar version of a ColorMap (ie interpolate between sample points) 8 | /// [TODO] could we make this a template? 9 | /// 10 | public class ScalarMap 11 | { 12 | struct Sample 13 | { 14 | public double t; 15 | public double value; 16 | } 17 | 18 | List points = new List(); 19 | Interval1d validRange; 20 | 21 | public ScalarMap() 22 | { 23 | validRange = Interval1d.Empty; 24 | } 25 | 26 | 27 | 28 | public void AddPoint(double t, double value) 29 | { 30 | Sample cp = new Sample() { t = t, value = value }; 31 | if ( points.Count == 0 ) { 32 | points.Add(cp); 33 | validRange.Contain(t); 34 | } else if ( t < points[0].t ) { 35 | points.Insert(0, cp); 36 | validRange.Contain(t); 37 | } else { 38 | for ( int k = 0; k < points.Count; ++k ) { 39 | if ( points[k].t == t ) { 40 | points[k] = cp; 41 | return; 42 | } else if ( points[k].t > t ) { 43 | points.Insert(k, cp); 44 | return; 45 | } 46 | } 47 | points.Add(cp); 48 | validRange.Contain(t); 49 | } 50 | } 51 | 52 | 53 | 54 | 55 | public double Linear(double t) 56 | { 57 | if (t <= points[0].t) 58 | return points[0].value; 59 | int N = points.Count; 60 | if (t >= points[N - 1].t) 61 | return points[N - 1].value; 62 | for ( int k = 1; k < points.Count; ++k ) { 63 | if ( points[k].t > t ) { 64 | Sample prev = points[k - 1], next = points[k]; 65 | double a = (t - prev.t) / (next.t - prev.t); 66 | return (1.0f - a) * prev.value + (a) * next.value; 67 | } 68 | } 69 | return points[N - 1].value; // should never get here... 70 | } 71 | 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /geometry3Sharp/math/Triangle2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace g3 7 | { 8 | public struct Triangle2d 9 | { 10 | public Vector2d V0, V1, V2; 11 | 12 | public Triangle2d(Vector2d v0, Vector2d v1, Vector2d v2) 13 | { 14 | V0 = v0; V1 = v1; V2 = v2; 15 | } 16 | 17 | public Vector2d this[int key] 18 | { 19 | get { return (key == 0) ? V0 : (key == 1) ? V1 : V2; } 20 | set { if (key == 0) V0 = value; else if (key == 1) V1 = value; else V2 = value; } 21 | } 22 | 23 | public Vector2d PointAt(double bary0, double bary1, double bary2) 24 | { 25 | return bary0 * V0 + bary1 * V1 + bary2 * V2; 26 | } 27 | public Vector2d PointAt(Vector3d bary) 28 | { 29 | return bary.x* V0 + bary.y* V1 + bary.z* V2; 30 | } 31 | 32 | // conversion operators 33 | public static implicit operator Triangle2d(Triangle2f v) 34 | { 35 | return new Triangle2d(v.V0, v.V1, v.V2); 36 | } 37 | public static explicit operator Triangle2f(Triangle2d v) 38 | { 39 | return new Triangle2f((Vector2f)v.V0, (Vector2f)v.V1, (Vector2f)v.V2); 40 | } 41 | } 42 | 43 | 44 | 45 | public struct Triangle2f 46 | { 47 | public Vector2f V0, V1, V2; 48 | 49 | public Triangle2f(Vector2f v0, Vector2f v1, Vector2f v2) 50 | { 51 | V0 = v0; V1 = v1; V2 = v2; 52 | } 53 | 54 | public Vector2f this[int key] 55 | { 56 | get { return (key == 0) ? V0 : (key == 1) ? V1 : V2; } 57 | set { if (key == 0) V0 = value; else if (key == 1) V1 = value; else V2 = value; } 58 | } 59 | 60 | 61 | public Vector2f PointAt(float bary0, float bary1, float bary2) 62 | { 63 | return bary0 * V0 + bary1 * V1 + bary2 * V2; 64 | } 65 | public Vector2f PointAt(Vector3f bary) 66 | { 67 | return bary.x * V0 + bary.y * V1 + bary.z * V2; 68 | } 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /geometry3Sharp/math/Triangle3.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace g3 7 | { 8 | public struct Triangle3d 9 | { 10 | public Vector3d V0, V1, V2; 11 | 12 | public Triangle3d(Vector3d v0, Vector3d v1, Vector3d v2) 13 | { 14 | V0 = v0; V1 = v1; V2 = v2; 15 | } 16 | 17 | public Vector3d this[int key] 18 | { 19 | get { return (key == 0) ? V0 : (key == 1) ? V1 : V2; } 20 | set { if (key == 0) V0 = value; else if (key == 1) V1 = value; else V2 = value; } 21 | } 22 | 23 | public Vector3d Normal { 24 | get { return MathUtil.Normal(ref V0, ref V1, ref V2); } 25 | } 26 | public double Area { 27 | get { return MathUtil.Area(ref V0, ref V1, ref V2); } 28 | } 29 | public double AspectRatio { 30 | get { return MathUtil.AspectRatio(ref V0, ref V1, ref V2); } 31 | } 32 | 33 | public Vector3d PointAt(double bary0, double bary1, double bary2) 34 | { 35 | return bary0 * V0 + bary1 * V1 + bary2 * V2; 36 | } 37 | public Vector3d PointAt(Vector3d bary) 38 | { 39 | return bary.x* V0 + bary.y* V1 + bary.z* V2; 40 | } 41 | 42 | public Vector3d BarycentricCoords(Vector3d point) 43 | { 44 | return MathUtil.BarycentricCoords(point, V0, V1, V2); 45 | } 46 | 47 | // conversion operators 48 | public static implicit operator Triangle3d(Triangle3f v) 49 | { 50 | return new Triangle3d(v.V0, v.V1, v.V2); 51 | } 52 | public static explicit operator Triangle3f(Triangle3d v) 53 | { 54 | return new Triangle3f((Vector3f)v.V0, (Vector3f)v.V1, (Vector3f)v.V2); 55 | } 56 | } 57 | 58 | 59 | 60 | public struct Triangle3f 61 | { 62 | public Vector3f V0, V1, V2; 63 | 64 | public Triangle3f(Vector3f v0, Vector3f v1, Vector3f v2) 65 | { 66 | V0 = v0; V1 = v1; V2 = v2; 67 | } 68 | 69 | public Vector3f this[int key] 70 | { 71 | get { return (key == 0) ? V0 : (key == 1) ? V1 : V2; } 72 | set { if (key == 0) V0 = value; else if (key == 1) V1 = value; else V2 = value; } 73 | } 74 | 75 | 76 | public Vector3f PointAt(float bary0, float bary1, float bary2) 77 | { 78 | return bary0 * V0 + bary1 * V1 + bary2 * V2; 79 | } 80 | public Vector3f PointAt(Vector3f bary) 81 | { 82 | return bary.x * V0 + bary.y * V1 + bary.z * V2; 83 | } 84 | 85 | public Vector3f BarycentricCoords(Vector3f point) 86 | { 87 | return (Vector3f)MathUtil.BarycentricCoords(point, V0, V1, V2); 88 | } 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /geometry3Sharp/mesh/DSubmesh3Set.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading; 7 | 8 | 9 | namespace g3 10 | { 11 | 12 | /// 13 | /// A set of submeshes of a base mesh. You provide a set of keys, and a Func 14 | /// that returns the triangle index list for a given key. The set of DSubmesh3 15 | /// objects are computed on construction. 16 | /// 17 | public class DSubmesh3Set : IEnumerable 18 | { 19 | public DMesh3 Mesh; 20 | 21 | public IEnumerable TriangleSetKeys; 22 | public Func> TriangleSetF; 23 | 24 | // outputs 25 | 26 | /// List of computed submeshes 27 | public List Submeshes; 28 | 29 | /// Mapping from keys to submeshes 30 | public Dictionary KeyToMesh; 31 | 32 | 33 | /// 34 | /// Construct submesh set from given keys and key-to-indices Func 35 | /// 36 | public DSubmesh3Set(DMesh3 mesh, IEnumerable keys, Func> indexSetsF) 37 | { 38 | Mesh = mesh; 39 | TriangleSetKeys = keys; 40 | TriangleSetF = indexSetsF; 41 | 42 | ComputeSubMeshes(); 43 | } 44 | 45 | 46 | /// 47 | /// Construct submesh set for an already-computed MeshConnectedComponents instance 48 | /// 49 | public DSubmesh3Set(DMesh3 mesh, MeshConnectedComponents components) 50 | { 51 | Mesh = mesh; 52 | 53 | TriangleSetF = (idx) => { 54 | return components.Components[(int)idx].Indices; 55 | }; 56 | List keys = new List(); 57 | for (int k = 0; k < components.Count; ++k) 58 | keys.Add(k); 59 | TriangleSetKeys = keys; 60 | 61 | ComputeSubMeshes(); 62 | } 63 | 64 | 65 | public IEnumerator GetEnumerator() { 66 | return Submeshes.GetEnumerator(); 67 | } 68 | IEnumerator IEnumerable.GetEnumerator() { 69 | return Submeshes.GetEnumerator(); 70 | } 71 | 72 | 73 | 74 | virtual protected void ComputeSubMeshes() 75 | { 76 | Submeshes = new List(); 77 | KeyToMesh = new Dictionary(); 78 | 79 | SpinLock data_lock = new SpinLock(); 80 | 81 | gParallel.ForEach(TriangleSetKeys, (obj) => { 82 | DSubmesh3 submesh = new DSubmesh3(Mesh, TriangleSetF(obj), 0); 83 | 84 | bool taken = false; 85 | data_lock.Enter(ref taken); 86 | Submeshes.Add(submesh); 87 | KeyToMesh[obj] = submesh; 88 | data_lock.Exit(); 89 | }); 90 | } 91 | 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /geometry3Sharp/mesh/MeshIndexUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | 5 | namespace g3 6 | { 7 | /// 8 | /// Utility functions for manipulating sets/lists of mesh indices 9 | /// 10 | public static class MeshIndexUtil 11 | { 12 | 13 | /// 14 | /// given list of edges of MeshA, and vertex map from A to B, map to list of edges on B 15 | /// 16 | public static List MapEdgesViaVertexMap(IIndexMap AtoBV, DMesh3 MeshA, DMesh3 MeshB, List edges) 17 | { 18 | int N = edges.Count; 19 | List result = new List(N); 20 | for ( int i = 0; i < N; ++i ) { 21 | int eid_a = edges[i]; 22 | Index2i aev = MeshA.GetEdgeV(eid_a); 23 | int bev0 = AtoBV[aev.a]; 24 | int bev1 = AtoBV[aev.b]; 25 | int eid_b = MeshB.FindEdge(bev0, bev1); 26 | Debug.Assert(eid_b != DMesh3.InvalidID); 27 | result.Add(eid_b); 28 | } 29 | return result; 30 | } 31 | 32 | 33 | 34 | /// 35 | /// given EdgeLoop on MeshA, and vertex map from A to B, map to EdgeLoop on B 36 | /// 37 | public static EdgeLoop MapLoopViaVertexMap(IIndexMap AtoBV, DMesh3 MeshA, DMesh3 MeshB, EdgeLoop loopIn) 38 | { 39 | int NV = loopIn.VertexCount, NE = loopIn.EdgeCount; 40 | int[] newVerts = new int[NV]; 41 | for (int i = 0; i < NV; ++i) 42 | newVerts[i] = AtoBV[loopIn.Vertices[i]]; 43 | 44 | int[] newEdges = new int[NE]; 45 | for ( int i = 0; i 10 | /// Present mesh edge midpoints as a point set 11 | /// 12 | public class MeshEdgeMidpoints : IPointSet 13 | { 14 | public MeshEdgeMidpoints(DMesh3 mesh) 15 | { 16 | Mesh = mesh; 17 | } 18 | 19 | public DMesh3 Mesh; 20 | 21 | public int VertexCount { get { return Mesh.EdgeCount; } } 22 | public int MaxVertexID { get { return Mesh.MaxEdgeID; } } 23 | 24 | public bool HasVertexNormals { get { return false; } } 25 | public bool HasVertexColors { get { return false; } } 26 | 27 | public Vector3d GetVertex(int i) { return Mesh.GetEdgePoint(i, 0.5); } 28 | public Vector3f GetVertexNormal(int i) { return Vector3f.AxisY; } 29 | public Vector3f GetVertexColor(int i) { return Vector3f.One; } 30 | 31 | public bool IsVertex(int vID) { return Mesh.IsEdge(vID); } 32 | 33 | // iterators allow us to work with gaps in index space 34 | public IEnumerable VertexIndices() 35 | { 36 | return Mesh.EdgeIndices(); 37 | } 38 | } 39 | 40 | 41 | 42 | 43 | /// 44 | /// Present mesh boundary-edge midpoints as a point set 45 | /// 46 | public class MeshBoundaryEdgeMidpoints : IPointSet 47 | { 48 | public MeshBoundaryEdgeMidpoints(DMesh3 mesh) 49 | { 50 | Mesh = mesh; 51 | // [RMS] we could count boundary edges really fast by iterating by +4's in 52 | // the mesh edge buffer... (also have to check that edge is valid though!) 53 | num_boundary_edges = 0; 54 | foreach (int eid in mesh.BoundaryEdgeIndices()) 55 | num_boundary_edges++; 56 | } 57 | 58 | int num_boundary_edges; 59 | public DMesh3 Mesh; 60 | 61 | public int VertexCount { get { return num_boundary_edges; } } 62 | public int MaxVertexID { get { return Mesh.MaxEdgeID; } } 63 | 64 | public bool HasVertexNormals { get { return false; } } 65 | public bool HasVertexColors { get { return false; } } 66 | 67 | public Vector3d GetVertex(int i) { return Mesh.GetEdgePoint(i, 0.5); } 68 | public Vector3f GetVertexNormal(int i) { return Vector3f.AxisY; } 69 | public Vector3f GetVertexColor(int i) { return Vector3f.One; } 70 | 71 | public bool IsVertex(int vID) { return Mesh.IsEdge(vID) && Mesh.IsBoundaryEdge(vID); } 72 | 73 | // iterators allow us to work with gaps in index space 74 | public IEnumerable VertexIndices() 75 | { 76 | return Mesh.BoundaryEdgeIndices(); 77 | } 78 | } 79 | 80 | 81 | } 82 | -------------------------------------------------------------------------------- /geometry3Sharp/mesh/MeshUVSet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace g3 5 | { 6 | // 7 | // Standalone UV mesh 8 | // (mainly we are using this as a UV layer for an existing 3D Mesh, so the assumption 9 | // is that TriangleUVs has the same # of triangles as that mesh...) 10 | public class DenseUVMesh 11 | { 12 | public DVector UVs; 13 | public DVector TriangleUVs; 14 | 15 | public DenseUVMesh() 16 | { 17 | UVs = new DVector(); 18 | TriangleUVs = new DVector(); 19 | } 20 | 21 | public int AppendUV(Vector2f uv) 22 | { 23 | int id = UVs.Length; 24 | UVs.Add(uv); 25 | return id; 26 | } 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /geometry3Sharp/mesh_generators/ArrowGenerators.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace g3 7 | { 8 | // radially-symmetric 3D arrow 9 | public class Radial3DArrowGenerator : VerticalGeneralizedCylinderGenerator 10 | { 11 | public float StickRadius = 0.5f; 12 | public float StickLength = 1.0f; 13 | public float HeadBaseRadius = 1.0f; 14 | public float TipRadius = 0.0f; 15 | public float HeadLength = 0.5f; 16 | 17 | override public MeshGenerator Generate() 18 | { 19 | Sections = new CircularSection[4]; 20 | Sections[0] = new CircularSection(StickRadius, 0.0f); 21 | Sections[1] = new CircularSection(StickRadius, StickLength); 22 | Sections[2] = new CircularSection(HeadBaseRadius, StickLength); 23 | Sections[3] = new CircularSection(TipRadius, StickLength+HeadLength); 24 | 25 | Capped = true; 26 | NoSharedVertices = true; 27 | base.Generate(); 28 | 29 | return this; 30 | } 31 | 32 | } 33 | 34 | 35 | 36 | 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /geometry3Sharp/mesh_generators/PointsMeshGenerators.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace g3 6 | { 7 | /// 8 | /// Create a mesh that contains a planar element for each point and normal 9 | /// (currently only triangles) 10 | /// 11 | public class PointSplatsGenerator : MeshGenerator 12 | { 13 | public IEnumerable PointIndices; 14 | public int PointIndicesCount = -1; // you can set this to avoid calling Count() on enumerable 15 | 16 | public Func PointF; // required 17 | public Func NormalF; // required 18 | public double Radius = 1.0f; 19 | 20 | public PointSplatsGenerator() 21 | { 22 | WantUVs = false; 23 | } 24 | 25 | public override MeshGenerator Generate() 26 | { 27 | int N = (PointIndicesCount == -1) ? PointIndices.Count() : PointIndicesCount; 28 | 29 | vertices = new VectorArray3d(N * 3); 30 | uv = null; 31 | normals = new VectorArray3f(vertices.Count); 32 | triangles = new IndexArray3i(N); 33 | 34 | Matrix2f matRot = new Matrix2f(120 * MathUtil.Deg2Radf); 35 | Vector2f uva = new Vector2f(0, Radius); 36 | Vector2f uvb = matRot * uva; 37 | Vector2f uvc = matRot * uvb; 38 | 39 | int vi = 0; 40 | int ti = 0; 41 | foreach (int pid in PointIndices) { 42 | Vector3d v = PointF(pid); 43 | Vector3d n = NormalF(pid); 44 | Frame3f f = new Frame3f(v, n); 45 | triangles.Set(ti++, vi, vi + 1, vi + 2, Clockwise); 46 | vertices[vi++] = f.FromPlaneUV(uva, 2); 47 | vertices[vi++] = f.FromPlaneUV(uvb, 2); 48 | vertices[vi++] = f.FromPlaneUV(uvc, 2); 49 | } 50 | 51 | return this; 52 | } 53 | 54 | 55 | 56 | /// 57 | /// shortcut utility 58 | /// 59 | public static DMesh3 Generate(IList indices, 60 | Func PointF, Func NormalF, 61 | double radius) 62 | { 63 | var gen = new PointSplatsGenerator() { 64 | PointIndices = indices, 65 | PointIndicesCount = indices.Count, 66 | PointF = PointF, NormalF = NormalF, Radius = radius 67 | }; 68 | return gen.Generate().MakeDMesh(); 69 | } 70 | 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /geometry3Sharp/mesh_generators/SphereGenerators.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | 5 | namespace g3 6 | { 7 | 8 | 9 | /// 10 | /// Generate a mesh of a sphere by first generating a mesh of a cube, 11 | /// and then normalizing the vertices and moving them to sphere of desired radius. 12 | /// 13 | public class Sphere3Generator_NormalizedCube : GridBox3Generator 14 | { 15 | public double Radius = 1.0; 16 | 17 | public enum NormalizationTypes 18 | { 19 | NormalizedVector, 20 | CubeMapping // produces more even distribution of quads 21 | // see http://catlikecoding.com/unity/tutorials/cube-sphere/ 22 | // or http://mathproofs.blogspot.ca/2005/07/mapping-cube-to-sphere.html 23 | } 24 | NormalizationTypes NormalizeType = NormalizationTypes.CubeMapping; 25 | 26 | public override MeshGenerator Generate() 27 | { 28 | base.Generate(); 29 | for ( int i = 0; i < vertices.Count; ++i ) { 30 | Vector3d v = vertices[i] - Box.Center; 31 | if (NormalizeType == NormalizationTypes.CubeMapping) { 32 | double x = v.Dot(Box.AxisX) / Box.Extent.x; 33 | double y = v.Dot(Box.AxisY) / Box.Extent.y; 34 | double z = v.Dot(Box.AxisZ) / Box.Extent.z; 35 | double x2 = x * x, y2 = y * y, z2 = z * z; 36 | double sx = x * Math.Sqrt(1.0 - y2*0.5 - z2*0.5 + y2*z2/3.0); 37 | double sy = y * Math.Sqrt(1.0 - x2*0.5 - z2*0.5 + x2*z2/3.0); 38 | double sz = z * Math.Sqrt(1.0 - x2*0.5 - y2*0.5 + x2*y2/3.0); 39 | v = sx*Box.AxisX + sy*Box.AxisY + sz*Box.AxisZ; 40 | } 41 | v.Normalize(); 42 | vertices[i] = Box.Center + Radius*v; 43 | normals[i] = (Vector3f)v; 44 | } 45 | 46 | return this; 47 | } 48 | 49 | } 50 | 51 | 52 | 53 | 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /geometry3Sharp/mesh_ops/MeshExtrudeLoop.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | 4 | namespace g3 5 | { 6 | /// 7 | /// Assumption is that Loop is a boundary loop on Mesh. 8 | /// Operation makes a duplicate loop of vertices, at location defind by PositionF, 9 | /// then stitches input and new loops together with a ring of triangles. 10 | /// 11 | public class MeshExtrudeLoop 12 | { 13 | public DMesh3 Mesh; 14 | public EdgeLoop Loop; 15 | 16 | // arguments 17 | 18 | // set new position based on original loop vertex position, normal, and index 19 | public Func PositionF; 20 | 21 | // outputs 22 | 23 | public int[] NewTriangles; 24 | public EdgeLoop NewLoop; 25 | 26 | 27 | public MeshExtrudeLoop(DMesh3 mesh, EdgeLoop loop) 28 | { 29 | Mesh = mesh; 30 | Loop = loop; 31 | 32 | PositionF = (pos, normal, idx) => { 33 | return pos + Vector3d.AxisY; 34 | }; 35 | } 36 | 37 | 38 | public virtual ValidationStatus Validate() 39 | { 40 | ValidationStatus loopStatus = MeshValidation.IsBoundaryLoop(Mesh, Loop); 41 | return loopStatus; 42 | } 43 | 44 | 45 | public virtual bool Extrude(int group_id = -1) 46 | { 47 | // duplicate loop vertices 48 | int NV = Loop.Vertices.Length; 49 | NewLoop = new EdgeLoop(Mesh); 50 | NewLoop.Vertices = new int[NV]; 51 | 52 | for ( int i = 0; i < NV; ++i ) { 53 | int vid = Loop.Vertices[i]; 54 | NewLoop.Vertices[i] = Mesh.AppendVertex(Mesh, vid); 55 | } 56 | 57 | // move to offset positions 58 | for ( int i = 0; i < NV; ++i ) { 59 | Vector3d v = Mesh.GetVertex(Loop.Vertices[i]); 60 | Vector3f n = Mesh.GetVertexNormal(Loop.Vertices[i]); 61 | Vector3d new_v = PositionF(v, n, i); 62 | Mesh.SetVertex(NewLoop.Vertices[i], new_v); 63 | } 64 | 65 | // stitch interior 66 | MeshEditor edit = new MeshEditor(Mesh); 67 | NewTriangles = edit.StitchLoop(Loop.Vertices, NewLoop.Vertices, group_id); 68 | 69 | return true; 70 | } 71 | 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /geometry3Sharp/mesh_ops/MeshIterativeSmooth.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace g3 5 | { 6 | public class MeshIterativeSmooth 7 | { 8 | public DMesh3 Mesh; 9 | public int[] Vertices; 10 | 11 | public double Alpha = 0.25f; 12 | public int Rounds = 10; 13 | 14 | public enum SmoothTypes { 15 | Uniform, Cotan, MeanValue 16 | }; 17 | public SmoothTypes SmoothType = SmoothTypes.Uniform; 18 | 19 | // reproject smoothed position to new location 20 | public Func ProjectF; 21 | 22 | Vector3d[] SmoothedPostions; 23 | 24 | public MeshIterativeSmooth(DMesh3 mesh, int[] vertices, bool bOwnVertices = false) 25 | { 26 | Mesh = mesh; 27 | Vertices = (bOwnVertices) ? vertices : (int[])vertices.Clone(); 28 | 29 | SmoothedPostions = new Vector3d[Vertices.Length]; 30 | 31 | ProjectF = null; 32 | } 33 | 34 | 35 | public virtual ValidationStatus Validate() 36 | { 37 | return ValidationStatus.Ok; 38 | } 39 | 40 | 41 | public virtual bool Smooth() 42 | { 43 | int NV = Vertices.Length; 44 | 45 | double a = MathUtil.Clamp(Alpha, 0, 1); 46 | double num_rounds = MathUtil.Clamp(Rounds, 0, 10000); 47 | 48 | Func smoothFunc = MeshUtil.UniformSmooth; 49 | if (SmoothType == SmoothTypes.MeanValue) 50 | smoothFunc = MeshUtil.MeanValueSmooth; 51 | else if (SmoothType == SmoothTypes.Cotan) 52 | smoothFunc = MeshUtil.CotanSmooth; 53 | 54 | Action smooth = (i) => { 55 | int vID = Vertices[i]; 56 | SmoothedPostions[i] = smoothFunc(Mesh, vID, a); 57 | }; 58 | Action project = (i) => { 59 | Vector3d pos = SmoothedPostions[i]; 60 | SmoothedPostions[i] = ProjectF(pos, Vector3f.AxisY, Vertices[i]); 61 | }; 62 | 63 | IndexRangeEnumerator indices = new IndexRangeEnumerator(0, NV); 64 | 65 | for (int round = 0; round < num_rounds; ++round) { 66 | 67 | gParallel.ForEach(indices, smooth); 68 | if ( ProjectF != null ) 69 | gParallel.ForEach(indices, project); 70 | 71 | // bake 72 | for (int i = 0; i < NV; ++i) 73 | Mesh.SetVertex(Vertices[i], SmoothedPostions[i]); 74 | } 75 | 76 | return true; 77 | } 78 | } 79 | 80 | 81 | 82 | 83 | } 84 | -------------------------------------------------------------------------------- /geometry3Sharp/mesh_ops/MeshLoopSmooth.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace g3 5 | { 6 | public class MeshLoopSmooth 7 | { 8 | public DMesh3 Mesh; 9 | public EdgeLoop Loop; 10 | 11 | public double Alpha = 0.25f; 12 | public int Rounds = 10; 13 | 14 | // reproject smoothed position to new location 15 | public Func ProjectF; 16 | 17 | 18 | Vector3d[] SmoothedPostions; 19 | 20 | public MeshLoopSmooth(DMesh3 mesh, EdgeLoop loop) 21 | { 22 | Mesh = mesh; 23 | Loop = loop; 24 | 25 | SmoothedPostions = new Vector3d[Loop.Vertices.Length]; 26 | 27 | ProjectF = null; 28 | } 29 | 30 | 31 | public virtual ValidationStatus Validate() 32 | { 33 | ValidationStatus loopStatus = MeshValidation.IsEdgeLoop(Mesh, Loop); 34 | return loopStatus; 35 | } 36 | 37 | 38 | public virtual bool Smooth() 39 | { 40 | int NV = Loop.Vertices.Length; 41 | 42 | double a = MathUtil.Clamp(Alpha, 0, 1); 43 | double num_rounds = MathUtil.Clamp(Rounds, 0, 10000); 44 | 45 | for (int round = 0; round < num_rounds; ++round) { 46 | 47 | // compute 48 | gParallel.ForEach(Interval1i.Range(NV), (i) => { 49 | int vid = Loop.Vertices[(i + 1) % NV]; 50 | Vector3d prev = Mesh.GetVertex(Loop.Vertices[i]); 51 | Vector3d cur = Mesh.GetVertex(vid); 52 | Vector3d next = Mesh.GetVertex(Loop.Vertices[(i + 2) % NV]); 53 | 54 | Vector3d centroid = (prev + next) * 0.5; 55 | SmoothedPostions[i] = (1 - a) * cur + (a) * centroid; 56 | }); 57 | 58 | // bake 59 | gParallel.ForEach(Interval1i.Range(NV), (i) => { 60 | int vid = Loop.Vertices[(i + 1) % NV]; 61 | Vector3d pos = SmoothedPostions[i]; 62 | 63 | if (ProjectF != null) 64 | pos = ProjectF(pos, vid); 65 | 66 | Mesh.SetVertex(vid, pos); 67 | }); 68 | } 69 | 70 | return true; 71 | } 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /geometry3Sharp/mesh_ops/MeshOps.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace g3 4 | { 5 | 6 | public struct SetGroupBehavior 7 | { 8 | public enum Modes 9 | { 10 | Ignore = 0, 11 | AutoGenerate = 1, 12 | UseConstant = 2 13 | }; 14 | Modes Mode; 15 | int SetGroupID; 16 | 17 | public SetGroupBehavior(Modes mode, int id = 0) { 18 | Mode = mode; 19 | SetGroupID = id; 20 | } 21 | 22 | public int GetGroupID(DMesh3 mesh) 23 | { 24 | if (Mode == Modes.Ignore) 25 | return -1; 26 | else if (Mode == Modes.AutoGenerate) 27 | return mesh.AllocateTriangleGroup(); 28 | else 29 | return SetGroupID; 30 | } 31 | 32 | public static SetGroupBehavior Ignore { get { return new SetGroupBehavior(Modes.Ignore, 0); } } 33 | public static SetGroupBehavior AutoGenerate { get { return new SetGroupBehavior(Modes.AutoGenerate, 0); } } 34 | public static SetGroupBehavior SetTo(int groupID) { return new SetGroupBehavior(Modes.UseConstant, groupID); } 35 | } 36 | 37 | 38 | public static class MeshOps 39 | { 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /geometry3Sharp/mesh_ops/SimpleHoleFiller.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace g3 7 | { 8 | public class SimpleHoleFiller 9 | { 10 | public DMesh3 Mesh; 11 | public EdgeLoop Loop; 12 | 13 | public int NewVertex; 14 | public int[] NewTriangles; 15 | 16 | 17 | public SimpleHoleFiller(DMesh3 mesh, EdgeLoop loop) 18 | { 19 | Mesh = mesh; 20 | Loop = loop; 21 | 22 | NewVertex = DMesh3.InvalidID; 23 | NewTriangles = null; 24 | } 25 | 26 | 27 | 28 | public virtual ValidationStatus Validate() 29 | { 30 | ValidationStatus loopStatus = MeshValidation.IsBoundaryLoop(Mesh, Loop); 31 | return loopStatus; 32 | } 33 | 34 | 35 | public virtual bool Fill(int group_id = -1) 36 | { 37 | if (Loop.Vertices.Length < 3) 38 | return false; 39 | 40 | // this just needs one triangle 41 | if ( Loop.Vertices.Length == 3 ) { 42 | Index3i tri = new Index3i(Loop.Vertices[0], Loop.Vertices[2], Loop.Vertices[1]); 43 | int new_tid = Mesh.AppendTriangle(tri, group_id); 44 | if (new_tid < 0) 45 | return false; 46 | NewTriangles = new int[1] { new_tid }; 47 | NewVertex = DMesh3.InvalidID; 48 | return true; 49 | } 50 | 51 | // [TODO] 4-case? could check nbr normals to figure out best internal edge... 52 | 53 | 54 | // compute centroid 55 | Vector3d c = Vector3d.Zero; 56 | for (int i = 0; i < Loop.Vertices.Length; ++i) 57 | c += Mesh.GetVertex(Loop.Vertices[i]); 58 | c *= 1.0 / Loop.Vertices.Length; 59 | 60 | // add centroid vtx 61 | NewVertex = Mesh.AppendVertex(c); 62 | 63 | // stitch triangles 64 | MeshEditor editor = new MeshEditor(Mesh); 65 | try { 66 | NewTriangles = editor.AddTriangleFan_OrderedVertexLoop(NewVertex, Loop.Vertices, group_id); 67 | } catch { 68 | NewTriangles = null; 69 | } 70 | 71 | // if fill failed, back out vertex-add 72 | if ( NewTriangles == null ) { 73 | Mesh.RemoveVertex(NewVertex, true, false); 74 | NewVertex = DMesh3.InvalidID; 75 | return false; 76 | } else 77 | return true; 78 | 79 | } 80 | 81 | 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /geometry3Sharp/queries/MeshValidation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | 5 | namespace g3 6 | { 7 | public enum ValidationStatus 8 | { 9 | Ok, 10 | 11 | NotAVertex, 12 | NotBoundaryVertex, 13 | NotBoundaryEdge, 14 | 15 | NotATriangle, 16 | 17 | VerticesNotConnectedByEdge, 18 | IncorrectLoopOrientation, 19 | 20 | DuplicateTriangles, 21 | 22 | NearDegenerateMeshEdges, 23 | NearDenegerateInputGeometry, 24 | } 25 | 26 | 27 | public static class MeshValidation 28 | { 29 | 30 | public static ValidationStatus IsEdgeLoop(DMesh3 mesh, EdgeLoop loop) 31 | { 32 | int N = loop.Vertices.Length; 33 | for ( int i = 0; i < N; ++i ) { 34 | if ( ! mesh.IsVertex(loop.Vertices[i]) ) 35 | return ValidationStatus.NotAVertex; 36 | } 37 | for (int i = 0; i < N; ++i) { 38 | int a = loop.Vertices[i]; 39 | int b = loop.Vertices[(i + 1) % N]; 40 | 41 | int eid = mesh.FindEdge(a, b); 42 | if (eid == DMesh3.InvalidID) 43 | return ValidationStatus.VerticesNotConnectedByEdge; 44 | } 45 | return ValidationStatus.Ok; 46 | } 47 | 48 | 49 | 50 | public static ValidationStatus IsBoundaryLoop(DMesh3 mesh, EdgeLoop loop) 51 | { 52 | int N = loop.Vertices.Length; 53 | 54 | for ( int i = 0; i < N; ++i ) { 55 | if ( ! mesh.IsBoundaryVertex(loop.Vertices[i]) ) 56 | return ValidationStatus.NotBoundaryVertex; 57 | } 58 | 59 | for ( int i = 0; i < N; ++i ) { 60 | int a = loop.Vertices[i]; 61 | int b = loop.Vertices[(i + 1) % N]; 62 | 63 | int eid = mesh.FindEdge(a, b); 64 | if (eid == DMesh3.InvalidID) 65 | return ValidationStatus.VerticesNotConnectedByEdge; 66 | 67 | if (mesh.IsBoundaryEdge(eid) == false) 68 | return ValidationStatus.NotBoundaryEdge; 69 | 70 | Index2i ev = mesh.GetOrientedBoundaryEdgeV(eid); 71 | if (!(ev.a == a && ev.b == b)) 72 | return ValidationStatus.IncorrectLoopOrientation; 73 | } 74 | 75 | return ValidationStatus.Ok; 76 | } 77 | 78 | 79 | 80 | public static ValidationStatus HasDuplicateTriangles(DMesh3 mesh) 81 | { 82 | foreach (int tid in mesh.TriangleIndices()) { 83 | Index3i nbrs = mesh.GetTriNeighbourTris(tid); 84 | if (nbrs.a == nbrs.b && nbrs.b == nbrs.c && nbrs.a != DMesh3.InvalidID) 85 | return ValidationStatus.DuplicateTriangles; 86 | } 87 | 88 | return ValidationStatus.Ok; 89 | } 90 | 91 | 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /geometry3Sharp/shapes3/Cylinder3.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace g3 4 | { 5 | // ported from GTEngine (WildMagic5 doesn't have cylinder primitive) 6 | public class Cylinder3d 7 | { 8 | // The cylinder axis is a line. The origin of the cylinder is chosen to be 9 | // the line origin. The cylinder wall is at a distance R units from the axis. 10 | // An infinite cylinder has infinite height. A finite cylinder has center C 11 | // at the line origin and has a finite height H. The segment for the finite 12 | // cylinder has endpoints C-(H/2)*D and C+(H/2)*D where D is a unit-length 13 | // direction of the line. 14 | 15 | public Line3d Axis; 16 | public double Radius; 17 | public double Height; 18 | 19 | public Cylinder3d(Line3d axis, double radius, double height) 20 | { 21 | Axis = axis; 22 | Radius = radius; 23 | Height = height; 24 | } 25 | public Cylinder3d(Vector3d center, Vector3d axis, double radius, double height) 26 | { 27 | Axis = new Line3d(center, axis); 28 | Radius = radius; 29 | Height = height; 30 | } 31 | public Cylinder3d(Frame3f frame, double radius, double height, int nNormalAxis = 1) 32 | { 33 | Axis = new Line3d(frame.Origin, frame.GetAxis(nNormalAxis)); 34 | Radius = radius; 35 | Height = height; 36 | } 37 | public Cylinder3d(double radius, double height) 38 | { 39 | Axis = new Line3d(Vector3d.Zero, Vector3d.AxisY); 40 | Radius = radius; 41 | Height = height; 42 | } 43 | 44 | 45 | public double Circumference { 46 | get { return MathUtil.TwoPI * Radius; } 47 | } 48 | public double Diameter { 49 | get { return 2 * Radius; } 50 | } 51 | public double Volume { 52 | get { return Math.PI * Radius * Radius * Height; } 53 | } 54 | 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /geometry3Sharp/solvers/DenseVector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace g3 4 | { 5 | public class DenseVector 6 | { 7 | double[] d; 8 | int N; 9 | 10 | 11 | public DenseVector(int N) 12 | { 13 | d = new double[N]; 14 | Array.Clear(d, 0, d.Length); 15 | this.N = N; 16 | } 17 | 18 | 19 | public void Set(int i, double value) 20 | { 21 | d[i] = value; 22 | } 23 | 24 | 25 | public int Size { get { return N; } } 26 | public int Length { get { return N; } } 27 | 28 | public double this[int i] 29 | { 30 | get { return d[i]; } 31 | set { d[i] = value; } 32 | } 33 | 34 | public double[] Buffer 35 | { 36 | get { return d; } 37 | } 38 | 39 | 40 | public double Dot(DenseVector v2) { 41 | return Dot(v2.d); 42 | } 43 | public double Dot(double[] v2) 44 | { 45 | if (v2.Length != N) 46 | throw new Exception("DenseVector.Dot: incompatible lengths"); 47 | double sum = 0; 48 | for (int k = 0; k < v2.Length; ++k) 49 | sum += d[k] * v2[k]; 50 | return sum; 51 | } 52 | 53 | } 54 | } -------------------------------------------------------------------------------- /geometry3Sharp/solvers/IMatrix.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | 4 | namespace g3 5 | { 6 | public interface IMatrix 7 | { 8 | int Rows { get; } 9 | int Columns { get; } 10 | Index2i Size { get; } 11 | 12 | void Set(int r, int c, double value); 13 | 14 | double this[int r, int c] { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /geometry3Sharp/spatial/BasicIntersectionTargets.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace g3 7 | { 8 | 9 | public class TransformedIntersectionTarget : IIntersectionTarget 10 | { 11 | DMeshIntersectionTarget BaseTarget = null; 12 | 13 | public Func MapToBaseF = null; 14 | public Func MapFromBasePosF = null; 15 | public Func MapFromBaseNormalF = null; 16 | 17 | 18 | public bool HasNormal { get { return BaseTarget.HasNormal; } } 19 | public bool RayIntersect(Ray3d ray, out Vector3d vHit, out Vector3d vHitNormal) 20 | { 21 | Ray3d baseRay = MapToBaseF(ray); 22 | if ( BaseTarget.RayIntersect(baseRay, out vHit, out vHitNormal) ) { 23 | vHit = MapFromBasePosF(vHit); 24 | vHitNormal = MapFromBasePosF(vHitNormal); 25 | return true; 26 | } 27 | return false; 28 | } 29 | } 30 | 31 | 32 | 33 | 34 | 35 | public class DMeshIntersectionTarget : IIntersectionTarget 36 | { 37 | public DMesh3 Mesh { get; set; } 38 | public ISpatial Spatial { get; set; } 39 | public bool UseFaceNormal = true; 40 | 41 | public DMeshIntersectionTarget() { } 42 | public DMeshIntersectionTarget(DMesh3 mesh, ISpatial spatial) 43 | { 44 | Mesh = mesh; 45 | Spatial = spatial; 46 | } 47 | 48 | 49 | public bool HasNormal { get { return true; } } 50 | public bool RayIntersect(Ray3d ray, out Vector3d vHit, out Vector3d vHitNormal) 51 | { 52 | vHit = Vector3d.Zero; 53 | vHitNormal = Vector3d.AxisX; 54 | int tHitID = Spatial.FindNearestHitTriangle(ray); 55 | if (tHitID == DMesh3.InvalidID) 56 | return false; 57 | IntrRay3Triangle3 t = MeshQueries.TriangleIntersection(Mesh, tHitID, ray); 58 | vHit = ray.PointAt(t.RayParameter); 59 | if ( UseFaceNormal == false && Mesh.HasVertexNormals) 60 | vHitNormal = Mesh.GetTriBaryNormal(tHitID, t.TriangleBaryCoords.x, t.TriangleBaryCoords.y, t.TriangleBaryCoords.z); 61 | else 62 | vHitNormal = Mesh.GetTriNormal(tHitID); 63 | return true; 64 | } 65 | } 66 | 67 | 68 | 69 | /// 70 | /// Compute ray-intersection with plane 71 | /// 72 | public class PlaneIntersectionTarget : IIntersectionTarget 73 | { 74 | public Frame3f PlaneFrame; 75 | public int NormalAxis = 2; 76 | 77 | public bool HasNormal { get { return true; } } 78 | public bool RayIntersect(Ray3d ray, out Vector3d vHit, out Vector3d vHitNormal) 79 | { 80 | Vector3f rayHit = PlaneFrame.RayPlaneIntersection((Vector3f)ray.Origin, (Vector3f)ray.Direction, NormalAxis); 81 | vHit = rayHit; 82 | vHitNormal = Vector3f.AxisY; 83 | return (rayHit != Vector3f.Invalid); 84 | } 85 | } 86 | 87 | 88 | 89 | } 90 | -------------------------------------------------------------------------------- /geometry3Sharp/spatial/BiGrid3.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace g3 7 | { 8 | /// 9 | /// BiGrid3 is a two-level multiresolution grid data structure. You provide 10 | /// exemplar object that implements suitable interfaces, and the class 11 | /// automatically generates necessary data structures. 12 | /// Functions to act on parent/child grids are in-progress... 13 | /// 14 | public class BiGrid3 where BlockType : class, IGridElement3, IFixedGrid3 15 | { 16 | Vector3i block_size; 17 | MultigridIndexer3 indexer; 18 | 19 | public Vector3i BlockSize { 20 | get { return block_size; } 21 | } 22 | public MultigridIndexer3 Indexer { 23 | get { return indexer; } 24 | } 25 | 26 | 27 | DSparseGrid3 sparse_grid; 28 | public DSparseGrid3 BlockGrid { 29 | get { return sparse_grid; } 30 | } 31 | 32 | 33 | public BiGrid3( BlockType exemplar ) 34 | { 35 | block_size = exemplar.Dimensions; 36 | indexer = new MultigridIndexer3(block_size); 37 | sparse_grid = new DSparseGrid3(exemplar); 38 | } 39 | 40 | 41 | /// 42 | /// map index into correct block and let client update that block at the correct local index 43 | /// 44 | public void Update(Index3i index, Action UpdateF ) 45 | { 46 | GridLevelIndex bidx = Indexer.ToBlock(index); 47 | BlockType block = sparse_grid.Get(bidx.block_index, true); 48 | UpdateF(block, bidx.local_index); 49 | } 50 | 51 | 52 | 53 | public IEnumerable> AllocatedBlocks() 54 | { 55 | return sparse_grid.Allocated(); 56 | } 57 | 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /geometry3Sharp/spatial/Bitmap2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | 5 | namespace g3 6 | { 7 | 8 | public class Bitmap2 9 | { 10 | public BitArray Bits; 11 | 12 | Vector2i dimensions; 13 | public Vector2i Dimensions { 14 | get { return dimensions; } 15 | } 16 | 17 | int row_size; 18 | 19 | public Bitmap2(Vector2i dims) { 20 | Resize(dims); 21 | } 22 | public Bitmap2(int Width, int Height) 23 | { 24 | Resize(new Vector2i(Width, Height)); 25 | } 26 | 27 | public void Resize(Vector2i dims) { 28 | int size = dims.x * dims.y; 29 | Bits = new BitArray(size); 30 | dimensions = dims; 31 | row_size = dims.x; 32 | } 33 | 34 | 35 | public AxisAlignedBox2i GridBounds { 36 | get { return new AxisAlignedBox2i(Vector2i.Zero, Dimensions); } 37 | } 38 | 39 | public bool this[int i] { 40 | get { return Bits[i]; } 41 | set { Bits[i] = value; } 42 | } 43 | 44 | public bool this[int r, int c] { 45 | get { return Bits[r * row_size + c]; } 46 | set { Bits[r * row_size + c] = value; } 47 | } 48 | 49 | public bool this[Vector2i idx] 50 | { 51 | get { 52 | int i = idx.y * row_size + idx.x; 53 | return Bits[i]; 54 | } 55 | set { 56 | int i = idx.y * row_size + idx.x; 57 | Bits[i] = value; 58 | } 59 | } 60 | 61 | public void Set(Vector2i idx, bool val) 62 | { 63 | int i = idx.y * row_size + idx.x; 64 | Bits[i] = val; 65 | } 66 | 67 | public bool Get(Vector2i idx) 68 | { 69 | int i = idx.y * row_size + idx.x; 70 | return Bits[i]; 71 | } 72 | 73 | 74 | public Vector2i ToIndex(int i) { 75 | int b = i / row_size; 76 | i -= b * row_size; 77 | return new Vector2i(i, b); 78 | } 79 | public int ToLinear(Vector2i idx) { 80 | return idx.y * row_size + idx.x; 81 | } 82 | 83 | 84 | 85 | public IEnumerable Indices() 86 | { 87 | for ( int y = 0; y < Dimensions.y; ++y ) { 88 | for (int x = 0; x < Dimensions.x; ++x) 89 | yield return new Vector2i(x, y); 90 | } 91 | } 92 | 93 | 94 | public IEnumerable NonZeros() 95 | { 96 | for ( int i = 0; i < Bits.Count; ++i ) { 97 | if (Bits[i]) 98 | yield return ToIndex(i); 99 | } 100 | } 101 | 102 | 103 | 104 | 105 | 106 | 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /geometry3Sharp/spatial/DCurveProjection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace g3 7 | { 8 | public class DCurveProjectionTarget : IProjectionTarget 9 | { 10 | public DCurve3 Curve; 11 | 12 | 13 | public DCurveProjectionTarget(DCurve3 curve) 14 | { 15 | this.Curve = curve; 16 | } 17 | 18 | public Vector3d Project(Vector3d vPoint, int identifier = -1) 19 | { 20 | Vector3d vNearest = Vector3d.Zero; 21 | double fNearestSqr = double.MaxValue; 22 | 23 | int N = Curve.VertexCount; 24 | int NStop = (Curve.Closed) ? N : N - 1; 25 | for ( int i = 0; i < NStop; ++i ) { 26 | Segment3d seg = new Segment3d(Curve[i], Curve[(i + 1) % N]); 27 | Vector3d pt = seg.NearestPoint(vPoint); 28 | double dsqr = pt.DistanceSquared(vPoint); 29 | if (dsqr < fNearestSqr) { 30 | fNearestSqr = dsqr; 31 | vNearest = pt; 32 | } 33 | } 34 | 35 | return (fNearestSqr < double.MaxValue) ? vNearest : vPoint; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /geometry3Sharp/spatial/NormalHistogram.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace g3 7 | { 8 | /// 9 | /// Construct spherical histogram of normals of mesh. 10 | /// Binning is done using a Spherical Fibonacci point set. 11 | /// 12 | public class NormalHistogram 13 | { 14 | public int Bins = 1024; 15 | public SphericalFibonacciPointSet Points; 16 | public double[] Counts; 17 | 18 | public HashSet UsedBins; 19 | 20 | public NormalHistogram(int bins, bool bTrackUsed = false) 21 | { 22 | Bins = bins; 23 | Points = new SphericalFibonacciPointSet(bins); 24 | Counts = new double[bins]; 25 | if (bTrackUsed) 26 | UsedBins = new HashSet(); 27 | } 28 | 29 | /// 30 | /// legacy API 31 | /// 32 | public NormalHistogram(DMesh3 mesh, bool bWeightByArea = true, int bins = 1024) : this(bins) 33 | { 34 | CountFaceNormals(mesh, bWeightByArea); 35 | } 36 | 37 | 38 | /// 39 | /// bin and count point, and optionally normalize 40 | /// 41 | public void Count(Vector3d pt, double weight = 1.0, bool bIsNormalized = false) { 42 | int bin = Points.NearestPoint(pt, bIsNormalized); 43 | Counts[bin] += weight; 44 | if (UsedBins != null) 45 | UsedBins.Add(bin); 46 | } 47 | 48 | /// 49 | /// Count all input mesh face normals 50 | /// 51 | public void CountFaceNormals(DMesh3 mesh, bool bWeightByArea = true) 52 | { 53 | foreach (int tid in mesh.TriangleIndices()) { 54 | if (bWeightByArea) { 55 | Vector3d n, c; double area; 56 | mesh.GetTriInfo(tid, out n, out area, out c); 57 | Count(n, area, true); 58 | } else { 59 | Count(mesh.GetTriNormal(tid), 1.0, true); 60 | } 61 | } 62 | } 63 | 64 | 65 | /// 66 | /// return (quantized) normal associated w/ maximum weight/area 67 | /// 68 | public Vector3d FindMaxNormal() 69 | { 70 | int max_i = 0; 71 | for ( int k = 1; k < Bins; ++k ) { 72 | if (Counts[k] > Counts[max_i]) 73 | max_i = k; 74 | } 75 | return Points[max_i]; 76 | } 77 | 78 | 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /geometry3Sharp/spatial/SegmentSet2d.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace g3 5 | { 6 | // [TODO] some kind of spatial sorting!! 7 | public class SegmentSet2d 8 | { 9 | List Segments; 10 | 11 | public SegmentSet2d() 12 | { 13 | Segments = new List(); 14 | } 15 | 16 | public SegmentSet2d(GeneralPolygon2d poly) { 17 | Segments = new List(poly.Outer.SegmentItr()); 18 | foreach (var hole in poly.Holes) 19 | Segments.AddRange(hole.SegmentItr()); 20 | } 21 | 22 | public SegmentSet2d(List polys) 23 | { 24 | Segments = new List(); 25 | foreach (var poly in polys) { 26 | Segments.AddRange(poly.Outer.SegmentItr()); 27 | foreach (var hole in poly.Holes) 28 | Segments.AddRange(hole.SegmentItr()); 29 | } 30 | } 31 | 32 | 33 | /// 34 | /// Find any segment in set that intersects input segment. 35 | /// Returns intersection test, and index of segment 36 | /// 37 | public IntrSegment2Segment2 FindAnyIntersection(Segment2d seg, out int iSegment) 38 | { 39 | int N = Segments.Count; 40 | for (iSegment = 0; iSegment < N; ++iSegment) { 41 | IntrSegment2Segment2 intr = new IntrSegment2Segment2(seg, Segments[iSegment]); 42 | if (intr.Find()) 43 | return intr; 44 | } 45 | return null; 46 | } 47 | 48 | 49 | public void FindAllIntersections(Segment2d seg, List segmentTs, List indices = null, List tests = null, bool bOnlySimple = true) 50 | { 51 | int N = Segments.Count; 52 | for (int i = 0; i < N; ++i) { 53 | 54 | // want to make sure we do not miss any hits, even if it means 55 | // we get duplicates... 56 | IntrSegment2Segment2 intr = new IntrSegment2Segment2(seg, Segments[i]) { 57 | IntervalThreshold = MathUtil.ZeroTolerance 58 | }; 59 | 60 | if (intr.Find()) { 61 | if (bOnlySimple && intr.IsSimpleIntersection == false) 62 | continue; 63 | 64 | if (tests != null) 65 | tests.Add(intr); 66 | if (indices != null) 67 | indices.Add(i); 68 | if ( segmentTs != null ) { 69 | segmentTs.Add(intr.Parameter0); 70 | if (!intr.IsSimpleIntersection) 71 | segmentTs.Add(intr.Parameter1); 72 | } 73 | 74 | } 75 | } 76 | } 77 | 78 | 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /geometry3Sharp/spatial/SpatialFunctions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | 5 | namespace g3 6 | { 7 | 8 | // [TODO] delete this file if nobody is using NormalOffset 9 | 10 | // collection of utility classes 11 | public static class SpatialFunctions 12 | { 13 | 14 | // various offset-surface functions, in class so the compute functions 15 | // can be passed to other functions 16 | [System.Obsolete("NormalOffset is deprecated - is anybody using it? please lmk.")] 17 | public class NormalOffset 18 | { 19 | public DMesh3 Mesh; 20 | public ISpatial Spatial; 21 | 22 | public double Distance = 0.01; 23 | public bool UseFaceNormal = true; 24 | 25 | public Vector3d FindNearestAndOffset(Vector3d pos) 26 | { 27 | int tNearestID = Spatial.FindNearestTriangle(pos); 28 | DistPoint3Triangle3 q = MeshQueries.TriangleDistance(Mesh, tNearestID, pos); 29 | Vector3d vHitNormal = 30 | (UseFaceNormal == false && Mesh.HasVertexNormals) ? 31 | Mesh.GetTriBaryNormal(tNearestID, q.TriangleBaryCoords.x, q.TriangleBaryCoords.y, q.TriangleBaryCoords.z) 32 | : Mesh.GetTriNormal(tNearestID); 33 | return q.TriangleClosest + Distance * vHitNormal; 34 | } 35 | 36 | } 37 | 38 | 39 | } 40 | 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /geometry3Sharp/spatial/SpatialInterfaces.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace g3 5 | { 6 | // [TODO] this should be called IMeshSpatial? it is specific to triangles. 7 | public interface ISpatial 8 | { 9 | bool SupportsNearestTriangle { get; } 10 | 11 | /// 12 | /// Find id of triangle nearest to p within distance fMaxDist, or return DMesh3.InvalidID if not found 13 | /// 14 | int FindNearestTriangle(Vector3d p, double fMaxDist = double.MaxValue); 15 | 16 | bool SupportsTriangleRayIntersection{ get; } 17 | 18 | /// 19 | /// Find id of triangle intersected by ray, where intersection point is within distance fMaxDist, or return DMesh3.InvalidID if not found 20 | /// 21 | int FindNearestHitTriangle(Ray3d ray, double fMaxDist = double.MaxValue); 22 | 23 | bool SupportsPointContainment { get; } 24 | 25 | /// 26 | /// return true if query point is inside mesh 27 | /// 28 | bool IsInside(Vector3d p); 29 | } 30 | 31 | 32 | public interface IProjectionTarget 33 | { 34 | Vector3d Project(Vector3d vPoint, int identifier = -1); 35 | } 36 | 37 | public interface IOrientedProjectionTarget : IProjectionTarget 38 | { 39 | Vector3d Project(Vector3d vPoint, out Vector3d vProjectNormal, int identifier = -1); 40 | } 41 | 42 | public interface IIntersectionTarget 43 | { 44 | bool HasNormal { get; } 45 | bool RayIntersect(Ray3d ray, out Vector3d vHit, out Vector3d vHitNormal); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /help/KMPExpander.chm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/help/KMPExpander.chm -------------------------------------------------------------------------------- /help/KMPExpander.hhp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PabloMK7/KMPExpander/7364324700b9ae1eac5b28406760b7c38cd710bc/help/KMPExpander.hhp -------------------------------------------------------------------------------- /help/Table of Contents.hhc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
    11 |
  • 12 | 13 | 14 | 15 |
  • 16 | 17 | 18 | 19 |
  • 20 | 21 | 22 | 23 |
  • 24 | 25 | 26 | 27 |
  • 28 | 29 | 30 | 31 |
      32 |
    • 33 | 34 | 35 | 36 |
    • 37 | 38 | 39 | 40 |
    • 41 | 42 | 43 | 44 |
        45 |
      • 46 | 47 | 48 | 49 |
      • 50 | 51 | 52 | 53 |
      • 54 | 55 | 56 | 57 |
      • 58 | 59 | 60 | 61 |
      • 62 | 63 | 64 | 65 |
      • 66 | 67 | 68 | 69 |
      • 70 | 71 | 72 | 73 |
      • 74 | 75 | 76 | 77 |
      • 78 | 79 | 80 | 81 |
      • 82 | 83 | 84 | 85 |
      86 |
    87 |
88 | 89 | -------------------------------------------------------------------------------- /help/htm/DIV_File.htm: -------------------------------------------------------------------------------- 1 |

DIV Files

2 |

DIV Files are used for rendering. This section is still being written and will be added to the next KMP Expander release.

-------------------------------------------------------------------------------- /help/htm/File_types.htm: -------------------------------------------------------------------------------- 1 |

File Types

2 |

KMP Expander supports the following file formats:

3 |
    4 |
  • Editing Mario Kart 7 KMP files.
  • 5 |
  • Creating new Mario Kart 7 DIV files as well as a working BCMDL file from a CMDL that will be linked to the DIV file properly.
  • 6 |
  • Editing Mario Kart 7 UIMapPos.bin files.
  • 7 |
-------------------------------------------------------------------------------- /help/htm/KMP/camera_settings.htm: -------------------------------------------------------------------------------- 1 |

Camera Settings

2 |

Camera settings related help is still being developed, will be added in the next KMP Expander release.

-------------------------------------------------------------------------------- /help/htm/KMP/glider_routes.htm: -------------------------------------------------------------------------------- 1 |

Glider Routes

2 |

Glider routes are used in glide sections. They dictate the path karts should follow when gliding and prevent them from getting too far from the route. Glider routes are applied to CPU racers and the human player.

3 |

Group Settings

4 |

Group settings are displayed in the Group Settings view:

5 |
    6 |
  • Next: Lists all the possible groups that gliding karts can go to after finishing this one. One of these groups will be taken randomly. There can be up to 6 next groups, unused entries in the next list should be set to -1.
  • 7 |
  • Previous: Lists all the possible groups that gliding karts could have come from. IMPORTANT: if group X has group Y in the next list, group Y has group X in the previous list, otherwise the game may crash. There can be up to 6 previous groups, unused entries in the previous list should be set to -1.
  • 8 |
  • Unknown2: The purpose of this field is unknown, normally 0.
  • 9 |
  • CannonSection: The group acts as a cannon route. If this flag is set to TrueForceToRoute must be also set to True.
  • 10 |
  • ForceToRoute: Karts are forced to follow the route and can't leave it, they are also forced to land when the route finishes. Otherwise they can continue flying.
  • 11 |
  • PreventRaising: Karts can only fly forwards or downwards, so after they have descended they are not able to ascend again.
  • 12 |
13 |

Normally Next and Previous are never used in original tracks as there is only one group per gliding section.

14 |

Parameters

15 |

Parameters are displayed in the entry list:

16 |
    17 |
  • PositionXYZ: Position of the Glider Point.
  • 18 |
  • Scale: Scale of the glider point. This is represented as a circle in the editor, karts are able to move within this circle. (Note that ingame, they are not circles but spheres).
  • 19 |
  • Unknown1/2: The purpose of these parameters are unknown, normally 0.
  • 20 |
21 |

Tips

22 |
    23 |
  • Make sure that if group X has group Y in the next list, group Y has group X in the previous list, otherwise the game may crash.
  • 24 |
  • Make sure all the glider points are inside the checkpoints, otherwise the game will crash.
  • 25 |
  • Make sure all the glider points are avobe Y=0 (failsafe death barrier), otherwise the game may crash.
  • 26 |
  • It is recommended to set the ForceToRoute flag to True so karts will follow the route more precisely.
  • 27 |
-------------------------------------------------------------------------------- /help/htm/KMP/item_points.htm: -------------------------------------------------------------------------------- 1 |

Item Routes

2 |

Item routes are used by red shells and blue shells to know where to go in tracks. Each route group is linked to other groups via its group settings and each point of the group has its own flags and parameters.

3 |

Group Settings

4 |

Group settings are displayed in the Group Settings view:

5 |
    6 |
  • Next: Lists all the possible groups that items can go to after finishing this one. One of these groups will be taken randomly. There can be up to 6 next groups, unused entries in the next list should be set to -1.
  • 7 |
  • Previous: Lists all the possible groups that items could have come from. IMPORTANT: if group X has group Y in the next list, group Y has group X in the previous list, otherwise the game may crash. There can be up to 6 previous groups, unused entries in the previous list should be set to -1.
  • 8 |
9 |

Parameters

10 |

Parameters are displayed in the entry list:

11 |
    12 |
  • PositionXYZ: Position of the Item Point.
  • 13 |
  • Scale: Scale of the item point. This is represented as a circle in the editor, shells will choose a point on each item entry within this circle to go to, so make sure that the whole circle is inside the road. (Note that ingame, they are not circles but spheres).
  • 14 |
  • GravityMode: Controls how gravity affect shells: 15 |
      16 |
    • 0 - Affected by Gravity: Items will fall to the ground. (Default)
    • 17 |
    • 1 - Unaffected By Gravity: Items will fly to follow the route. (Used in places where there is no ground and items should fly, such as gliding sections or big jumps.)
    • 18 |
    • 2 - Cannon Section: Same as Unaffected By Gravity but items will fly faster. (Used in cannon sections.)
    • 19 |
    20 |
  • 21 |
  • PlayerScanRadius: Controls the scan radius of shells to target players. The scan radius is shown in the editor as a dashed circle:
    22 |
      23 |
    • 0 - Small: Small radius of 300 units. (Default)
    • 24 |
    • 1 - Big: Big radius of 900 units. (Used in wide sections)
    • 25 |
    26 |
  • 27 |
28 |

Tips

29 |
    30 |
  • Make sure that if group X has group Y in the next list, group Y has group X in the previous list, otherwise the game may crash.
  • 31 |
  • Make sure all the item points are inside the checkpoints, otherwise the game will crash.
  • 32 |
  • Make sure all the item points are above Y=0 (failsafe death barrier), otherwise the game may crash.
  • 33 |
  • If shells fall or crash on walls because they can't make a jump, remember to set GravityMode to 1. Remember to set the value to 2 in cannon sections.
  • 34 |
  • Only use the Big value of PlayerScanRadius if it's needed to scan a larger area, otherwise use Small.
  • 35 |
-------------------------------------------------------------------------------- /help/htm/KMP/respawn_points.htm: -------------------------------------------------------------------------------- 1 |

Respawn Points

2 |

Respawn points are used to respawn karts and blue shells when they go through a fall boundary. Respawn points are linked to checkpoints by the checkpoint RespawnID parameter.

3 |

Parameters

4 |

Parameters are displayed in the entry list:

5 |
    6 |
  • PositionXYZ: Position of the respawn point.
  • 7 |
  • RotationXYZ: Rotation of the respawn point. The direction of the respawn point is shown in the editor (based of the RotationY value).
  • 8 |
  • Unknown: The purpose of this parameter is unknown, normally FFFF.
  • 9 |
10 |

Tips

11 |
    12 |
  • You can create as many respawn points as the number of checkpoints. It is recommended to space the respawn points so there aren't any large sections of the track without them, even if it is not possible to fall, just in case.
  • 13 |
  • Make sure you set the RotationY of the point properly. Use the line shown in the editor to check the direction. 
  • 14 |
  • Keep in mind that after a CPU Racer respawns, they will search for the closest Enemy Point to their respawn point to follow.
  • 15 |
-------------------------------------------------------------------------------- /help/htm/KMP/routes.htm: -------------------------------------------------------------------------------- 1 |

Routes

2 |

Routes are general purpose paths used with other KMP Sections.

3 |

Group Settings

4 |

Group settings are displayed in the Group Settings view:

5 |
    6 |
  • Loop: Defines if the route is looped. If set to True, whatever thing is linked to the route will go to the first point after finishing the last one.
  • 7 |
  • Smooth: Defines if the route path is smoothen. Recommended for opening cameras.
  • 8 |
9 |

Parameters

10 |

Parameters are displayed in the entry list:

11 |
    12 |
  • PositionXYZ: Position of the Enemy Point.
  • 13 |
  • Speed: The speed of the route. This parameter is not used by some Objects (one of the Settings of the object is used instead). Route speed is interpolated between points, so if you don't want whatever thing is linked to the route to never finish the route, set the last point speed to 0.
  • 14 |
  • Setting2: Used by some Objects, its meaning is ObjectType specific. (Default value is 0). 
  • 15 |
16 |

Tips

17 |
    18 |
  • Since Routes are for general purpose, there are no Route specific tips.
  • 19 |
-------------------------------------------------------------------------------- /help/htm/KMP/start_positions.htm: -------------------------------------------------------------------------------- 1 |

Start Positions

2 |

Start Positions are only used in battle tracks so in normal tracks, this section is empty. There has to be 8 different start positions in battle tracks, otherwise, the game will crash. Once the battle starts, each player will be placed in one of the start positions randomly.

3 |

Parameters

4 |
    5 |
  • PositionXYZPosition of the point.
  • 6 |
  • RotationXYZ: Rotation of the point (RotationY is the most useful one, represented by a line in the editor).
  • 7 |
-------------------------------------------------------------------------------- /help/htm/KMP_expander.htm: -------------------------------------------------------------------------------- 1 |

KMP Expander

2 |

KMP Expander is a tool that allows the editing of several Mario Kart 7 track files.

3 |

You will find information about each file format in this manual as well as some tips about KMP stuff.

4 |

To open, save and close KMP, UIMapPos and DIV files, use the File menu.

5 |

NOTE: This manual is not final, some sections are missing or may be wrong.

-------------------------------------------------------------------------------- /help/htm/OBJ_Manager.htm: -------------------------------------------------------------------------------- 1 |

OBJ Manager

2 |

KMP Expander allows to open a Wavefront .obj file which will be displayed in the editor below the kmp data. This helps having a perspective on how the kmp data will be positioned in the track. Furthermore, by right clicking on compatible entry points, its Y coordinate will be calculated automatically.

3 |

OBJ Manager Window

4 |

The OBJ manager window can be opened by clicking OBJ Manager under the Tools menu.

5 |
    6 |
  • Load OBJ: Opens an .obj file.
  • 7 |
  • Close OBJ: Closes the currently loaded .obj file.
  • 8 |
  • Render OBJ: Enables/Disables OBJ rendering in the editor.
  • 9 |
  • Wireframe: Only the lines connecting vertices will be displayed instead of the full model. This is useful to know which triangles will be affected by DIV boxes.
  • 10 |
  • Material: Selects a material from the .obj
  • 11 |
  • Material Settings: Allows to change some settings from the current selected material. (Description about each parameter can be found below the Material Settings view).
  • 12 |
13 |

Tips

14 |
    15 |
  • If your model shows completely black, make sure the texture is showing correctly in the texture view and that the diffuse color is not black.
  • 16 |
-------------------------------------------------------------------------------- /help/htm/Options.htm: -------------------------------------------------------------------------------- 1 |

Options

2 |

KMP Expander options can be changed under the Tools menu. From the options you can change several editor settings such as point colors and sizes. (See the settings menu for a description of each setting.)

-------------------------------------------------------------------------------- /help/htm/UIMapPos.htm: -------------------------------------------------------------------------------- 1 |

UIMapPos

2 |

The UIMapPos file controls how the local and global minimaps are placed in the bottom screen ingame. To open, save and close UIMapPos files, go to the File menu. KMP expander only allows to edit local minimap position as how the global minimap coordinates are handled is unknown.

3 |

From the Tools->UIMapPos menu you can load an image to the local map box shown in the editor as well as toggle its view.

4 |

Local Minimap

5 |

The local minimap will be displayed in the editor as a black box with two black points on two of its corners. You can move those points to adjust the size of the black box so it matches the 3D model properly.

6 |

Tips

7 |

If you load a minimap image, you won't be able to see the OBJ model as it is covered by the image itself. However, you can open the minimap image with an image editor and change its transparency. That way the transparency will also be applied in the editor and you will be able to see the OBJ model through the minimap.

-------------------------------------------------------------------------------- /help/htm/User Interface.htm: -------------------------------------------------------------------------------- 1 |

User Interface

2 |

KMP Expander is divided in four sections:

3 |
    4 |
  • Tree View (Top Left)From the tree view you can select which KMP/DIV section or section group is loaded to the entry list and group settings view. By right clicking on compatible section groups you will be able to add new groups or remove existing ones. By checking or unchecking the checkbox, that specific section/group will be hidden in the editor.
  • 5 |
  • Group Settings (Botom Left): Allows to change the settings for the current selected group (see section specific help for details).
  • 6 |
  • Entry List (Bottom Right): Displays all the entries of the current selected section/group. You can also edit individual parameters for each entry (see section specific help for details). There are several controls in the top part of the entry list: 7 |
      8 |
    • Add Entry (+): Adds a new entry below the selected one with default parameters.
    • 9 |
    • Remove Entry (-): Removes the current selected entry.
    • 10 |
    • Shift Up/Down (^,v): Moves up or down in the list the current selected entry.
    • 11 |
    • Toggle Draw Mode (ItemBox with cursor): With draw mode enabled, clicking on the editor will place a new point where the cursor is instead of selecting/moving existing points. Click again to disable.
    • 12 |
    • Change View Plane: Changes the camera position in the Editor: 13 |
        14 |
      • XZ: Top to bottom.
      • 15 |
      • XY: Back to front.
      • 16 |
      • ZY: Left to right.
      • 17 |
      18 |
    • 19 |
    • Play Intro Cameras: (Camera):Plays the track intro cameras. Press the Escape key to stop.
    • 20 |
    21 |
  • 22 |
  • Editor (Top Right): This is where all the visible section points will be displayed as well as the UIMapPos image, DIV boxes and loaded OBJ. You can use the editor to move existing points or place new ones with the Draw Mode enabled by left clicking. If an OBJ is loaded, right clicking on a point will calculate its Y position based on the OBJ geometry.
  • 23 |
-------------------------------------------------------------------------------- /help/htm/kmp_file.htm: -------------------------------------------------------------------------------- 1 |

KMP File

2 |

KMP files contain all the information about Mario Kart 7 tracks that isn't collission or scenary, this includes item boxes, coins, enemy paths, etc. You can use this tool to edit all of these parameters that can be found in the file:

3 |
    4 |
  • Start Positions
  • 5 |
  • Enemy Routes
  • 6 |
  • Item Routes
  • 7 |
  • Glider Routes
  • 8 |
  • Checkpoints
  • 9 |
  • Respawn Points
  • 10 |
  • Objects
  • 11 |
  • Routes
  • 12 |
  • Areas
  • 13 |
  • Cameras
  • 14 |
15 |

You can find information about those parameters in their respective help pages.

--------------------------------------------------------------------------------