void GetFaceIndices(IList <FaceIndices> targetFacesList, string[] linePart) { string[] indices; for (int i = 1; i < linePart.Length; i++) { indices = linePart[i].Trim().Split(faceSplitChar); var faceIndices = new FaceIndices(); // vertex int vertexIndex = ci(indices[0]); faceIndices.vertexIndex = vertexIndex - 1; // uv if (indices.Length > 1 && indices[1] != "") { int uvIndex = ci(indices[1]); faceIndices.vertexUV = uvIndex - 1; } // normal if (indices.Length > 2 && indices[2] != "") { int normalIndex = ci(indices[2]); faceIndices.vertexNormal = normalIndex - 1; } else { faceIndices.vertexNormal = -1; } targetFacesList[i - 1] = faceIndices; } }
private bool ParseObjLine(ref string objline) { linePart = objline.Trim().Split(linePartSplitChar); switch (linePart[0]) { case O: //buffer.AddObject(linePart[1].Trim()); We skip object seperation, to reduce object count. //Importing large SketchupUp generated OBJ files results in an enormous amount of objects, making WebGL builds explode. break; case MTLLIB: mtllib = line.Substring(linePart[0].Length + 1).Trim(); break; case USEMTL: buffer.AddSubMeshGroup(linePart[1].Trim()); break; case V: buffer.PushVertex(new Vector3(cf(linePart[1]), cf(linePart[2]), cf(linePart[3]))); break; case VT: buffer.PushUV(new Vector2(cf(linePart[1]), cf(linePart[2]))); break; case VN: buffer.PushNormal(new Vector3(cf(linePart[1]), cf(linePart[2]), cf(linePart[3]))); break; case F: var faces = new FaceIndices[linePart.Length - 1]; GetFaceIndices(faces, linePart); if (linePart.Length == 4) { //tris buffer.PushFace(faces[0]); buffer.PushFace(faces[1]); buffer.PushFace(faces[2]); } else if (linePart.Length == 5) { //quad buffer.PushFace(faces[0]); buffer.PushFace(faces[1]); buffer.PushFace(faces[3]); buffer.PushFace(faces[3]); buffer.PushFace(faces[1]); buffer.PushFace(faces[2]); } else { Debug.LogWarning("face vertex count :" + (linePart.Length - 1) + " larger than 4. Ngons not supported."); return(false); //Return failure. Not triangulated. } break; } return(true); }
public void PushFace(FaceIndices f) { curgr.faces.Add(f); current.allFaces.Add(f); if (f.vn >= 0) { current.normalCount++; } }
public void PushFace(FaceIndices f) { currentSubMeshGroup.FaceIndices.Add(f); currentObjectData.AllFacesIndices.Add(f); if (f.vertexNormal >= 0) { currentObjectData.NormalCount++; } }
public void PushFace(FaceIndices f) { curgr.Faces.Add(f); current.AllFaces.Add(f); if (f.Vn >= 0) { current.NormalCount++; } }
/// <summary> /// Add a new face indices entry to the current faces group /// </summary> /// <param name="faceIdx">new vertex indices</param> public void AddFaceIndices(FaceIndices faceIdx) { currGroup.faces.Add(faceIdx); currObjData.allFaces.Add(faceIdx); if (faceIdx.normIdx >= 0) { currObjData.hasNormals = true; } }
private void SetGeometryData(string data) { string[] lines = data.Split("\n".ToCharArray()); for(int i = 0; i < lines.Length; i++) { string l = lines[i]; if(l.IndexOf("#") != -1) l = l.Substring(0, l.IndexOf("#")); string[] p = l.Split(" ".ToCharArray()); switch(p[0]) { case O: buffer.PushObject(p[1].Trim()); break; case G: buffer.PushGroup(p[1].Trim()); break; case V: buffer.PushVertex( new Vector3( cf(p[1]), cf(p[2]), cf(p[3]) ) ); break; case VT: buffer.PushUV(new Vector2( cf(p[1]), cf(p[2]) )); break; case VN: buffer.PushNormal(new Vector3( cf(p[1]), cf(p[2]), cf(p[3]) )); break; case F: for(int j = 1; j < p.Length; j++) { string[] c = p[j].Trim().Split("/".ToCharArray()); FaceIndices fi = new FaceIndices(); fi.vi = ci(c[0])-1; if(c.Length > 1 && c[1] != "") fi.vu = ci(c[1])-1; if(c.Length > 2 && c[2] != "") fi.vn = ci(c[2])-1; buffer.PushFace(fi); } break; case MTL: mtllib = p[1].Trim(); break; case UML: buffer.PushMaterialName(p[1].Trim()); break; } } // buffer.Trace(); }
protected override DxfObject PostParse() { // geo mesh points Debug.Assert(_geoMeshPointCount == _sourceMeshXPoints.Count); Debug.Assert(_geoMeshPointCount == _sourceMeshYPoints.Count); Debug.Assert(_geoMeshPointCount == _destinationMeshXPoints.Count); Debug.Assert(_geoMeshPointCount == _destinationMeshYPoints.Count); var limit = new[] { _geoMeshPointCount, _sourceMeshXPoints.Count, _sourceMeshYPoints.Count, _destinationMeshXPoints.Count, _destinationMeshYPoints.Count }.Min(); GeoMeshPoints.Clear(); for (int i = 0; i < limit; i++) { GeoMeshPoints.Add(new DxfGeoMeshPoint() { SourcePoint = new DxfPoint(_sourceMeshXPoints[i], _sourceMeshYPoints[i], 0.0), DestinationPoint = new DxfPoint(_destinationMeshXPoints[i], _destinationMeshYPoints[i], 0.0) }); } _sourceMeshXPoints.Clear(); _sourceMeshYPoints.Clear(); _destinationMeshXPoints.Clear(); _destinationMeshYPoints.Clear(); // face index points Debug.Assert(_facesCount == _facePointIndexX.Count); Debug.Assert(_facesCount == _facePointIndexY.Count); Debug.Assert(_facesCount == _facePointIndexZ.Count); limit = new[] { _facesCount, _facePointIndexX.Count, _facePointIndexY.Count, _facePointIndexZ.Count }.Min(); FaceIndices.Clear(); for (int i = 0; i < limit; i++) { FaceIndices.Add(new DxfPoint(_facePointIndexX[i], _facePointIndexY[i], _facePointIndexZ[i])); } _facePointIndexX.Clear(); _facePointIndexY.Clear(); _facePointIndexZ.Clear(); return(this); }
/// <summary> /// Generates all vertices for given FaceIndices. /// </summary> private IEnumerable <int> GenerateFaceVertices(FaceIndices[] faceIndices) { // Generate vertex for (int loop = 0; loop < faceIndices.Length; loop++) { FaceIndices actFaceIndices = faceIndices[loop]; Vertex actVertex = new Vertex(); actVertex.Position = m_rawVertices[actFaceIndices.VertexIndex]; if (actFaceIndices.TextureCoordinateIndex > Int32.MinValue) { actVertex.TexCoord = m_rawTextureCoordinates[actFaceIndices.TextureCoordinateIndex]; } if (actFaceIndices.NormalIndex > Int32.MinValue) { actVertex.Normal = m_rawNormals[actFaceIndices.NormalIndex]; } yield return(m_targetVertexStructure.AddVertex(actVertex)); } }
private void SetGeometryData(string data) { string[] lines = data.Split("\n".ToCharArray()); Regex regexWhitespaces = new Regex(@"\s+"); bool isFirstInGroup = true; bool isFaceIndexPlus = true; for (int i = 0; i < lines.Length; i++) { string l = lines[i].Trim(); if (l.IndexOf("#") != -1) // comment line { continue; } string[] p = regexWhitespaces.Split(l); switch (p[0]) { case O: buffer.PushObject(p[1].Trim()); isFirstInGroup = true; break; case G: string groupName = null; if (p.Length >= 2) { groupName = p[1].Trim(); } isFirstInGroup = true; buffer.PushGroup(groupName); break; case V: buffer.PushVertex(new Vector3(cf(p[1]), cf(p[2]), cf(p[3]))); break; case VT: buffer.PushUV(new Vector2(cf(p[1]), cf(p[2]))); break; case VN: buffer.PushNormal(new Vector3(cf(p[1]), cf(p[2]), cf(p[3]))); break; case F: FaceIndices[] faces = new FaceIndices[p.Length - 1]; if (isFirstInGroup) { isFirstInGroup = false; string[] c = p[1].Trim().Split("/".ToCharArray()); isFaceIndexPlus = (ci(c[0]) >= 0); } GetFaceIndicesByOneFaceLine(faces, p, isFaceIndexPlus); if (p.Length == 4) { buffer.PushFace(faces[0]); buffer.PushFace(faces[1]); buffer.PushFace(faces[2]); } else if (p.Length == 5) { buffer.PushFace(faces[0]); buffer.PushFace(faces[1]); buffer.PushFace(faces[3]); buffer.PushFace(faces[3]); buffer.PushFace(faces[1]); buffer.PushFace(faces[2]); } else { //Debug.LogWarning("face vertex count :"+(p.Length-1)+" larger than 4:"); } break; case MTL: mtllib = l.Substring(p[0].Length + 1).Trim(); break; case UML: buffer.PushMaterialName(p[1].Trim()); break; } } // buffer.Trace(); }
private void GetFaceIndicesByOneFaceLine(FaceIndices[] faces, string[] p, bool isFaceIndexPlus) { if (isFaceIndexPlus) { for (int j = 1; j < p.Length; j++) { string[] c = p[j].Trim().Split("/".ToCharArray()); FaceIndices fi = new FaceIndices(); // vertex int vi = ci(c[0]); fi.vi = vi - 1; // uv if (c.Length > 1 && c[1] != "") { int vu = ci(c[1]); fi.vu = vu - 1; } // normal if (c.Length > 2 && c[2] != "") { int vn = ci(c[2]); fi.vn = vn - 1; } else { fi.vn = -1; } faces[j - 1] = fi; } } else // for minus index { int vertexCount = buffer.vertices.Count; int uvCount = buffer.uvs.Count; for (int j = 1; j < p.Length; j++) { string[] c = p[j].Trim().Split("/".ToCharArray()); FaceIndices fi = new FaceIndices(); // vertex int vi = ci(c[0]); fi.vi = vertexCount + vi; // uv if (c.Length > 1 && c[1] != "") { int vu = ci(c[1]); fi.vu = uvCount + vu; } // normal if (c.Length > 2 && c[2] != "") { int vn = ci(c[2]); fi.vn = vertexCount + vn; } else { fi.vn = -1; } faces[j - 1] = fi; } } }
private IEnumerator SetGeometryData(string data) { yield return(0); // play nice by not hogging the main thread string[] lines = data.Split("\n".ToCharArray()); bool isFirstInGroup = true; bool isFaceIndexPlus = true; for (int i = 0; i < lines.Length; i++) { string l = lines[i].Trim(); if (l.Length > 0 && l[0] == '#') // comment line { continue; } string[] p = l.Replace(" ", " ").Split(' '); switch (p[0]) { case O: buffer.PushObject(p[1].Trim()); isFirstInGroup = true; break; case G: string groupName = null; if (p.Length >= 2) { groupName = p[1].Trim(); } isFirstInGroup = true; buffer.PushGroup(groupName); break; case V: buffer.PushVertex(new Vector3(cf(p[1]), cf(p[2]), cf(p[3]))); break; case VT: buffer.PushUV(new Vector2(cf(p[1]), cf(p[2]))); break; case VN: buffer.PushNormal(new Vector3(cf(p[1]), cf(p[2]), cf(p[3]))); break; case F: FaceIndices[] faces = new FaceIndices[p.Length - 1]; if (isFirstInGroup) { isFirstInGroup = false; string[] c = p[1].Trim().Split("/".ToCharArray()); isFaceIndexPlus = (ci(c[0]) >= 0); } GetFaceIndicesByOneFaceLine(faces, p, isFaceIndexPlus); if (p.Length == 4) { buffer.PushFace(faces[0]); buffer.PushFace(faces[1]); buffer.PushFace(faces[2]); } else if (p.Length == 5) { buffer.PushFace(faces[0]); buffer.PushFace(faces[1]); buffer.PushFace(faces[3]); buffer.PushFace(faces[3]); buffer.PushFace(faces[1]); buffer.PushFace(faces[2]); } else { //Debug.LogWarning("face vertex count :"+(p.Length-1)+" larger than 4:"); } break; case MTL: mtllib = l.Substring(p[0].Length + 1).Trim(); break; case UML: buffer.PushMaterialName(p[1].Trim()); break; } if (i % 7000 == 0) { yield return(0); // play nice with main thread while parsing large objs } } // buffer.Trace(); }
private void SetGeometryData(string data) { string[] lines = data.Split("\n".ToCharArray()); Debug.Log(DateTime.Now.Second + "." + DateTime.Now.Millisecond + " split complete"); for(int i = 0; i < lines.Length; i++) { string l = lines[i]; if(l.IndexOf("#") != -1) l = l.Substring(0, l.IndexOf("#")); string[] p = l.Split(" ".ToCharArray()); switch(p[0]) { case O: buffer.PushObject(p[1].Trim()); break; case G: buffer.PushGroup(p[1].Trim()); break; case V: //add 3d-space point buffer.PushVertex( new Vector3( cf(p[1]), cf(p[2]), cf(p[3]) ) ); break; case VT: //add 2d-uv point buffer.PushUV(new Vector2( cf(p[1]), cf(p[2]) )); break; case VN: //add 3d normal point buffer.PushNormal(new Vector3( cf(p[1]), cf(p[2]), cf(p[3]) )); break; case F: //add face, it will call add_hash_node for vtopo.vpair for(int j = 1; j < p.Length; j++) { string[] c = p[j].Trim().Split("/".ToCharArray()); FaceIndices fi = new FaceIndices(); fi.vi = (ushort) (ci(c[0])-1); if (c.Length > 1 && c[1] != "") fi.vu = (ushort) (ci(c[1]) - 1); if (c.Length > 2 && c[2] != "") fi.vn = (ushort) (ci(c[2]) - 1); buffer.PushFace(ref fi); } break; case MTL: mtllib = p[1].Trim(); break; case UML: buffer.PushMaterialName(p[1].Trim()); break; } } // buffer.Trace(); }
private void GetFaceIndicesByOneFaceLine(FaceIndices[] faces, string[] p, bool isFaceIndexPlus) { if (isFaceIndexPlus) { for(int j = 1; j < p.Length; j++) { string[] c = p[j].Trim().Split("/".ToCharArray()); FaceIndices fi = new FaceIndices(); // vertex int vi = ci(c[0]); fi.vi = vi-1; // uv if(c.Length > 1 && c[1] != "") { int vu = ci(c[1]); fi.vu = vu-1; } // normal if(c.Length > 2 && c[2] != "") { int vn = ci(c[2]); fi.vn = vn-1; } else { fi.vn = -1; } faces[j-1] = fi; } } else { // for minus index int vertexCount = buffer.vertices.Count; int uvCount = buffer.uvs.Count; for(int j = 1; j < p.Length; j++) { string[] c = p[j].Trim().Split("/".ToCharArray()); FaceIndices fi = new FaceIndices(); // vertex int vi = ci(c[0]); fi.vi = vertexCount + vi; // uv if(c.Length > 1 && c[1] != "") { int vu = ci(c[1]); fi.vu = uvCount + vu; } // normal if(c.Length > 2 && c[2] != "") { int vn = ci(c[2]); fi.vn = vertexCount + vn; } else { fi.vn = -1; } faces[j-1] = fi; } } }
/// <summary> /// Reads a line containing face information. /// </summary> private void HandleKeyword_Obj_F(string arguments) { // Split arguments string[] faceArguments = arguments.Split(ARGUMENT_SPLITTER, StringSplitOptions.RemoveEmptyEntries); if (faceArguments.Length < 3) { throw new SeeingSharpGraphicsException($"Invalid count of arguments for keyword 'f', (expected = >2, got={faceArguments.Length})!"); } // Prepare FaceIndices array FaceIndices[] faceIndices = null; if (faceArguments.Length == 3) { faceIndices = m_dummyFaceIndices_3; } else if (faceArguments.Length == 4) { faceIndices = m_dummyFaceIndices_4; } else { faceIndices = new FaceIndices[faceArguments.Length]; } // Parse and preprocess all arumgents for (int loop = 0; loop < faceArguments.Length; loop++) { ParseFaceData(faceArguments[loop], m_dummyIntArguments_3); // Preprocess vertex index int actIndex = m_dummyIntArguments_3[0]; if (actIndex < 0) { int newIndex = m_rawVertices.Count + actIndex; if (newIndex < 0) { throw new SeeingSharpGraphicsException($"Invalid vertex index: {actIndex} (we currently have {m_rawVertices.Count} vertices)!"); } faceIndices[loop].VertexIndex = newIndex; } else { faceIndices[loop].VertexIndex = m_dummyIntArguments_3[0] - 1; } // Preprocess texture coordinates actIndex = m_dummyIntArguments_3[1]; if ((actIndex < 0) && (actIndex != Int32.MinValue)) { int newIndex = m_rawTextureCoordinates.Count + actIndex; if (newIndex < 0) { throw new SeeingSharpGraphicsException($"Invalid vertex index: {actIndex} (we currently have {m_rawTextureCoordinates.Count} texture coordinates)!"); } faceIndices[loop].TextureCoordinateIndex = newIndex; } else if (actIndex != Int32.MinValue) { faceIndices[loop].TextureCoordinateIndex = m_dummyIntArguments_3[1] - 1; } else { faceIndices[loop].TextureCoordinateIndex = Int32.MinValue; } // Preprocess normal coordinates actIndex = m_dummyIntArguments_3[2]; if ((actIndex < 0) && (actIndex != Int32.MinValue)) { int newIndex = m_rawNormals.Count + actIndex; if (newIndex < 0) { throw new SeeingSharpGraphicsException($"Invalid vertex index: {actIndex} (we currently have {m_rawNormals.Count} normals)!"); } faceIndices[loop].NormalIndex = newIndex; } else if (actIndex != Int32.MinValue) { faceIndices[loop].NormalIndex = m_dummyIntArguments_3[2] - 1; } else { faceIndices[loop].NormalIndex = Int32.MinValue; } } // Generate vertices and triangles on current VertexStructure if (faceIndices.Length == 3) { GenerateFaceVertices(faceIndices).ForEachInEnumeration((actIndex) => { }); int highestVertexIndex = m_targetVertexStructure.CountVertices - 1; m_currentSurface.AddTriangle( highestVertexIndex - 2, highestVertexIndex - 1, highestVertexIndex); if (m_importOptions.TwoSidedSurfaces) { m_currentSurface.AddTriangle( highestVertexIndex, highestVertexIndex - 1, highestVertexIndex - 2); } } else { m_currentSurface.AddPolygonByCuttingEars( GenerateFaceVertices(faceIndices), twoSided: m_importOptions.TwoSidedSurfaces); } }
public void PushFace(ref FaceIndices f) { vtopo.add_hash_node(ref f); curgr.faces.Add(f); current.allFaces.Add(f); //TODO delete one Add }
public void PushFace(FaceIndices f) { curgr.faces.Add(f); current.allFaces.Add(f); }
private void SetGeometryData(string data) { string[] lines = data.Split("\n".ToCharArray()); for (int i = 0; i < lines.Length; i++) { string l = lines[i]; if (l.IndexOf("#") != -1) { l = l.Substring(0, l.IndexOf("#")); } string[] p = l.Split(" ".ToCharArray()); switch (p[0]) { case O: buffer.PushObject(p[1].Trim()); break; case G: buffer.PushGroup(p[1].Trim()); break; case V: //Unity has a left-handed coordinates system while Molecular OBJs are right-handed //So we have to negate the X coordinates buffer.PushVertex(new Vector3(-cf(p[1]), cf(p[2]), cf(p[3]))); compteurvertice++; break; case VT: buffer.PushUV(new Vector2(cf(p[1]), cf(p[2]))); break; case VN: //Unity has a left-handed coordinates system while Molecular OBJs are right-handed //So we have to negate the X coordinates //Here it affects only light ! The winding reverse is in GeometryBuffer::PopulateMeshes Vector3 norm = new Vector3(-cf(p[1]), cf(p[2]), cf(p[3])); norm.Normalize(); buffer.PushNormal(norm); break; case F: for (int j = 1; j < p.Length; j++) { string[] c = p[j].Trim().Split("/".ToCharArray()); // Debug.Log("" +p[j]); FaceIndices fi = new FaceIndices(); fi.vi = ci(c[0]) - 1; if (c.Length > 1 && c[1] != "") { fi.vu = ci(c[1]) - 1; } if (c.Length > 2 && c[2] != "") { fi.vn = ci(c[2]) - 1; } // Debug.Log("vi "+fi.vi+" vu "+fi.vu+ " vn "+fi.vn); buffer.PushFace(fi); } break; case MTL: if (mtl_reader != null) { mtllib = p[1].Trim(); } break; case UML: if (mtl_reader != null) { buffer.PushMaterialName(p[1].Trim()); } break; } } // buffer.Trace(); }
public void add_hash_node(ref FaceIndices f) { if (vpair[f.vi].vu == INVALID_V) //new vi { f.vp = vpair_count; vpair[f.vi].vi = f.vi; vpair[f.vi].vu = f.vu; vpair[f.vi].vp = vpair_count++; } else { int idx = f.vi; while (vpair[idx].vu != f.vu && vpair[idx].next_hash_idx != INVALID_V) idx = vpair[idx].next_hash_idx; if (vpair[idx].vu == f.vu) //find same (vi,vu) part, find existing pair f.vp = vpair[idx].vp; else { //same vi,different vu, new pair vpair_cap--; vpair[idx].next_hash_idx = vpair_cap; f.vp = vpair_count; vpair[vpair_cap].vi = f.vi; vpair[vpair_cap].vu = f.vu; vpair[vpair_cap].vp = vpair_count++; } } if (vpair_count >= VPAIR_SIZE) throw new Exception("Vertices can't exceed " + VPAIR_SIZE); }
private IEnumerator SetGeometryData(string data) { yield return 0; // play nice by not hogging the main thread string[] lines = data.Split("\n".ToCharArray()); bool isFirstInGroup = true; bool isFaceIndexPlus = true; for(int i = 0; i < lines.Length; i++) { string l = lines[i].Trim(); if(l.Length > 0 && l[0] == '#') { // comment line continue; } string[] p = l.Replace(" ", " ").Split(' '); switch(p[0]) { case O: buffer.PushObject(p[1].Trim()); isFirstInGroup = true; break; case G: string groupName = null; if (p.Length >= 2) { groupName = p[1].Trim(); } isFirstInGroup = true; buffer.PushGroup(groupName); break; case V: buffer.PushVertex( new Vector3( cf(p[1]), cf(p[2]), cf(p[3]) ) ); break; case VT: buffer.PushUV(new Vector2( cf(p[1]), cf(p[2]) )); break; case VN: buffer.PushNormal(new Vector3( cf(p[1]), cf(p[2]), cf(p[3]) )); break; case F: FaceIndices[] faces = new FaceIndices[p.Length-1]; if (isFirstInGroup) { isFirstInGroup = false; string[] c = p[1].Trim().Split("/".ToCharArray()); isFaceIndexPlus = (ci(c[0]) >= 0); } GetFaceIndicesByOneFaceLine(faces, p, isFaceIndexPlus); if (p.Length == 4) { buffer.PushFace(faces[0]); buffer.PushFace(faces[1]); buffer.PushFace(faces[2]); } else if (p.Length == 5) { buffer.PushFace(faces[0]); buffer.PushFace(faces[1]); buffer.PushFace(faces[3]); buffer.PushFace(faces[3]); buffer.PushFace(faces[1]); buffer.PushFace(faces[2]); } else { Debug.LogWarning("face vertex count :"+(p.Length-1)+" larger than 4:"); } break; case MTL: mtllib = l.Substring(p[0].Length+1).Trim(); break; case UML: buffer.PushMaterialName(p[1].Trim()); break; } if (i % 7000 == 0) yield return 0; // play nice with main thread while parsing large objs } // buffer.Trace(); }
public void add_hash_node(ref FaceIndices f) { if (vpair[f.vi].vu == INVALID_V) { f.vp = vpair_count; vpair[f.vi].vi = f.vi; vpair[f.vi].vu = f.vu; vpair[f.vi].vp = vpair_count++; } else { int idx = f.vi; while (vpair[idx].vu != f.vu && vpair[idx].next_hash_idx != INVALID_V) idx = vpair[idx].next_hash_idx; if (vpair[idx].vu == f.vu) f.vp = vpair[idx].vp; else { vpair_cap--; vpair[idx].next_hash_idx = vpair_cap; f.vp = vpair_count; vpair[vpair_cap].vi = f.vi; vpair[vpair_cap].vu = f.vu; vpair[vpair_cap].vp = vpair_count++; } } if (vpair_count >= VPAIR_SIZE) throw new Exception("Vertices can't exceed " + VPAIR_SIZE); }
private void SetGeometryData(string data) { //ALTERATION 1:- Major Problems with different OBJ file format whitespace, this helped:-. data = data.Replace("\r\n","\n"); string[] lines = data.Split("\n".ToCharArray()); // for(int i = 0; i < lines.Length; i++) { string l = lines[i]; if(l.IndexOf("#") != -1) l = l.Substring(0, l.IndexOf("#")); //ALTERATION 1:- whitespace leading to null values, this helped:- l=Regex.Replace(l,@"\s+"," "); l=l.Trim(); string[] p = l.Split(" ".ToCharArray()); switch(p[0]) { case O: buffer.PushObject(p[1].Trim()); break; case G: buffer.PushGroup(p[1].Trim()); break; case V: if (p.Length>=3) { buffer.PushVertex( new Vector3( cf(p[1]), cf(p[2]), cf(p[3]) ) ); } break; case VT: if (p.Length>=2) { buffer.PushUV(new Vector2( cf(p[1]), cf(p[2]) )); } break; case VN: if (p.Length>=3) { buffer.PushNormal(new Vector3( cf(p[1]), cf(p[2]), cf(p[3]) )); } break; case F: if (p.Length>=4) { string[] c; // ALTERATION 2:- Rough Fix to deal with quads and polys there may be better methods for (int j=0;j<p.Length-3;j++) { //Amount of Triangles To Make up Face FaceIndices fi = new FaceIndices(); //Get first point c=p[1].Trim().Split("/".ToCharArray()); if (c.Length > 0 && c[0] != string.Empty) {fi.vi = ci(c[0])-1;} if (c.Length > 1 && c[1] != string.Empty) {fi.vu = ci(c[1])-1;} if (c.Length > 2 && c[2] != string.Empty) {fi.vn = ci(c[2])-1;} buffer.PushFace(fi); for (int k=0;k<2;k++) { fi = new FaceIndices(); //Get second and third points (depending on p length) int no=2+k+j; c=p[no].Trim().Split("/".ToCharArray()); if (c.Length > 0 && c[0] != string.Empty) {fi.vi = ci(c[0])-1;} if (c.Length > 1 && c[1] != string.Empty) {fi.vu = ci(c[1])-1;} if (c.Length > 2 && c[2] != string.Empty) {fi.vn = ci(c[2])-1;} buffer.PushFace(fi); } } } break; case MTL: mtllib = p[1].Trim(); break; case UML: buffer.PushMaterialName(p[1].Trim()); break; } } buffer.Trace(); }
static private void ProcessOBJLine(GeometryBuffer gBuffer, string line) { string l = line; int iSchrp = l.IndexOf("#"); if (iSchrp != -1) { l = l.Substring(0, iSchrp); } l = l.Trim().Replace(" ", " "); string[] p = l.Split(" ".ToCharArray()); switch (p[0]) { case O: gBuffer.PushObject(p[1].Trim()); break; case G: gBuffer.PushGroup(p[1].Trim()); break; case V: gBuffer.PushVertex(new Vector3(Cf(p[1]), Cf(p[2]), Cf(p[3]))); break; case VT: gBuffer.PushUV(new Vector2(Cf(p[1]), Cf(p[2]))); break; case VN: gBuffer.PushNormal(new Vector3(Cf(p[1]), Cf(p[2]), Cf(p[3]))); break; case F: string[] c; FaceIndices fi; if (p.Length - 1 == 3) { //For Triangles for (int j = 0; j < 3; j++) { c = p[rightTrisWay[j]].Trim().Split("/".ToCharArray()); fi = new FaceIndices(); fi.vi = Ci(c[0]) - 1; if (c.Length > 1 && c[1] != string.Empty) { fi.vu = Ci(c[1]) - 1; } if (c.Length > 2 && c[2] != string.Empty) { fi.vn = Ci(c[2]) - 1; } gBuffer.PushFace(fi); } } else { //For Quads for (int j = 0; j < 6; j++) { c = p[rightQuadsWay[j]].Trim().Split("/".ToCharArray()); fi = new FaceIndices(); fi.vi = Ci(c[0]) - 1; if (c.Length > 1 && c[1] != string.Empty) { fi.vu = Ci(c[1]) - 1; } if (c.Length > 2 && c[2] != string.Empty) { fi.vn = Ci(c[2]) - 1; } gBuffer.PushFace(fi); } } break; default: break; } }
/// <summary> /// Get a string key based on the given face indices /// </summary> /// <param name="fi">face indices structure</param> /// <returns></returns> public static string GetFaceIndicesKey(FaceIndices fi) { return(fi.vertIdx.ToString() + "/" + fi.uvIdx.ToString() + "/" + fi.normIdx.ToString()); }
public static Mesh Load(string path) { if (!File.Exists(path)) { throw new FileNotFoundException("Unable to open \"" + path + "\", does not exist."); } List <Vector4> vertices = new List <Vector4>(); List <Vector3> textureVertices = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); //List<FaceIndices> indices = new List<FaceIndices>(); List <Face> faces = new List <Face>(); using (StreamReader streamReader = new StreamReader(path)) { while (!streamReader.EndOfStream) { List <string> words = new List <string>(streamReader.ReadLine().ToLower().Split(' ')); words.RemoveAll(s => s == string.Empty); if (words.Count == 0) { continue; } string type = words[0]; words.RemoveAt(0); switch (type) { // vertex case "v": vertices.Add(new Vector4(float.Parse(words[0]), float.Parse(words[1]), float.Parse(words[2]), words.Count < 4 ? 1 : float.Parse(words[3]))); break; case "vt": textureVertices.Add(new Vector3(float.Parse(words[0]), float.Parse(words[1]), words.Count < 3 ? 0 : float.Parse(words[2]))); break; case "vn": normals.Add(new Vector3(float.Parse(words[0]), float.Parse(words[1]), float.Parse(words[2]))); break; // face case "f": Face face = new Face(); int i = 0; foreach (string w in words) { if (w.Length == 0) { continue; } string[] comps = w.Split('/'); FaceIndices fi = new FaceIndices(); fi.VertexId = w; // subtract 1: indices start from 1, not 0 fi.VertexIndex = int.Parse(comps[0]) - 1; if (comps.Length > 1 && comps[1].Length != 0) { fi.TextureCoordIndex = int.Parse(comps[1]) - 1; } if (comps.Length > 2) { fi.NormalIndex = int.Parse(comps[2]) - 1; } face.Indices[i] = fi; i++; } // Calculate face Tangent/Bitangent Vector4 pos1 = vertices[face.Indices[0].VertexIndex]; Vector4 pos2 = vertices[face.Indices[1].VertexIndex]; Vector4 pos3 = vertices[face.Indices[2].VertexIndex]; Vector3 uv1 = textureVertices[face.Indices[0].TextureCoordIndex]; Vector3 uv2 = textureVertices[face.Indices[1].TextureCoordIndex]; Vector3 uv3 = textureVertices[face.Indices[2].TextureCoordIndex]; Vector4 edge1 = pos2 - pos1; Vector4 edge2 = pos3 - pos1; Vector3 deltaUV1 = uv2 - uv1; Vector3 deltaUV2 = uv3 - uv1; float f = 1.0f / (deltaUV1.X * deltaUV2.Y - deltaUV2.X * deltaUV1.Y); Vector3 tangent = new Vector3(); tangent.X = f * (deltaUV2.Y * edge1.X - deltaUV1.Y * edge2.X); tangent.Y = f * (deltaUV2.Y * edge1.Y - deltaUV1.Y * edge2.Y); tangent.Z = f * (deltaUV2.Y * edge1.Z - deltaUV1.Y * edge2.Z); tangent.Normalize(); Vector3 bitangent = new Vector3(); bitangent.X = f * (-deltaUV2.X * edge1.X + deltaUV1.X * edge2.X); bitangent.Y = f * (-deltaUV2.X * edge1.Y + deltaUV1.X * edge2.Y); bitangent.Z = f * (-deltaUV2.X * edge1.Z + deltaUV1.X * edge2.Z); bitangent.Normalize(); face.Tangent = tangent; face.Bitangent = bitangent; faces.Add(face); break; default: break; } } } List <int> meshIndices = new List <int>(); Mesh m = new Mesh(); Dictionary <String, int> vertmap = new Dictionary <string, int>(); int index = 0; foreach (Face face in faces) { foreach (FaceIndices fi in face.Indices) { Vertex v; if (vertmap.ContainsKey(fi.VertexId)) { int vindex = vertmap[fi.VertexId]; v = m.Vertices[vindex]; v.Tangent += face.Tangent; v.Bitangent += face.Bitangent; v.Tangent = v.Tangent.Normalized(); v.Bitangent = v.Bitangent.Normalized(); m.Vertices[vindex] = v; meshIndices.Add(vindex); } else { v = new Vertex(vertices[fi.VertexIndex].Xyz); v.Tangent = face.Tangent; v.Bitangent = face.Bitangent; if (fi.NormalIndex >= 0) { v.Normal = normals[fi.NormalIndex]; } if (fi.TextureCoordIndex >= 0) { v.TexCoord = textureVertices[fi.TextureCoordIndex].Xy; } m.Vertices.Add(v); vertmap.Add(fi.VertexId, index); meshIndices.Add(index); index++; } } } m.Indices = meshIndices.ToArray(); m.GenerateVAO(); return(m); }
private void SetGeometryData(string data) { string[] lines = data.Split("\n".ToCharArray()); Regex regexWhitespaces = new Regex(@"\s+"); bool isFirstInGroup = true; bool isFaceIndexPlus = true; for(int i = 0; i < lines.Length; i++) { string l = lines[i].Trim(); if(l.IndexOf("#") != -1) { // comment line continue; } string[] p = regexWhitespaces.Split(l); switch(p[0]) { case O: buffer.PushObject(p[1].Trim()); isFirstInGroup = true; break; case G: string groupName = null; if (p.Length >= 2) { groupName = p[1].Trim(); } isFirstInGroup = true; buffer.PushGroup(groupName); break; case V: buffer.PushVertex( new Vector3( cf(p[1]), cf(p[2]), cf(p[3]) ) ); break; case VT: buffer.PushUV(new Vector2( cf(p[1]), cf(p[2]) )); break; case VN: buffer.PushNormal(new Vector3( cf(p[1]), cf(p[2]), cf(p[3]) )); break; case F: FaceIndices[] faces = new FaceIndices[p.Length-1]; if (isFirstInGroup) { isFirstInGroup = false; string[] c = p[1].Trim().Split("/".ToCharArray()); isFaceIndexPlus = (ci(c[0]) >= 0); } GetFaceIndicesByOneFaceLine(faces, p, isFaceIndexPlus); if (p.Length == 4) { buffer.PushFace(faces[0]); buffer.PushFace(faces[1]); buffer.PushFace(faces[2]); } else if (p.Length == 5) { buffer.PushFace(faces[0]); buffer.PushFace(faces[1]); buffer.PushFace(faces[3]); buffer.PushFace(faces[3]); buffer.PushFace(faces[1]); buffer.PushFace(faces[2]); } else { Debug.LogWarning("face vertex count :"+(p.Length-1)+" larger than 4:"); } break; case MTL: mtllib = l.Substring(p[0].Length+1).Trim(); break; case UML: buffer.PushMaterialName(p[1].Trim()); break; } } // buffer.Trace(); }
private void SetGeometryData(string data) { string[] lines = data.Split("\n".ToCharArray()); for (int i = 0; i < lines.Length; i++) { string l = lines[i]; l = l.Replace(" ", " |").Replace("| ", "").Replace("|", ""); if (l.IndexOf("#") != -1) { l = l.Substring(0, l.IndexOf("#")); } string[] p = l.Split(" ".ToCharArray()); switch (p[0]) { case O: //buffer.PushObject(p[1].Trim()); break; case G: buffer.PushGroup(p[1].Trim()); break; case V: buffer.PushVertex(new Vector3(cf(p[1]), cf(p[2]), cf(p[3]))); break; case VT: buffer.PushUV(new Vector2(cf(p[1]), cf(p[2]))); break; case VN: buffer.PushNormal(new Vector3(cf(p[1]), cf(p[2]), cf(p[3]))); break; case F: for (int j = 1; j < p.Length; j++) { string[] c = p[j].Trim().Split("/".ToCharArray()); FaceIndices fi = new FaceIndices(); if (c[0] != "") { fi.vi = ci(c[0]) - 1; } if (c.Length > 1 && c[1] != "") { fi.vu = ci(c[1]) - 1; } if (c.Length > 2 && c[2] != "") { fi.vn = ci(c[2]) - 1; } if (c[0] != "") { buffer.PushFace(fi); } } break; case MTL: mtllib = p[1].Trim(); break; case UML: buffer.PushMaterialName(p[1].Trim()); break; } } //buffer.Trace(); }
///Geometry private void SetGeometryData(string data) { data = data.Replace("\r\n", "\n"); string[] lines = data.Split("\n".ToCharArray()); Vector3 v; mainso = new scaleoffset(); for (int i = 0; i < lines.Length; i++) { string l = lines[i]; l = Regex.Replace(l, @"# object", "o"); //tomekkie ALTERATION if (l.IndexOf("#") != -1) { l = l.Substring(0, l.IndexOf("#")); } l = Regex.Replace(l, @"\s+", " "); l = l.Trim(); string[] p = l.Split(" ".ToCharArray()); switch (p[0]) { case O: if (!EnforceSingleObj) { if (currentso != null) { currentso.vlast = vcount; objso.Add(currentso); } buffer.PushObject(p[1].Trim()); currentso = new scaleoffset(); currentso.vfirst = vcount; currentso.name = p[1].Trim(); } break; case G: buffer.PushGroup(p[1].Trim()); break; case V: if (p.Length >= 3) { v = new Vector3(cf(p[1]), cf(p[2]), 0 - cf(p[3])); buffer.PushVertex(v); //Any 0- Flipping should match normals vcount++; pushscaleoffset(mainso, v); if (currentso != null) { pushscaleoffset(currentso, v); } } break; case VT: if (p.Length >= 2) { buffer.PushUV(new Vector2(cf(p[1]), cf(p[2]))); } break; case VN: if (p.Length >= 3) { buffer.PushNormal(new Vector3(cf(p[1]), cf(p[2]), 0 - cf(p[3]))); //Any 0- Flipping should match vertex } break; case F: if (p.Length >= 4) { if (p.Length <= 5) //is triangle or quad { string[] c; for (int j = 0; j < p.Length - 3; j++) //get all possible triangles from line { FaceIndices fi = new FaceIndices(); //1 vert c = p[1].Trim().Split("/".ToCharArray()); if (c.Length > 0 && c[0] != string.Empty) { fi.vi = ci(c[0]) - 1; } if (c.Length > 1 && c[1] != string.Empty) { fi.vu = ci(c[1]) - 1; } if (c.Length > 2 && c[2] != string.Empty) { fi.vn = ci(c[2]) - 1; } buffer.PushFace(fi); for (int k = 0; k < 2; k++) //2nd and 3rd vert { fi = new FaceIndices(); int no = 3 - k + j; // To invert faces replace with : int no=2+k+j; c = p[no].Trim().Split("/".ToCharArray()); if (c.Length > 0 && c[0] != string.Empty) { fi.vi = ci(c[0]) - 1; } if (c.Length > 1 && c[1] != string.Empty) { fi.vu = ci(c[1]) - 1; } if (c.Length > 2 && c[2] != string.Empty) { fi.vn = ci(c[2]) - 1; } buffer.PushFace(fi); } } } else //is poly try triangulate, see TriPoly script { TriPoly triangulation; triangulation = new TriPoly(); Vector3[] pointlist = new Vector3[p.Length - 1]; //Vector3[] normallist=new Vector3[p.Length-1]; string[] c; for (int j = 1; j < p.Length; j++) //go through each faceindex in poly list and pull relevant vertice from geometrybuffer add to vector[] { c = p[j].Trim().Split("/".ToCharArray()); if (c.Length > 0 && c[0] != string.Empty) { pointlist[j - 1] = buffer.vertices[ci(c[0]) - 1]; } //if (c.Length > 2 && c[2] != string.Empty) {normallist[j-1] = buffer.normals[ci(c[2])-1];} } int[] indices; //if (normallist!=null) { // indices=triangulation.Patch(pointlist, normallist); //} else { indices = triangulation.Patch(pointlist); //, normallist //} if (indices.Length > 2) { for (int j = 0; j < indices.Length; ++j) //may need to reverse this? { FaceIndices fi = new FaceIndices(); c = p[indices[j] + 1].Trim().Split("/".ToCharArray()); if (c.Length > 0 && c[0] != string.Empty) { fi.vi = ci(c[0]) - 1; } if (c.Length > 1 && c[1] != string.Empty) { fi.vu = ci(c[1]) - 1; } if (c.Length > 2 && c[2] != string.Empty) { fi.vn = ci(c[2]) - 1; } buffer.PushFace(fi); } } } } break; case MTL: mtllib = p[1].Trim(); break; case UML: buffer.PushMaterialGroup(p[1].Trim()); //hello break; } } if (currentso != null) { currentso.vlast = vcount; objso.Add(currentso); } }
public static Mesh Load(string path) { if (!File.Exists(path)) { throw new FileNotFoundException("Unable to open \"" + path + "\", does not exist."); } List <Vector4> vertices = new List <Vector4>(); List <Vector3> textureVertices = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <FaceIndices> indices = new List <FaceIndices>(); using (StreamReader streamReader = new StreamReader(path)) { while (!streamReader.EndOfStream) { List <string> words = new List <string>(streamReader.ReadLine().ToLower().Split(' ')); words.RemoveAll(s => s == string.Empty); if (words.Count == 0) { continue; } string type = words[0]; words.RemoveAt(0); switch (type) { // vertex case "v": vertices.Add(new Vector4(float.Parse(words[0]), float.Parse(words[1]), float.Parse(words[2]), words.Count < 4 ? 1 : float.Parse(words[3]))); break; case "vt": textureVertices.Add(new Vector3(float.Parse(words[0]), float.Parse(words[1]), words.Count < 3 ? 0 : float.Parse(words[2]))); break; case "vn": normals.Add(new Vector3(float.Parse(words[0]), float.Parse(words[1]), float.Parse(words[2]))); break; // face case "f": foreach (string w in words) { if (w.Length == 0) { continue; } string[] comps = w.Split('/'); FaceIndices fi = new FaceIndices(); fi.VertexId = w; // subtract 1: indices start from 1, not 0 fi.VertexIndex = int.Parse(comps[0]) - 1; if (comps.Length > 1 && comps[1].Length != 0) { fi.TextureCoordIndex = int.Parse(comps[1]) - 1; } if (comps.Length > 2) { fi.NormalIndex = int.Parse(comps[2]) - 1; } indices.Add(fi); } break; default: break; } } } List <uint> meshIndices = new List <uint>(); Mesh m = new Mesh(); Dictionary <String, uint> vertmap = new Dictionary <string, uint>(); uint index = 0; foreach (FaceIndices fi in indices) { Vertex v; if (vertmap.ContainsKey(fi.VertexId)) { meshIndices.Add(vertmap[fi.VertexId]); } else { v = new Vertex(vertices[fi.VertexIndex].Xyz); if (fi.NormalIndex >= 0) { v.Normal = normals[fi.NormalIndex]; } if (fi.TextureCoordIndex >= 0) { v.TexCoord = textureVertices[fi.TextureCoordIndex].Xy; } m.Vertices.Add(v); vertmap.Add(fi.VertexId, index); meshIndices.Add(index); index++; } } m.Indices = meshIndices.ToArray(); m.GenerateVAO(); return(m); }
public void PushFace(FaceIndices f) { _curgr.Faces.Add(f); _current.AllFaces.Add(f); }
public static void SetGeometryData(string data, GeometryBuffer buffer) { var lines = data.Split("\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); for (var i = 0; i < lines.Length; i++) { var l = lines[i].Trim(); if (l.IndexOf("#") != -1) l = l.Substring(0, l.IndexOf("#")); var p = l.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); if (p.Length > 1) { switch (p[0]) { case O: buffer.PushObject(p[1].Trim()); break; case G: buffer.PushGroup(p[1].Trim()); break; case V: buffer.PushVertex(new Vector3( Cf(p[1]), Cf(p[2]), Cf(p[3])) ); break; case Vt: buffer.PushUv(new Vector2(Cf(p[1]), Cf(p[2]))); break; case Vn: buffer.PushNormal(new Vector3(Cf(p[1]), Cf(p[2]), Cf(p[3]))); break; case F: for (var j = 1; j < p.Length; j++) { var c = p[j].Trim().Split("/".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); var fi = new FaceIndices(); fi.Vi = Ci(c[0]) - 1; if (c.Length > 1) { fi.Vu = Ci(c[1]) - 1; } if (c.Length > 2) { fi.Vn = Ci(c[2]) - 1; } buffer.PushFace(fi); } break; case Mtl: // mtllib = p[1].Trim(); break; case Uml: buffer.PushMaterialName(p[1].Trim()); break; } } } // buffer.Trace(); }