public IntersectionInfo(float distance, Vector3 intersectionPoint, Face3 face, int faceIndex, Object3D o) { Distance = distance; IntersectionPoint = intersectionPoint; Face = face; FaceIndex = faceIndex; Object = o; }
// Analytically subdivide a face to the required detail level. private void Subdivide(List<VertexInfo> vertexSet, Face3 face, int detail) { var cols = Mathf.Pow(2, detail); var cells = Mathf.Pow(4, detail); var a = Prepare(vertexSet[face.A].Position, vertexSet); var b = Prepare(vertexSet[face.B].Position, vertexSet); var c = Prepare(vertexSet[face.C].Position, vertexSet); var v = new List<List<VertexInfo>>(); // Construct all of the vertices for this subdivision. for (var i = 0; i <= cols; i++) { v.Add(new List<VertexInfo>()); var offset = i / (float)cols; var aV = a.Position; aV.Lerp(c.Position, offset); var aj = Prepare(aV, vertexSet); var bV = b.Position; bV.Lerp(c.Position, offset); var bj = Prepare(bV, vertexSet); var rows = cols - i; for (var j = 0; j <= rows; j++) { if (j == 0 && i == cols) { v[i].Add(aj); } else { var ajV = aj.Position; ajV.Lerp(bj.Position, j / (float)rows); v[i].Add(Prepare(ajV, vertexSet)); } } } // Construct all of the faces. for (var i = 0; i < cols; i++) { for (var j = 0; j < 2 * (cols - i) - 1; j++) { var k = Mathf.Floor(j / 2); if (j % 2 == 0) { Make( v[i][k + 1], v[i + 1][k], v[i][k] ); } else { Make( v[i][k + 1], v[i + 1][k + 1], v[i + 1][k] ); } } } }
// Approximate a curved face with recursively sub-divided triangles. private void Make(VertexInfo v1, VertexInfo v2, VertexInfo v3) { var face = new Face3(v1.Index, v2.Index, v3.Index, v1.Position, v2.Position, v3.Position); faces.Add(face); var centroid = v1.Position; centroid.Add(v2.Position); centroid.Add(v3.Position); centroid.Divide(3); var azi = Azimuth(centroid); var uvA = CorrectUV(v1.UV, v1.Position, azi); var uvB = CorrectUV(v2.UV, v2.Position, azi); var uvC = CorrectUV(v3.UV, v3.Position, azi); var faceSet = new UVFaceSet(uvA,uvB,uvC); var uvs = faceVertexUvs[0]; uvs.Add(faceSet); }
private void ParseModel(JObject json, Geometry geometry, float scale) { var verticesData = json["vertices"].Values<float>().ToArray(); var facesData = json["faces"].Values<int>().ToArray(); var normalsData = json["normals"].Values<float>().ToArray(); var colorsData = json["colors"].Values<uint>().ToArray(); var uvsData = new List<List<float>>(); foreach (var array in json["uvs"]) { var uvData = array.Values<float>().ToArray(); uvsData.Add(new List<float>(uvData)); } var nUvLayers = 0; if(uvsData.Count > 0) { geometry.faceVertexUvs.Clear(); // disregard empty arrays foreach (var row in uvsData) { nUvLayers++; geometry.faceVertexUvs.Add(new List<UVFaceSet>()); } } var offset = 0; while (offset < verticesData.Length) { var x = verticesData[offset++] * scale; var y = verticesData[offset++] * scale; var z = verticesData[offset++] * scale; var v = new Vector3(x, y, z); geometry.vertices.Add(v); } offset = 0; while (offset < facesData.Length) { var type = facesData[offset++]; var isQuad = IsBitSet(type, 0); var hasMaterial = IsBitSet(type, 1); var hasFaceVertexUv = IsBitSet(type, 3); var hasFaceNormal = IsBitSet(type, 4); var hasFaceVertexNormal = IsBitSet(type, 5); var hasFaceColor = IsBitSet(type, 6); var hasFaceVertexColor = IsBitSet(type, 7); //Debug.WriteLine("type:{0} bits( IsQuad:{1} Material:{2} FaceVertexUv:{3} FaceNormal:{4} FaceVertexNormal:{5} FaceColor:{6} FaceVertexColor:{7}", type, isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor); if (isQuad != 0) { var a = facesData[offset++]; var b = facesData[offset++]; var c = facesData[offset++]; var d = facesData[offset++]; var faceA = new Face3(a, b, d); var faceB = new Face3(b, c, d); if (hasMaterial != 0) { var materialIndex = facesData[offset++]; } if (hasFaceVertexUv != 0) { for (var i = 0; i < nUvLayers; i++) { var uvLayer = uvsData[ i ]; var uvIndexA = facesData[offset++]; var uvIndexB = facesData[offset++]; var uvIndexC = facesData[offset++]; var uvIndexD = facesData[offset++]; var uA = uvLayer[uvIndexA * 2]; var vA = uvLayer[uvIndexA * 2 + 1]; var uvA = new Vector2(uA, vA); var uB = uvLayer[uvIndexB * 2]; var vB = uvLayer[uvIndexB * 2 + 1]; var uvB = new Vector2(uB, vB); var uC = uvLayer[uvIndexC * 2]; var vC = uvLayer[uvIndexC * 2 + 1]; var uvC = new Vector2(uC, vC); var uD = uvLayer[uvIndexD * 2]; var vD = uvLayer[uvIndexD * 2 + 1]; var uvD = new Vector2(uD, vD); geometry.faceVertexUvs[i].Add(new UVFaceSet(uvA,uvB,uvD)); geometry.faceVertexUvs[i].Add(new UVFaceSet(uvB,uvC,uvD)); } } if (hasFaceNormal != 0) { var normalIndex = facesData[offset++] * 3; var x = normalsData[normalIndex++]; var y = normalsData[normalIndex++]; var z = normalsData[normalIndex]; var n = new Vector3(x, y, z); ; faceA.NormalA = n; faceA.NormalB = n; faceA.NormalC = n; faceB.NormalA = n; faceB.NormalB = n; faceB.NormalC = n; } if (hasFaceVertexNormal != 0) { for (var i = 0; i < 4; i++) { var normalIndex = facesData[offset++] * 3; var x = normalsData[normalIndex++]; var y = normalsData[normalIndex++]; var z = normalsData[normalIndex]; var n = new Vector3(x, y, z); switch(i) { case 0: faceA.NormalA = n; break; case 1: faceA.NormalB = n; faceB.NormalA = n; break; case 2: faceB.NormalB = n; break; case 3: faceA.NormalC = n; faceB.NormalC = n; break; } } } if (hasFaceColor != 0) { var colorIndex = facesData[offset++]; var hex = colorsData[colorIndex]; var color = new Color(hex); faceA.ColorA = color; faceA.ColorB = color; faceA.ColorC = color; faceB.ColorA = color; faceB.ColorB = color; faceB.ColorC = color; } if (hasFaceVertexColor != 0) { for (var i = 0; i < 4; i++) { var colorIndex = facesData[offset++]; var hex = colorsData[colorIndex]; var color = new Color(hex); switch (i) { case 0: faceA.ColorA = color; break; case 1: faceA.ColorB = color; faceB.ColorA = color; break; case 2: faceB.ColorB = color; break; case 3: faceA.ColorC = color; faceB.ColorC = color; break; } } } geometry.faces.Add(faceA); geometry.faces.Add(faceB); } else { var a = facesData[offset++]; var b = facesData[offset++]; var c = facesData[offset++]; var face = new Face3(a, b, c); if (hasFaceVertexUv != 0) { for (var i = 0; i < nUvLayers; i++) { var uvLayer = uvsData[i]; var uvIndexA = facesData[offset++]; var uvIndexB = facesData[offset++]; var uvIndexC = facesData[offset++]; var uA = uvLayer[uvIndexA * 2]; var vA = uvLayer[uvIndexA * 2 + 1]; var uvA = new Vector2(uA, vA); var uB = uvLayer[uvIndexB * 2]; var vB = uvLayer[uvIndexB * 2 + 1]; var uvB = new Vector2(uB, vB); var uC = uvLayer[uvIndexC * 2]; var vC = uvLayer[uvIndexC * 2 + 1]; var uvC = new Vector2(uC, vC); geometry.faceVertexUvs[i].Add(new UVFaceSet(uvA, uvB, uvC)); } } if (hasFaceNormal != 0) { var normalIndex = facesData[offset++] * 3; var x = normalsData[normalIndex++]; var y = normalsData[normalIndex++]; var z = normalsData[normalIndex]; var n = new Vector3(x, y, z); face.NormalA = n; face.NormalB = n; face.NormalC = n; } if (hasFaceVertexNormal != 0) { for (var i = 0; i < 3; i++) { var normalIndex = facesData[offset++] * 3; var x = normalsData[normalIndex++]; var y = normalsData[normalIndex++]; var z = normalsData[normalIndex]; var n = new Vector3(x, y, z); switch (i) { case 0: face.NormalA = n; break; case 1: face.NormalB = n; break; case 2: face.NormalC = n; break; } } } if (hasFaceColor != 0) { var colorIndex = facesData[offset++]; var hex = colorsData[colorIndex]; var color = new Color(hex); face.ColorA = color; face.ColorB = color; face.ColorC = color; } if (hasFaceVertexColor != 0) { for (var i = 0; i < 3; i++) { var colorIndex = facesData[offset++]; var hex = colorsData[colorIndex]; var color = new Color(hex); switch (i) { case 0: face.ColorA = color; break; case 1: face.ColorB = color; break; case 2: face.ColorC = color; break; } } } geometry.faces.Add(face); } } }