public TriangleMesh(GeometryInfo geoInfo) { MeshProfile = new SurfaceProfile(); MaterialName = geoInfo.MaterialName; MeshName = geoInfo.Name; Vertices = geoInfo.VertexData.ToPointList().ToArray(); Normals = geoInfo.NormalData.ToNormalList().ToArray(); TexCoords = geoInfo.TextureData.TodVectorList().ToArray(); var triangles = new List<TriangleDataInfo>(); int index = 0; if (geoInfo.IndexData.Any()) { int[] ni = null; int[] ti = null; var hasNormals = geoInfo.NormalIndexData != null && geoInfo.NormalIndexData.Any(); var hasTexCoords = geoInfo.TextureIndexData != null && geoInfo.TextureIndexData.Any(); if (hasTexCoords) { ti = geoInfo.TextureIndexData.ToArray(); } if (hasNormals) { ni = geoInfo.NormalIndexData.ToArray(); } HasNormals = hasNormals; HasTexCoords = hasTexCoords; for (int i = 0; i < geoInfo.IndexData.Count; i += 3) { index++; var newTriangle = new TriangleDataInfo() { v0 = new MeshVertexInfo() { NormalIndex = hasNormals ? ni[i] - 1 : -1, VertexIndex = geoInfo.IndexData[i] - delta, TexCoordIndex = hasTexCoords ? ti[i] - 1 : -1 }, v1 = new MeshVertexInfo() { NormalIndex = hasNormals ? ni[i + 1] - 1 : -1, VertexIndex = geoInfo.IndexData[i + 1] - delta, TexCoordIndex = hasTexCoords ? ti[i + 1] - 1 : -1 }, v2 = new MeshVertexInfo() { NormalIndex = hasNormals ? ni[i + 2] - 1 : -1, VertexIndex = geoInfo.IndexData[i + 2] - delta, TexCoordIndex = hasTexCoords ? ti[i + 2] - 1 : -1 }, }; triangles.Add(newTriangle); } WorldBound = new AABB(this.Vertices); this.Triangles = triangles.ToArray(); this.BottomLevelBVH = new AccellerationData() {data = BvhDataAdapter.CreateBVH(Triangles, Vertices)}; } }
public void Init(GeometryInfo model, SceneGeometryInfo scene) { this.scene = scene; triangles = new List<Triangle>(); normals = new Dictionary<int, Normal[]>(300); texCoords = new Dictionary<int, UV[]>(); this.MaterialName = model.MaterialName; this.MeshName = model.Name; var delta = -1; var index = 0; bool hasNormals = false; Normal[] norms = null; int[] ni = null; bool hasTexCoords = false; UV[] texs = null; int[] ti = null; if (model.IndexData.Any()) { hasNormals = model.NormalIndexData.Any(); hasTexCoords = model.TextureIndexData != null && model.TextureIndexData.Any(); if (hasTexCoords) { texs = scene.TexCoords.ToUVArray(); if (!texs.Any()) hasTexCoords = false; ti = model.TextureIndexData.ToArray(); } if (hasNormals) { norms = scene.Normals.Select(item => new Normal(item)).ToArray(); ni = model.NormalIndexData.ToArray(); } for (int i = 0; i < model.IndexData.Count; i += 3) { index++; var newTriangle = new Triangle(model.IndexData[i] - delta, model.IndexData[i + 1] - delta, model.IndexData[i + 2] - delta); newTriangle.Index = triangles.Count; newTriangle.Owner = this; triangles.Add(newTriangle); //meshIndexes.Add(extMesh); if (hasTexCoords) { var triIndex = index; var t1 = texs[(ti[i] - 1)]; var t2 = texs[(ti[i + 1] - 1)]; var t3 = texs[(ti[i + 2] - 1)]; texCoords.Add(triIndex, new[] { t1, t2, t3 }); } if (hasNormals) { //Add vertice normal var triIndex = index; var norm1 = a*norms[(ni[i] - 1)]; var norm2 = a*norms[(ni[i + 1] - 1)]; var norm3 = a*norms[(ni[i + 2] - 1)]; normals.Add(triIndex, new[] { norm1, norm2, norm3 }); } else { var triIndex = index; var norm1 = newTriangle.ComputeVerticeNormal(0, ref scene.Vertices); var norm2 = newTriangle.ComputeVerticeNormal(1, ref scene.Vertices); var norm3 = newTriangle.ComputeVerticeNormal(2, ref scene.Vertices); normals.Add(triIndex, new[] { norm1, norm2, norm3 }); } } //extMesh.Indexes = model.IndexBuffer.Select(item => item - (extMesh.StartVertice - 1)).ToArray(); } else { for (int i = 0; i < scene.Vertices.Length; i += 3) { var tri = new Triangle(Array.IndexOf(scene.Vertices, scene.Vertices[i]), Array.IndexOf(scene.Vertices, scene.Vertices[i + 1]), Array.IndexOf(scene.Vertices, scene.Vertices[i + 2])); triangles.Add(tri); //meshIndexes.Add(extMesh); index++; } } }
public SceneGeometryInfo Load(string fileName, bool invertNormals = false, params string[] additionalFiles) { var result = new SceneGeometryInfo(); var objs = new List<GeometryInfo>(); var curves = new List<CurveInfo>(); string lastCommand = "f"; FloatStore vb = null; FloatStore vt = null; FloatStore vn = null; IntStore ib = null; int giOffset = 0; IntStore tib = null; IntStore nib = null; int oCount = 0; var buffer = new Queue<string>(); bool isCurve = false; string currentMaterial = null; ObjHandler.md *= invertNormals ? -1f : 1f; Console.WriteLine("Normals inverted : {0}", invertNormals); using( var reader = new StreamReader(fileName) ) { while( !reader.EndOfStream ) { var s = reader.ReadLine(); if( String.IsNullOrEmpty(s) ) continue; buffer.Enqueue(s); } } while( buffer.Count > 0 ) { string line = buffer.Dequeue(); if( string.IsNullOrEmpty(line) ) continue; if (line.StartsWith("#")) { isCurve = line.Contains("shape "); continue; } //try //{ var tag = line.Contains(" ") ? line.Substring(0, line.IndexOf(" ")).Trim() : line.Trim(); switch( tag ) { case "vt": if( vt == null ) { vt = objs[oCount - 1].TextureData; } objs[oCount - 1].UseTextures = true; vt.AddRange(ObjHandler.Process_VT(line)); break; case "vn": if( vn == null ) { vn = objs[oCount - 1].NormalData; } objs[oCount - 1].UseNormals = true; vn.AddRange(ObjHandler.Process_VN(line)); break; case "v": if( lastCommand.Equals("f") ) { if (isCurve) { if (curves.Count > 0) { } } if (objs.Count > 0) { giOffset += objs[oCount - 1].IndexData.Count; } var newObj = new GeometryInfo() { GlobalIndexOffset = giOffset, MaterialName = currentMaterial}; objs.Add(newObj); //vb = newObj.VertexData; vn = null; ib = null; tib = null; nib = null; oCount++; } if( vb == null ) { vb = objs[oCount - 1].VertexData; } vb.AddRange(ObjHandler.Process_V(line)); break; case "f": if( ib == null ) { ib = objs[oCount - 1].IndexData; } int[] tibs, nibs; var ibValues = ObjHandler.Process_F(line, out nibs, out tibs); bool TexInd = false; bool NormInd = false; ib.AddRange(ibValues); if( objs[oCount - 1].UseTextures && objs[oCount - 1].UseNormals ) { NormInd = true; TexInd = true; } else if( objs[oCount - 1].UseTextures && !objs[oCount - 1].UseNormals ) { TexInd = true; tibs = nibs; } else if( !objs[oCount - 1].UseTextures && objs[oCount - 1].UseNormals ) { NormInd = true; } if( TexInd ) { if( tib == null ) { objs[oCount - 1].TextureIndexData = new IntStore(); tib = objs[oCount - 1].TextureIndexData; } if( tibs != null ) { tib.AddRange(tibs); } else if( nibs != null) { tib.AddRange(nibs); } } if( NormInd ) { if( nib == null ) { objs[oCount - 1].NormalIndexData = new IntStore(); nib = objs[oCount - 1].NormalIndexData; } if (nibs != null) nib.AddRange(nibs); } break; case "g": if( lastCommand.Equals("f") ) { var newObj = new GeometryInfo() {GlobalIndexOffset = giOffset, MaterialName = currentMaterial }; objs.Add(newObj); //vb = null; vn = null; ib = null; tib = null; nib = null; oCount++; } string name = string.Empty; ObjHandler.Process_G(line, out name); objs[oCount - 1].Name = name; break; case "usemtl": string mtl = string.Empty; ObjHandler.Process_Mtl(line, out mtl); objs[oCount - 1].MaterialName = mtl.ToLowerInvariant(); currentMaterial = mtl.ToLowerInvariant(); break; default: continue; } lastCommand = tag; //} //catch (Exception ex) //{ // throw ex; // //continue; //} } result.Vertices = vb.ToPointList().ToArray(); AABB bounds = new AABB(); AABB bounds1 = bounds; bounds = result.Vertices.Select(bounds1.Union).Aggregate<AABB>((c, i) => i.Union(c)); result.BoundingSphereCenter = bounds.Center; result.BoundingSphereRadius = bounds1.Size.Length; if (vt != null && vt.Any()) result.TexCoords = vt.TodVectorList().ToArray(); result.Normals = new FloatStore( objs.SelectMany(item => item.NormalData) ).TodVectorList().ToArray(); objs.ForEach(ob => { ob.IndexData.Iterator(Math.Abs); if( ob.TextureIndexData != null ) ob.TextureIndexData.Iterator(Math.Abs); if( ob.NormalIndexData != null ) ob.NormalIndexData.Iterator(Math.Abs); ob.Name = String.IsNullOrEmpty(ob.Name) ? Guid.NewGuid().ToString() : ob.Name; }); result.Geometry = objs.ToArray(); return result; }
public SceneGeometryInfo LoadData(string fileName) { sceneMats = new Dictionary<string, MaterialInfo>(); textures = new Dictionary<string, ImageTextureInfo>(); COLLADA model = COLLADA.Load(fileName); var result = new SceneGeometryInfo(); var sceneVerts = new List<Point>(); var meshes = new Dictionary<string, GeometryInfo>(); var sceneNormals = new List<Vector>(); var sceneTexData = new List<Vector>(); var cams = new List<CameraInfo>(); foreach (var item in model.Items) { if (item is library_materials) { var materials = item as library_materials; foreach (var material in materials.material) { } } if (item is library_cameras) { var cameras = item as library_cameras; foreach (var camera in cameras.camera) { if (camera.optics.technique.Length > 0) { var t = camera.optics.technique[0]; } var camItem = new CameraInfo() { CameraName = camera.id.Replace("-lib", string.Empty) }; cams.Add(camItem); } } var geometries = item as library_geometries; if (geometries == null) continue; // Iterate on geomerty in library_geometries foreach (var geom in geometries.geometry) { var meshInfo = geom.Item as mesh; if (meshInfo == null) continue; var mesh = new GeometryInfo() { Name = geom.name.Replace("Mesh", string.Empty) }; meshes.Add(mesh.Name, mesh); // Dump source[] for geom foreach (var source in meshInfo.source) { var float_array = source.Item as float_array; if (float_array == null) continue; if (source.id.Contains("Position")) { sceneVerts.AddRange(float_array.Values.ToPointList()); mesh.VertexData = new FloatStore(float_array.Values.ToFloatArray()); } else if (source.id.Contains("Normal")) { sceneNormals.AddRange(float_array.Values.ToVectorList()); mesh.NormalData = new FloatStore(float_array.Values.ToFloatArray()); } else if (source.id.Contains("UV")) { sceneTexData.AddRange(float_array.Values.ToVectorList()); mesh.TextureData = new FloatStore(float_array.Values.ToFloatArray()); } else { Console.WriteLine("Geometry {0} Unknown source {1} : ", geom.id, source.id); } Console.Write("Geometry {0} source {1} : ", geom.id, source.id); /* foreach (var mesh_source_value in float_array.Values) Console.Write("{0} ", mesh_source_value); */ Console.WriteLine(); } // Dump Items[] for geom foreach (var meshItem in meshInfo.Items) { if (meshItem is vertices) { var vertices = meshItem as vertices; var inputs = vertices.input; foreach (var input in inputs) Console.WriteLine("\t Semantic {0} Source {1}", input.semantic, input.source); } else if (meshItem is triangles) { var triangles = meshItem as triangles; var inputs = triangles.input; foreach (var input in inputs) Console.WriteLine("\t Semantic {0} Source {1} Offset {2}", input.semantic, input.source, input.offset); Console.WriteLine("\t Indices {0}", triangles.p); } else if (meshItem is polygons) { var polygons = meshItem as polygons; var inputs = polygons.input; foreach (var input in inputs) Console.WriteLine("\t Semantic {0} Source {1} Offset {2}", input.semantic, input.source, input.offset); var indexes = polygons.Items.SelectMany(u => u.ToString().Split(' ')).Select(ix => int.Parse(ix, CultureInfo.InvariantCulture)).ToArray(); mesh.IndexData = new IntStore(indexes.Where((x, i) => i % 3 == 0)); mesh.NormalIndexData = new IntStore(indexes.Where((x, i) => (i + 1) % 3 == 0)); mesh.TextureIndexData = new IntStore(indexes.Where((x, i) => (i + 2) % 3 == 0)); Console.WriteLine("\t Indices {0}", indexes.ToArray()); } } } } foreach (var node in model.Items.OfType<library_visual_scenes>().SelectMany(sceneNode => sceneNode.visual_scene.SelectMany(it => it.node))) { if (node.instance_camera != null && node.instance_camera.Length > 0) { var cam = cams.FirstOrDefault(m => m.CameraName.Equals(node.id)); if (cam != null) { cam.PosTransform = new Matrix4x4(((matrix)node.Items[0]).Values); cam.Position = new Point(cam.PosTransform[3], cam.PosTransform[7], cam.PosTransform[11]); cam.Up = new Vector(0, 0, -1f); Console.WriteLine("Camera {0} initialized", cam.CameraName); } continue; } if (cams.Any(cam => node.id.Contains(cam.CameraName))) { var cam = cams.FirstOrDefault(cm => node.id.Contains(cm.CameraName)); if (cam != null) { cam.DirTransform = new Matrix4x4(((matrix)node.Items[0]).Values); cam.Direction = new Vector(cam.DirTransform[3], cam.DirTransform[7], cam.DirTransform[11]); Console.WriteLine("Camera {0} initialized", cam.CameraName); } continue; } if (node.instance_geometry != null && node.instance_geometry.Length > 0) { var mesh = meshes[node.id]; if (mesh != null) { var instanceMaterials = node.instance_geometry[0].bind_material; if (instanceMaterials != null) mesh.MaterialName = instanceMaterials.technique_common[0].symbol; mesh.Transform = new Matrix4x4(((matrix)node.Items[0]).Values); Console.WriteLine(mesh); } } } result.Geometry = meshes.Values.ToArray(); result.Vertices = sceneVerts.ToArray(); result.Normals = sceneNormals.ToArray(); result.TexCoords = sceneTexData.ToArray(); result.Cameras = cams.ToArray(); return result; }