public override bool Intersects(Ray ray, out STriangle hitTriangle, out float hitDistance) { BoundingBox boundingBox = m_mesh.BoundingBox.TransformBoundingBox(m_transform.WorldMatrix); if (ray.Intersects(ref boundingBox, out hitDistance)) { if (m_sourceAsset == null || m_sourceAsset.PrimitiveTopology != PrimitiveTopology.TriangleList) { hitTriangle = new STriangle(); return(false); } } else { hitTriangle = new STriangle(); return(false); } Matrix worldTransform = m_transform.WorldMatrix; var closestHit = (0, 1e10f); bool bTriangleHit = false; for (int i = 0; i < m_sourceAsset.IndexData.Length - 2; i += 3) { Vector3 vert1 = (Vector3)Vector3.Transform(m_sourceAsset.VertexData[m_sourceAsset.IndexData[i]].position, worldTransform); Vector3 vert2 = (Vector3)Vector3.Transform(m_sourceAsset.VertexData[m_sourceAsset.IndexData[i + 1]].position, worldTransform); Vector3 vert3 = (Vector3)Vector3.Transform(m_sourceAsset.VertexData[m_sourceAsset.IndexData[i + 2]].position, worldTransform); if (ray.Intersects(ref vert1, ref vert2, ref vert3, out float distance)) { if (distance < closestHit.Item2) { closestHit = (i, distance); bTriangleHit = true; } } } if (!bTriangleHit) { hitTriangle = new STriangle(); return(false); } Vector3 p1 = (Vector3)Vector3.Transform(m_sourceAsset.VertexData[m_sourceAsset.IndexData[closestHit.Item1]].position, worldTransform); Vector3 p2 = (Vector3)Vector3.Transform(m_sourceAsset.VertexData[m_sourceAsset.IndexData[closestHit.Item1 + 1]].position, worldTransform); Vector3 p3 = (Vector3)Vector3.Transform(m_sourceAsset.VertexData[m_sourceAsset.IndexData[closestHit.Item1 + 2]].position, worldTransform); hitTriangle = new STriangle(p1, p2, p3); hitDistance = closestHit.Item2; return(true); }
private STriangle[] CreateCube(OpenTK.Vector3 position, float size) { STriangle[] Triangles = new STriangle[2 * CUBE_MSIDES]; Base[] basis = new Base[6]; basis[0].top = new OpenTK.Vector3(+0, +1, +0); basis[0].left = new OpenTK.Vector3(-1, +0, +0); basis[0].right = new OpenTK.Vector3(+1, +0, +0); basis[0].bottom = new OpenTK.Vector3(+0, -1, +0); basis[0].align = new OpenTK.Vector3(+0, +0, +1); basis[1].top = new OpenTK.Vector3(+0, +1, +0); basis[1].left = new OpenTK.Vector3(-1, +0, +0); basis[1].right = new OpenTK.Vector3(+1, +0, +0); basis[1].bottom = new OpenTK.Vector3(+0, -1, +0); basis[1].align = new OpenTK.Vector3(+0, +0, -1); basis[2].top = new OpenTK.Vector3(+0, +1, +0); basis[2].left = new OpenTK.Vector3(+0, +0, +1); basis[2].right = new OpenTK.Vector3(+0, +0, -1); basis[2].bottom = new OpenTK.Vector3(+0, -1, +0); basis[2].align = new OpenTK.Vector3(-1, +0, +0); basis[3].top = new OpenTK.Vector3(+0, -1, +0); basis[3].left = new OpenTK.Vector3(+0, +0, +1); basis[3].right = new OpenTK.Vector3(+0, +0, -1); basis[3].bottom = new OpenTK.Vector3(+0, +1, +0); basis[3].align = new OpenTK.Vector3(+1, +0, +0); basis[4].top = new OpenTK.Vector3(+0, +0, +1); basis[4].left = new OpenTK.Vector3(-1, +0, +0); basis[4].right = new OpenTK.Vector3(+1, +0, +0); basis[4].bottom = new OpenTK.Vector3(+0, +0, -1); basis[4].align = new OpenTK.Vector3(+0, +1, +0); basis[5].top = new OpenTK.Vector3(+0, +0, +1); basis[5].left = new OpenTK.Vector3(-1, +0, +0); basis[5].right = new OpenTK.Vector3(+1, +0, +0); basis[5].bottom = new OpenTK.Vector3(+0, +0, -1); for (int i = 0; i < CUBE_MSIDES; i++) { Triangles[2 * i + 0].v1 = position + size * (basis[i].align + basis[i].right + basis[i].top); Triangles[2 * i + 0].v2 = position + size * (basis[i].align + basis[i].left + basis[i].bottom); Triangles[2 * i + 0].v3 = position + size * (basis[i].align + basis[i].right + basis[i].bottom); Triangles[2 * i + 1].v1 = position + size * (basis[i].align + basis[i].right + basis[i].top); Triangles[2 * i + 1].v2 = position + size * (basis[i].align + basis[i].left + basis[i].top); Triangles[2 * i + 1].v3 = position + size * (basis[i].align + basis[i].left + basis[i].bottom); } return(Triangles); }
private void LoadCubes() { STriangle[] Triangles = new STriangle[0]; for (int i = 0; i < CUBE_COUNT; i++) { STriangle[] NextTriangles = CreateCube(CubePositions[i], CubeSizes[i]); Triangles = Triangles.Union(NextTriangles).ToArray(); } for (int i = 0, CubeIndex = 0; i < Triangles.Length; i++) { SetUni1("CubeTriangles[" + i + "].MaterialIdx", CubeMaterials[CubeIndex]); SetUni3("CubeTriangles[" + i + "].v1", Triangles[i].v1); SetUni3("CubeTriangles[" + i + "].v2", Triangles[i].v2); SetUni3("CubeTriangles[" + i + "].v3", Triangles[i].v3); CubeIndex = i / CUBE_TRIANGLES_COUNT; } }
private STriangle[] CreateCube(OpenTK.Vector3 Position, float size) { STriangle[] Triangles = new STriangle[2 * CUBE_SIDES_COUNT]; Side[] sides = new Side[6]; // back sides[0].up = new OpenTK.Vector3(0, size, 0); sides[0].left = new OpenTK.Vector3(-size, 0, 0); sides[0].right = new OpenTK.Vector3(size, 0, 0); sides[0].bottom = new OpenTK.Vector3(0, -size, 0); sides[0].align = new OpenTK.Vector3(0, 0, size); // front sides[1].up = new OpenTK.Vector3(0, size, 0); sides[1].left = new OpenTK.Vector3(-size, 0, 0); sides[1].right = new OpenTK.Vector3(size, 0, 0); sides[1].bottom = new OpenTK.Vector3(0, -size, 0); sides[1].align = new OpenTK.Vector3(0, 0, -size); // left sides[2].up = new OpenTK.Vector3(0, size, 0); sides[2].left = new OpenTK.Vector3(0, 0, size); sides[2].right = new OpenTK.Vector3(0, 0, -size); sides[2].bottom = new OpenTK.Vector3(0, -size, 0); sides[2].align = new OpenTK.Vector3(-size, 0, 0); // right sides[3].up = new OpenTK.Vector3(0, -size, 0); sides[3].left = new OpenTK.Vector3(0, 0, size); sides[3].right = new OpenTK.Vector3(0, 0, -size); sides[3].bottom = new OpenTK.Vector3(0, size, 0); sides[3].align = new OpenTK.Vector3(size, 0, 0); // top sides[4].up = new OpenTK.Vector3(0, 0, size); sides[4].left = new OpenTK.Vector3(-size, 0, 0); sides[4].right = new OpenTK.Vector3(size, 0, 0); sides[4].bottom = new OpenTK.Vector3(0, 0, -size); sides[4].align = new OpenTK.Vector3(0, size, 0); // bottom sides[5].up = new OpenTK.Vector3(0, 0, size); sides[5].left = new OpenTK.Vector3(-size, 0, 0); sides[5].right = new OpenTK.Vector3(size, 0, 0); sides[5].bottom = new OpenTK.Vector3(0, 0, -size); sides[5].align = new OpenTK.Vector3(0, -size, 0); for (int i = 0; i < CUBE_SIDES_COUNT; i++) { Triangles[2 * i + 0].v1 = Position + sides[i].align + sides[i].right + sides[i].up; Triangles[2 * i + 0].v2 = Position + sides[i].align + sides[i].left + sides[i].bottom; Triangles[2 * i + 0].v3 = Position + sides[i].align + sides[i].right + sides[i].bottom; Triangles[2 * i + 1].v1 = Position + sides[i].align + sides[i].right + sides[i].up; Triangles[2 * i + 1].v2 = Position + sides[i].align + sides[i].left + sides[i].up; Triangles[2 * i + 1].v3 = Position + sides[i].align + sides[i].left + sides[i].bottom; } return(Triangles); }
public abstract bool Intersects(Ray ray, out STriangle hitTriangle, out float hitDistance);
private void ProcessMesh() { MeshFilter originalMeshFilter = GetComponentInChildren <MeshFilter>(); Mesh rawMesh = originalMeshFilter.mesh; int[] rawTris = rawMesh.triangles; // Triplets of indices into the vertex array. Vector3[] rawVerts = rawMesh.vertices; Vector2[] rawUvs = rawMesh.uv; // Color coordinates on the material's palette. // Convert the mesh into a triangles list. List <STriangle> allTriangles = new List <STriangle>(); for (int i = 0; i < rawTris.Length; i += 3) { STriangle currentTriangle = new STriangle(); currentTriangle.a = rawTris[i]; currentTriangle.b = rawTris[i + 1]; currentTriangle.c = rawTris[i + 2]; currentTriangle.uv = rawUvs[currentTriangle.a]; allTriangles.Add(currentTriangle); } // Dictionary key is the texture UVs of the triangle on the MagicaVoxel color palette. Dictionary <Vector2, List <STriangle> > meshDataDictionary = new Dictionary <Vector2, List <STriangle> >(); // Split the triangles out into meshes based on their texture UVs. foreach (STriangle triangle in allTriangles) { if (!meshDataDictionary.ContainsKey(triangle.uv)) { meshDataDictionary[triangle.uv] = new List <STriangle>(); } meshDataDictionary[triangle.uv].Add(triangle); } foreach (Vector2 key in meshDataDictionary.Keys) { List <STriangle> values = meshDataDictionary[key]; MeshFilter newMeshObject = GameObject.Instantiate(originalMeshFilter); newMeshObject.mesh = new Mesh(); newMeshObject.mesh.vertices = rawVerts; List <int> tris = new List <int>(); foreach (STriangle triangle in values) { tris.Add(triangle.a); tris.Add(triangle.b); tris.Add(triangle.c); } newMeshObject.mesh.SetTriangles(tris, submesh: 0); newMeshObject.mesh.normals = rawMesh.normals; newMeshObject.mesh.uv = rawMesh.uv; newMeshObject.mesh.RecalculateBounds(); // Set up colliders MeshCollider newCollider = newMeshObject.GetComponent <MeshCollider>(); newCollider.sharedMesh = newMeshObject.mesh; // Get data based on the color of this voxel MeshRenderer newMeshRenderer = newMeshObject.GetComponent <MeshRenderer>(); Color voxelColor = meshData.GetColorFromMaterial(newMeshRenderer.material, key); if (logColors) { // Log the color and if you double-click on the message in the Console, you'll select it in the Hierarchy. Debug.Log(voxelColor, newMeshObject.gameObject); } MagicaVoxelRuntimeMeshSplitterData.STerrainData colorData = meshData.GetTerrainDataFromVoxelColor(voxelColor); newCollider.material = colorData.physicsMaterial; newMeshRenderer.material = colorData.renderMaterial; } // Disable the original so that it doesn't overlap with the split meshes. originalMeshFilter.gameObject.SetActive(false); }
public override bool Intersects(Ray ray, out STriangle hitTriangle, out float hitDistance) { hitTriangle = new STriangle(); hitDistance = -1.0f; return(false); }