private Dictionary <int, int> indexLookup;//= new Dictionary<int, int>(); private void BuildMeshForObject() { List <int> triangles = new List <int>(); // Use a BSP tree to find nearby triangles at log(n) speeds. tree.FindClosestTriangles(position, scale, triangles); // Calculate the matrix needed to transform a point from the obj's local mesh, to our local mesh. // Matrix4x4 mat = transform.worldToLocalMatrix * obj.transform.localToWorldMatrix; // Clear the index lookup, we use it to check which verticies are shared. // This keeps us from having to rebuild the mesh so intricately. indexLookup = new Dictionary <int, int>(triangles.Count); // TODO: split this up into more jobs. for (int i = 0; i < triangles.Count; i++) { // We use the indices of the original mesh's triangles to determine which // verticies are shared. So we don't have to calculate that ourselves. // we grab them here. int i1, i2, i3; tree.GetIndices(triangles [i], out i1, out i2, out i3); // Here we get the points of the obj's mesh in our local space. Vector3 v1, v2, v3; tree.GetVertices(triangles [i], out v1, out v2, out v3); v1 = mat.MultiplyPoint(v1); v2 = mat.MultiplyPoint(v2); v3 = mat.MultiplyPoint(v3); Vector3 n1, n2, n3; tree.GetNormals(triangles [i], out n1, out n2, out n3); // We do a quick normal calculation to see if the triangle is mostly facing us. // we have to recalculate it since the normal is different in our local space // (maybe we could just transform the original bsptree's precomputed normals with the matrix ?) Vector3 side1 = v2 - v1; Vector3 side2 = v3 - v1; Vector3 normal = Vector3.Cross(side1, side2).normalized; if (normal.y <= 0.2f) { continue; } // To prevent z-fighting, I randomly offset each vertex by the normal. v1 += normal * offset; v2 += normal * offset; v3 += normal * offset; // First we check to see if a vertex has already been grabbed and calculated. // If it has been, we just use that as the index for the triangle. // Otherwise we create a new vertex, with coorisponding UV mapping. // Since we're in a local space where the decal spans from -0.5f to 0.5f, // Our UV is just the x and z values in the space offset by 0.5f int ni1, ni2, ni3; if (!indexLookup.TryGetValue(i1, out ni1)) { verts.Add(v1); uvs.Add(new Vector2(v1.x + 0.5f, v1.z + 0.5f)); normals.Add(rotation * n1); ni1 = verts.Count - 1; indexLookup [i1] = ni1; } if (!indexLookup.TryGetValue(i2, out ni2)) { verts.Add(v2); uvs.Add(new Vector2(v2.x + 0.5f, v2.z + 0.5f)); normals.Add(rotation * n2); ni2 = verts.Count - 1; indexLookup [i2] = ni2; } if (!indexLookup.TryGetValue(i3, out ni3)) { verts.Add(v3); uvs.Add(new Vector2(v3.x + 0.5f, v3.z + 0.5f)); normals.Add(rotation * n3); ni3 = verts.Count - 1; indexLookup [i3] = ni3; } // Finally we add the triangle to the triangle list. tri.AddLast(ni1); tri.AddLast(ni2); tri.AddLast(ni3); } }