public ModelShape(Model model) { var positionsByteArray = model.Meshes[0].Attributes["POSITION"].BufferData; var positionsFloatArray = new float[positionsByteArray.Length / 4]; Buffer.BlockCopy(positionsByteArray, 0, positionsFloatArray, 0, positionsByteArray.Length); var positions = new List <JVector>(); for (var i = 0; i < positionsFloatArray.Length / 3; i++) { positions.Add(new JVector(positionsFloatArray[i * 3], positionsFloatArray[i * 3 + 1], positionsFloatArray[i * 3 + 2])); } var indicesByteArray = model.Meshes[0].Attributes["INDEX"].BufferData; var indicesShortArray = new short[indicesByteArray.Length / 2]; Buffer.BlockCopy(indicesByteArray, 0, indicesShortArray, 0, indicesByteArray.Length); var tris = new List <TriangleVertexIndices>(); for (var i = 0; i < indicesShortArray.Length / 3; i++) { tris.Add(new TriangleVertexIndices(indicesShortArray[i * 3], indicesShortArray[i * 3 + 1], indicesShortArray[i * 3 + 2])); } var octree = new Octree(positions, tris); octree.BuildOctree(); Shape = new TriangleMeshShape(octree); }
/* * public bool CreateChunk(int octreeSize, Vector3 position) * { * min = position - new Vector3(octreeSize / 2, octreeSize / 2, octreeSize / 2); * Vector3 octreePos = new Vector3(position.x - (octreeSize / 2), position.y - (octreeSize / 2), position.z - (octreeSize / 2)); * root = tree.BuildOctree(octreePos, octreeSize); * * if (root == null && meshObject != null) * { * DestroyMesh(); * } * * return root != null; * } */ public bool CreateChunk(ComputeShader computeShader, int lod, Vector3 position) { LOD = lod; if (LOD < 1) { LOD = 1; } else if (LOD > 6) { LOD = 6; } int octreeSize = (int)Mathf.Pow(2, LOD); min = position - new Vector3(octreeSize / 2, octreeSize / 2, octreeSize / 2); Vector3 octreePos = new Vector3(position.x - (octreeSize / 2), position.y - (octreeSize / 2), position.z - (octreeSize / 2)); root = tree.BuildOctree(computeShader, octreePos, octreeSize); if (root == null && meshObject != null) { DestroyMesh(); } return(root != null); }
public static TriangleMeshShape Load(string filename) { int lineIndex = 2; // This function is very similar to the main mesh loading function, but physics meshes generally contain // less data (fewer vertices and no texture coordinates). Physics meshes also aren't cached in the same way // as regular models (since triangle meshes tend to be loaded in large chunks infrequently as the player // moves around the world). string[] lines = File.ReadAllLines(Paths.Meshes + filename); string line = lines[lineIndex]; // Parse points. List <JVector> points = new List <JVector>(); do { points.Add(ParseJVector(line)); line = lines[++lineIndex]; }while (line[0] == 'v' && line[1] != 'n'); // Normals may or may not be present in the exported .obj file. while (line[1] == 'n') { line = lines[++lineIndex]; } // The next line is smoothing ("s off"), which isn't relevant. lineIndex++; // Parse triangles. All remaining lines should be faces. List <TriangleVertexIndices> tris = new List <TriangleVertexIndices>(); do { // With only indices exported, each face line looks like "f 1 2 3". string[] tokens = lines[lineIndex++].Split(' '); // If normals were exported, each token will look like "1/2/3" instead. Also note that assigning // indices in the opposite order (2-1-0 rather than 0-1-2) causes Jitter to process triangles in the // correct direction (without having to flip normals in Blender). int i2 = int.Parse(tokens[1].Split('/')[0]) - 1; int i1 = int.Parse(tokens[2].Split('/')[0]) - 1; int i0 = int.Parse(tokens[3].Split('/')[0]) - 1; tris.Add(new TriangleVertexIndices(i0, i1, i2)); }while (lineIndex < lines.Length); var octree = new Octree(points, tris); octree.BuildOctree(); // TODO: Lists are attached to the triangle mesh for debug rendering. They should be removed later. var shape = new TriangleMeshShape(octree); shape.Tag = new Tuple <List <JVector>, List <TriangleVertexIndices> >(points, tris); return(shape); }
public void CreateMesh(List <Vector3> vertices, List <TriangleVertexIndices> triangleVertexIndices, int maxTrianglesPerCell, float minCellSize) { var numVertices = vertices.Count; Octree.Clear(true); Octree.AddTriangles(vertices, triangleVertexIndices); Octree.BuildOctree(maxTrianglesPerCell, minCellSize); this.maxTrianglesPerCell = maxTrianglesPerCell; this.minCellSize = minCellSize; }
public static TriangleMeshShape GetTriangleMeshShape(this Mesh3 mesh) { Octree octree = new Octree( mesh.Vertices.Select(x => new JVector((float)x.X, (float)x.Y, (float)x.Z)).ToList(), Enumerable.Range(0, mesh.TriangleCount).Select(x => new TriangleVertexIndices( mesh.TriangleIndices[x * 3 + 2], mesh.TriangleIndices[x * 3 + 1], mesh.TriangleIndices[x * 3])).ToList()); octree.BuildOctree(); return(new TriangleMeshShape(octree)); }
public override Task Rebuild() { this.DebugDepth("Rebuild"); return(Task.Run(() => { using (RebuildLock()) { using (new CenterAndHeightMaintainer(this)) { #if true ISdf shape = new Sphere() { Radius = Size }; if (Shape == Shapes.Box) { shape = new Box() { Size = new Vector3(Size, Size, Size) }; } var bounds = shape.Bounds; bounds.Expand(.1); if (Iterations > 7) { Iterations = 7; } var root = Octree.BuildOctree(shape.Sdf, bounds.MinXYZ, bounds.Size, Iterations, Threshold); Mesh = Octree.GenerateMeshFromOctree(root); #else var c = new MarchingCubes(); c.Generate(); MeshNormals.QuickCompute(c.Mesh); // generate normals Mesh = c.Mesh.ToMesh(); #endif } } Invalidate(InvalidateType.DisplayValues); Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); return Task.CompletedTask; })); }
protected override Shape MakeShape() { var mf = GetComponent <MeshFilter>(); var mesh = mf.mesh; if (mesh == null) { Debug.Log("No Mesh found!"); return(null); } if (IsTrigger || Convex) { Convex = IsTrigger; return(new ConvexHullShape(GetComponent <MeshFilter>().mesh.vertices.Select(vert => vert.ConvertToJVector()).ToList())); } var positions = new List <JVector>(); var indices = new List <TriangleVertexIndices>(); var vertices = mesh.vertices; var count = mesh.vertices.Length; var scale = transform.lossyScale; for (var i = 0; i < count; i++) { var v = vertices[i]; v.x *= scale.x; v.y *= scale.y; v.z *= scale.z; positions.Add(new JVector(v.x, v.y, v.z)); } count = mesh.triangles.Length; var triangles = mesh.triangles; for (var i = 0; i < count; i += 3) { indices.Add(new TriangleVertexIndices(triangles[i], triangles[i + 2], triangles[i + 1])); } var octree = new Octree(positions, indices); octree.BuildOctree(); return(new TriangleMeshShape(octree)); }
void Start() { PlayerInput.Start(); thresholdIndex = (thresholdIndex + 1) % MAX_THRESHOLDS; List <MeshVertex> vertices = new List <MeshVertex>(); List <int> indices = new List <int>(); root = Octree.BuildOctree(new Vector3(-octreeSize / 2, -octreeSize / 2, -octreeSize / 2), octreeSize, THRESHOLDS[thresholdIndex]); if (root == null) { Debug.Log("root is null"); } Octree.GenerateMeshFromOctree(root, vertices, indices); }
protected override Shape MakeShape() { var mf = GetComponent<MeshFilter>(); var mesh = mf.mesh; if (mesh == null) { Debug.Log("No Mesh found!"); return null; } if (IsTrigger || Convex) { Convex = IsTrigger; return new ConvexHullShape(GetComponent<MeshFilter>().mesh.vertices.Select(vert => vert.ConvertToJVector()).ToList()); } var positions = new List<JVector>(); var indices = new List<TriangleVertexIndices>(); var vertices = mesh.vertices; var count = mesh.vertices.Length; var scale = transform.lossyScale; for (var i = 0; i < count; i++) { var v = vertices[i]; v.x *= scale.x; v.y *= scale.y; v.z *= scale.z; positions.Add(new JVector(v.x, v.y, v.z)); } count = mesh.triangles.Length; var triangles = mesh.triangles; for (var i = 0; i < count; i += 3) { indices.Add(new TriangleVertexIndices(triangles[i], triangles[i + 2], triangles[i + 1])); } var octree = new Octree(positions, indices); octree.BuildOctree(); return new TriangleMeshShape(octree); }