Mesh::Mesh(Program &program) : Drawable(program) , vbuffer(-1) , nbuffer(-1) , tbuffer(-1) , fbuffer(-1) , texture(NULL) { AddVertex(-1.0, -1.0, -1.0); AddVertex(-1.0, 1.0, -1.0); AddVertex(1.0, 1.0, -1.0); AddVertex(1.0, -1.0, -1.0); AddTexcoord(0, 1); AddTexcoord(0, 0); AddTexcoord(1, 0); AddTexcoord(1, 1); AddColour(1.0, 0.0, 0.0); AddColour(0.0, 1.0, 0.0); AddColour(0.0, 0.0, 1.0); AddColour(1.0, 1.0, 1.0); AddNormal(0.0, 0.0, 1.0); AddNormal(0.0, 0.0, 1.0); AddNormal(0.0, 0.0, 1.0); AddNormal(0.0, 0.0, 1.0); AddFace(0, 1, 2); AddFace(2, 3, 0); InitBuffers(); }
void DBrush::BuildFromWinding(DWinding *w) { if(w->numpoints < 3) { Sys_ERROR("Winding has invalid number of points"); return; } DPlane* wPlane = w->WindingPlane(); DWinding* w2; w2 = w->CopyWinding(); int i; for(i = 0; i < w2->numpoints; i++) VectorAdd(w2->p[i], wPlane->normal, w2->p[i]); AddFace(w2->p[0], w2->p[1], w2->p[2], NULL); AddFace(w->p[2], w->p[1], w->p[0], NULL); for(i = 0; i < w->numpoints-1; i++) AddFace(w2->p[i], w->p[i], w->p[i+1], NULL); AddFace(w2->p[w->numpoints-1], w->p[w->numpoints-1], w->p[0], NULL); delete wPlane; delete w2; }
CMFRet CMesh::AddQuad(int iCorner1, int iCorner2, int iCorner3, int iCorner4) { CMFRet r1; CMFRet r2; r1 = AddFace(iCorner1, iCorner2, iCorner4); r1.Repack(0, 1, 3); r2 = AddFace(iCorner2, iCorner3, iCorner4); r2.Repack(1, 2, 3); r1.Pack2(r2); return r1; }
hacd::HaI32 AddFilterFace (hacd::HaU32 count, hacd::HaI32* const pool) { BeginFace(); HACD_ASSERT (count); bool reduction = true; while (reduction && !AddFace (hacd::HaI32 (count), pool)) { reduction = false; if (count >3) { for (hacd::HaU32 i = 0; i < count; i ++) { for (hacd::HaU32 j = i + 1; j < count; j ++) { if (pool[j] == pool[i]) { for (i = j; i < count - 1; i ++) { pool[i] = pool[i + 1]; } count --; i = count; reduction = true; break; } } } } } EndFace(); HACD_ASSERT (reduction); return reduction ? hacd::HaI32 (count) : 0; }
dgInt32 AddFilterFace(dgUnsigned32 count, dgInt32* const pool) { BeginFace(); _ASSERTE(count); bool reduction = true; while (reduction && !AddFace(dgInt32(count), pool)) { reduction = false; if (count > 3) { for (dgUnsigned32 i = 0; i < count; i++) { for (dgUnsigned32 j = i + 1; j < count; j++) { if (pool[j] == pool[i]) { for (i = j; i < count - 1; i++) { pool[i] = pool[i + 1]; } count--; i = count; reduction = true; break; } } } } } EndFace(); _ASSERTE(reduction); return reduction ? dgInt32(count) : 0; }
void Cube::GenerateFaces() { const int sideFacesCount = 4; const int verticesPerFaceCount = 4; for (int i = 0; i < sideFacesCount; ++i) { const int aIndex = i; const int bIndex = (i + 1) % verticesPerFaceCount; const int cIndex = bIndex + verticesPerFaceCount; const int dIndex = aIndex + verticesPerFaceCount; AddFace(aIndex, bIndex, cIndex, dIndex); } AddFace(0, 1, 2, 3);// bottom face AddFace(4, 5, 6, 7);// top face }
bool CSPrimPolyhedronReader::ReadFile(string filename) { vtkPolyData *polydata = NULL; switch (m_filetype) { case STL_FILE: { vtkSTLReader* reader = vtkSTLReader::New(); reader->SetFileName(filename.c_str()); reader->SetMerging(1); polydata = reader->GetOutput(0); break; } case PLY_FILE: { vtkPLYReader* reader = vtkPLYReader::New(); reader->SetFileName(filename.c_str()); polydata = reader->GetOutput(0); break; } case UNKNOWN: default: { cerr << "CSPrimPolyhedronReader::ReadFile: unknown filetype, skipping..." << endl; return false; break; } } polydata->Update(); if ((polydata->GetNumberOfPoints()==0) || (polydata->GetNumberOfCells()==0)) { cerr << "CSPrimPolyhedronReader::ReadFile: file invalid or empty, skipping ..." << endl; return false; } vtkCellArray *verts = polydata->GetPolys(); if (verts->GetNumberOfCells()==0) { cerr << "CSPrimPolyhedronReader::ReadFile: file invalid or empty, skipping ..." << endl; return false; } for (int n=0;n<polydata->GetNumberOfPoints();++n) AddVertex(polydata->GetPoint(n)); vtkIdType numP; vtkIdType *vertices = new vtkIdType[10]; while (verts->GetNextCell(numP, vertices)) { face f; f.numVertex=numP; f.vertices = new int[f.numVertex]; for (unsigned int np=0;np<f.numVertex;++np) f.vertices[np]=vertices[np]; AddFace(f); } return true; }
/* ============= */ int EXPORT FAR PASCAL EnumFacesProc (LPLOGFONT lf, LPTEXTMETRIC tm, short FontType, LPSTR Data) /* Data should point to a handle to the dialog box */ /* lists only fixed pitch fonts that match the selected charset */ { AddFace (*(HWND FAR *)Data, lf->lfFaceName); return 1; } /* EnumFacesProc */
void Mesh::ReadFaceData(FILE *fp, int num) { int f[4]; char buf[1024]; for(int i = 0; i < num; i++) { fgets(buf, 1024, fp); if(sscanf(buf, "%*d %d %d %d %d", f, f+1, f+2, f+3) == 4) { AddFace(f[0], f[1], f[2]); AddFace(f[2], f[3], f[0]); } else if(sscanf(buf, "%*d %d %d %d" , f, f+1, f+2) == 3) { AddFace(f[0], f[1], f[2]); } } }
void Patch::GeneratePlane() { // Allocate vertices for the plane int vertNum = 0; GLfloat numVertsf = (GLfloat)NUM_VERTS; for (GLfloat i = 0.0f; i < numVertsf; i += 1.0f) { for (GLfloat j = 0.0f; j < numVertsf; j += 1.0f) { AddVert(0.0f, 0.0f, 0.0f, i / (numVertsf - 1.0f), j / (numVertsf - 1.0f), vertNum++); } } int cp = 0; float zOffset = 1.0f / 3.0f; float xOffset = 1.0f / 3.0f; glm::vec3 baseVec = glm::vec3(-0.5f, 0.0f, -0.5f); for (int row = 0; row < 4; ++row) { _controlPoints[cp++] = glm::vec3(baseVec.x, baseVec.y, baseVec.z + zOffset * row); _controlPoints[cp++] = glm::vec3(baseVec.x + xOffset, baseVec.y, baseVec.z + zOffset * row); _controlPoints[cp++] = glm::vec3(baseVec.x + xOffset * 2, baseVec.y, baseVec.z + zOffset * row); _controlPoints[cp++] = glm::vec3(baseVec.x + xOffset * 3, baseVec.y, baseVec.z + zOffset * row); } // Add elements for faces int faceNum = 0; int quadsPerRow = NUM_VERTS * (NUM_VERTS - 1); for (int i = 0; i < quadsPerRow; i += NUM_VERTS) { for (int j = 0; j < NUM_VERTS - 1; ++j) { AddFace(i + j, i + j + 1, i + NUM_VERTS + j, faceNum++); AddFace(i + j + 1, i + NUM_VERTS + j + 1, i + NUM_VERTS + j, faceNum++); } } glBindBuffer(GL_VERTEX_ARRAY, _vao); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(_elements), (void*)&_elements, GL_DYNAMIC_DRAW); UpdateSurface(); }
bool Delaunay3D::Invoke() { typedef leda::d3_rat_point point3_t; _simplices.clear(); if(!NB::FirstSelectedMesh()) { NB::LogPrintf("no geometry selected.\n"); return false; } NB::SetOperatorName("Delaunay 3D"); NB::Mesh cloud = NB::FirstSelectedMesh(); COM_assert(cloud); leda::nb::RatPolyMesh& cloudGraph = NB::GetGraph(cloud); leda::list<point3_t> L; leda::node v; forall_nodes(v, cloudGraph) L.push_back(cloudGraph.position_of(v)); leda::list<leda::fork::simplex_t> S; std::cout << "Delaunay3D: calling D3_DELAUNAY ... " << std::flush; // NOTE: include d3_delaunay.cpp when building LEDA leda::fork::D3_DELAUNAY(L, S); std::cout << "DONE" << std::endl; _mesh = NB::CreateMesh(); NB::SetMeshRenderMode(_mesh, NB::RM_ALL); NB::SetMeshPosition(_mesh, NB::GetMeshPosition(cloud)); leda::nb::RatPolyMesh& graph = NB::GetGraph(_mesh); std::cout << "Delaunay3D: creating simplex geometries ... " << std::flush; leda::list_item it; forall_items(it, S) { Simplex simplex; simplex.center = leda::rat_vector::zero(3); leda::rat_vector pos[4]; for(int i = 0; i < 4; ++i) { pos[i] = S[it].verts[i].to_vector(); simplex.center += pos[i]; simplex.verts[i] = graph.new_node(); graph.set_position(simplex.verts[i], pos[i]); } simplex.center /= 4; for(int i = 0; i < 4; ++i) simplex.localPos[i] = pos[i] - simplex.center; AddFace(graph, simplex.verts[0], simplex.verts[1], simplex.verts[2], simplex.verts[3]); _simplices.push_back(simplex); }
void DBrush::LoadFromBrush(scene::Node* brush, bool textured) { ClearFaces(); ClearPoints(); #if 0 for(int i = g_FuncTable.m_pfnGetFaceCount(brush)-1; i >= 0 ; i--) { // running backwards so i dont have to use the count function each time (OPT) _QERFaceData* faceData = g_FuncTable.m_pfnGetFaceData(brush, i); if(faceData == NULL) DoMessageBox("Null pointer returned", "WARNING!", MB_OK); if(textured) AddFace(faceData->m_v1, faceData->m_v2, faceData->m_v3, faceData); else AddFace(faceData->m_v1, faceData->m_v2, faceData->m_v3, NULL); } #endif QER_brush = brush; }
void TriSoup::Merge(const TriSoup* other) { const int prevNumVerts = NumVertices(); for(int i = 0, c = other->NumVertices(); i < c; ++i) AddVertex(other->m_vertices[i].m_pos); for(int i = 0, c = other->NumFaces(); i < c; ++i) { int indices[3]; other->GetFace(i, indices); for(int j = 0; j < 3; ++j) indices[j] += prevNumVerts; AddFace(indices[0], indices[1], indices[2]); } }
CMFRet CMesh::AddPolygon(CArrayInt* paiCorners) { CMFRet r; if (paiCorners->NumElements() < 3) { r.PackEmpty(); return r; } else if (paiCorners->NumElements() == 3) { return AddFace(paiCorners->GetValue(0), paiCorners->GetValue(1), paiCorners->GetValue(2)); } else if (paiCorners->NumElements() == 4) { return AddQuad(paiCorners->GetValue(0), paiCorners->GetValue(1), paiCorners->GetValue(2), paiCorners->GetValue(3)); } else { //Remember to return the new edge count also. r.PackOverflow(); return r; } }
void IFXNeighborResController::AddFaces(U32 meshIndex) { ResolutionState* state = &(m_pMeshStates[meshIndex]); IFXUpdates* pUpdates = m_pUpdatesGroup->GetUpdates(meshIndex); IFXResolutionChange* rc = &(pUpdates->pResChanges[state->resolutionChangeIndex]); ++state->resolutionChangeIndex; // Increment the face updates index to reflect modified faces state->faceUpdateIndex += rc->numFaceUpdates; if (rc->deltaFaces == 0) return; IFXNeighborFace* pNeighborFaces = m_pNeighborMesh->GetNeighborFaceArray(meshIndex); U32 faceIndex = state->numFaces; state->numFaces += rc->deltaFaces; while (faceIndex < state->numFaces) { // Determine corner across from collapse edge. U32 xCornerIndex = pNeighborFaces[faceIndex].GetFaceFlags()->collapseIndex; if (xCornerIndex < NO_COLLAPSE_INDEX) AddFace(meshIndex, faceIndex, xCornerIndex); ++faceIndex; } }
bool Map::CompileEQGv4() { collide_verts.clear(); collide_indices.clear(); non_collide_verts.clear(); non_collide_indices.clear(); current_collide_index = 0; current_non_collide_index = 0; collide_vert_to_index.clear(); non_collide_vert_to_index.clear(); map_models.clear(); map_eqg_models.clear(); map_placeables.clear(); if(!terrain) return false; auto &water_sheets = terrain->GetWaterSheets(); for(size_t i = 0; i < water_sheets.size(); ++i) { auto &sheet = water_sheets[i]; if(sheet->GetTile()) { auto &tiles = terrain->GetTiles(); for(size_t j = 0; j < tiles.size(); ++j) { float x = tiles[j]->GetX(); float y = tiles[j]->GetY(); float z = tiles[j]->GetBaseWaterLevel(); float QuadVertex1X = x; float QuadVertex1Y = y; float QuadVertex1Z = z; float QuadVertex2X = QuadVertex1X + (terrain->GetOpts().quads_per_tile * terrain->GetOpts().units_per_vert); float QuadVertex2Y = QuadVertex1Y; float QuadVertex2Z = QuadVertex1Z; float QuadVertex3X = QuadVertex2X; float QuadVertex3Y = QuadVertex1Y + (terrain->GetOpts().quads_per_tile * terrain->GetOpts().units_per_vert); float QuadVertex3Z = QuadVertex1Z; float QuadVertex4X = QuadVertex1X; float QuadVertex4Y = QuadVertex3Y; float QuadVertex4Z = QuadVertex1Z; uint32_t current_vert = (uint32_t)non_collide_verts.size() + 3; non_collide_verts.push_back(glm::vec3(QuadVertex1X, QuadVertex1Y, QuadVertex1Z)); non_collide_verts.push_back(glm::vec3(QuadVertex2X, QuadVertex2Y, QuadVertex2Z)); non_collide_verts.push_back(glm::vec3(QuadVertex3X, QuadVertex3Y, QuadVertex3Z)); non_collide_verts.push_back(glm::vec3(QuadVertex4X, QuadVertex4Y, QuadVertex4Z)); non_collide_indices.push_back(current_vert); non_collide_indices.push_back(current_vert - 2); non_collide_indices.push_back(current_vert - 1); non_collide_indices.push_back(current_vert); non_collide_indices.push_back(current_vert - 3); non_collide_indices.push_back(current_vert - 2); } } else { uint32_t id = (uint32_t)non_collide_verts.size(); non_collide_verts.push_back(glm::vec3(sheet->GetMinY(), sheet->GetMinX(), sheet->GetZHeight())); non_collide_verts.push_back(glm::vec3(sheet->GetMinY(), sheet->GetMaxX(), sheet->GetZHeight())); non_collide_verts.push_back(glm::vec3(sheet->GetMaxY(), sheet->GetMinX(), sheet->GetZHeight())); non_collide_verts.push_back(glm::vec3(sheet->GetMaxY(), sheet->GetMaxX(), sheet->GetZHeight())); non_collide_indices.push_back(id); non_collide_indices.push_back(id + 1); non_collide_indices.push_back(id + 2); non_collide_indices.push_back(id + 1); non_collide_indices.push_back(id + 3); non_collide_indices.push_back(id + 2); } } auto &invis_walls = terrain->GetInvisWalls(); for (size_t i = 0; i < invis_walls.size(); ++i) { auto &wall = invis_walls[i]; auto &verts = wall->GetVerts(); for(size_t j = 0; j < verts.size(); ++j) { if (j + 1 == verts.size()) break; float t; auto v1 = verts[j]; auto v2 = verts[j + 1]; t = v1.x; v1.x = v1.y; v1.y = t; t = v2.x; v2.x = v2.y; v2.y = t; glm::vec3 v3 = v1; v3.z += 1000.0; glm::vec3 v4 = v2; v4.z += 1000.0; AddFace(v2, v1, v3, true); AddFace(v3, v4, v2, true); AddFace(v3, v1, v2, true); AddFace(v2, v4, v3, true); } } //map_eqg_models auto &models = terrain->GetModels(); auto model_iter = models.begin(); while(model_iter != models.end()) { auto &model = model_iter->second; if (map_eqg_models.count(model->GetName()) == 0) { map_eqg_models[model->GetName()] = model; } ++model_iter; } //map_placeables auto &pgs = terrain->GetPlaceableGroups(); for(size_t i = 0; i < pgs.size(); ++i) { map_group_placeables.push_back(pgs[i]); } return true; }
void dgConvexHull4d::InsertNewVertex(dgInt32 vertexIndex, dgListNode* const frontFace, dgList<dgListNode*>& deletedFaces, dgList<dgListNode*>& newFaces) { dgAssert (Sanity()); dgList<dgListNode*> stack(GetAllocator()); dgInt32 mark = IncMark(); stack.Append(frontFace); dgHullVector* const hullVertexArray = &m_points[0]; const dgBigVector& p = hullVertexArray[vertexIndex]; while (stack.GetCount()) { dgList<dgListNode*>::dgListNode* const stackNode = stack.GetLast(); dgListNode* const node = stackNode->GetInfo(); stack.Remove(stackNode); dgConvexHull4dTetraherum* const face = &node->GetInfo(); if ((face->GetMark() != mark) && (face->Evalue(hullVertexArray, p) > dgFloat64(0.0f))) { #ifdef _DEBUG for (dgList<dgListNode*>::dgListNode* deleteNode = deletedFaces.GetFirst(); deleteNode; deleteNode = deleteNode->GetNext()) { dgAssert (deleteNode->GetInfo() != node); } #endif deletedFaces.Append(node); face->SetMark(mark); for (dgInt32 i = 0; i < 4; i ++) { dgListNode* const twinNode = (dgListNode*)face->m_faces[i].m_twin; dgAssert (twinNode); dgConvexHull4dTetraherum* const twinFace = &twinNode->GetInfo(); if (twinFace->GetMark() != mark) { stack.Append(twinNode); } } } } dgTree<dgListNode*, dgInt32> perimeter(GetAllocator()); for (dgList<dgListNode*>::dgListNode* deleteNode = deletedFaces.GetFirst(); deleteNode; deleteNode = deleteNode->GetNext()) { dgListNode* const deleteTetraNode = deleteNode->GetInfo(); dgConvexHull4dTetraherum* const deletedTetra = &deleteTetraNode->GetInfo(); dgAssert (deletedTetra->GetMark() == mark); for (dgInt32 i = 0; i < 4; i ++) { dgListNode* const twinNode = deletedTetra->m_faces[i].m_twin; dgConvexHull4dTetraherum* const twinTetra = &twinNode->GetInfo(); if (twinTetra->GetMark() != mark) { if (!perimeter.Find(twinTetra->m_uniqueID)) { perimeter.Insert(twinNode, twinTetra->m_uniqueID); } } deletedTetra->m_faces[i].m_twin = NULL; } } dgList<dgListNode*> coneList(GetAllocator()); dgTree<dgListNode*, dgInt32>::Iterator iter (perimeter); for (iter.Begin(); iter; iter ++) { dgListNode* const perimeterNode = iter.GetNode()->GetInfo(); dgConvexHull4dTetraherum* const perimeterTetra = &perimeterNode->GetInfo(); for (dgInt32 i = 0; i < 4; i ++) { dgConvexHull4dTetraherum::dgTetrahedrumFace* const perimeterFace = &perimeterTetra->m_faces[i]; if (perimeterFace->m_twin->GetInfo().GetMark() == mark) { dgListNode* const newNode = AddFace (vertexIndex, perimeterFace->m_index[0], perimeterFace->m_index[1], perimeterFace->m_index[2]); newFaces.Addtop(newNode); dgConvexHull4dTetraherum* const newTetra = &newNode->GetInfo(); newTetra->m_faces[2].m_twin = perimeterNode; perimeterFace->m_twin = newNode; coneList.Append (newNode); } } } for (dgList<dgListNode*>::dgListNode* coneNode = coneList.GetFirst(); coneNode->GetNext(); coneNode = coneNode->GetNext()) { dgListNode* const coneNodeA = coneNode->GetInfo(); for (dgList<dgListNode*>::dgListNode* nextConeNode = coneNode->GetNext(); nextConeNode; nextConeNode = nextConeNode->GetNext()) { dgListNode* const coneNodeB = nextConeNode->GetInfo(); LinkSibling (coneNodeA, coneNodeB); } } }
bool Map::CompileS3D( std::vector<EQEmu::S3D::WLDFragment> &zone_frags, std::vector<EQEmu::S3D::WLDFragment> &zone_object_frags, std::vector<EQEmu::S3D::WLDFragment> &object_frags ) { collide_verts.clear(); collide_indices.clear(); non_collide_verts.clear(); non_collide_indices.clear(); current_collide_index = 0; current_non_collide_index = 0; collide_vert_to_index.clear(); non_collide_vert_to_index.clear(); map_models.clear(); map_eqg_models.clear(); map_placeables.clear(); eqLogMessage(LogTrace, "Processing s3d zone geometry fragments."); for(uint32_t i = 0; i < zone_frags.size(); ++i) { if(zone_frags[i].type == 0x36) { EQEmu::S3D::WLDFragment36 &frag = reinterpret_cast<EQEmu::S3D::WLDFragment36&>(zone_frags[i]); auto model = frag.GetData(); auto &mod_polys = model->GetPolygons(); auto &mod_verts = model->GetVertices(); for (uint32_t j = 0; j < mod_polys.size(); ++j) { auto ¤t_poly = mod_polys[j]; auto v1 = mod_verts[current_poly.verts[0]]; auto v2 = mod_verts[current_poly.verts[1]]; auto v3 = mod_verts[current_poly.verts[2]]; float t = v1.pos.x; v1.pos.x = v1.pos.y; v1.pos.y = t; t = v2.pos.x; v2.pos.x = v2.pos.y; v2.pos.y = t; t = v3.pos.x; v3.pos.x = v3.pos.y; v3.pos.y = t; if(current_poly.flags == 0x10) AddFace(v1.pos, v2.pos, v3.pos, false); else AddFace(v1.pos, v2.pos, v3.pos, true); } } } eqLogMessage(LogTrace, "Processing zone placeable fragments."); std::vector<std::pair<std::shared_ptr<EQEmu::Placeable>, std::shared_ptr<EQEmu::S3D::Geometry>>> placables; std::vector<std::pair<std::shared_ptr<EQEmu::Placeable>, std::shared_ptr<EQEmu::S3D::SkeletonTrack>>> placables_skeleton; for (uint32_t i = 0; i < zone_object_frags.size(); ++i) { if (zone_object_frags[i].type == 0x15) { EQEmu::S3D::WLDFragment15 &frag = reinterpret_cast<EQEmu::S3D::WLDFragment15&>(zone_object_frags[i]); auto plac = frag.GetData(); if(!plac) { eqLogMessage(LogWarn, "Placeable entry was not found."); continue; } bool found = false; for (uint32_t o = 0; o < object_frags.size(); ++o) { if (object_frags[o].type == 0x14) { EQEmu::S3D::WLDFragment14 &obj_frag = reinterpret_cast<EQEmu::S3D::WLDFragment14&>(object_frags[o]); auto mod_ref = obj_frag.GetData(); if(mod_ref->GetName().compare(plac->GetName()) == 0) { found = true; auto &frag_refs = mod_ref->GetFrags(); for (uint32_t m = 0; m < frag_refs.size(); ++m) { if (object_frags[frag_refs[m] - 1].type == 0x2D) { EQEmu::S3D::WLDFragment2D &r_frag = reinterpret_cast<EQEmu::S3D::WLDFragment2D&>(object_frags[frag_refs[m] - 1]); auto m_ref = r_frag.GetData(); EQEmu::S3D::WLDFragment36 &mod_frag = reinterpret_cast<EQEmu::S3D::WLDFragment36&>(object_frags[m_ref]); auto mod = mod_frag.GetData(); placables.push_back(std::make_pair(plac, mod)); } else if (object_frags[frag_refs[m] - 1].type == 0x11) { EQEmu::S3D::WLDFragment11 &r_frag = reinterpret_cast<EQEmu::S3D::WLDFragment11&>(object_frags[frag_refs[m] - 1]); auto s_ref = r_frag.GetData(); EQEmu::S3D::WLDFragment10 &skeleton_frag = reinterpret_cast<EQEmu::S3D::WLDFragment10&>(object_frags[s_ref]); auto skele = skeleton_frag.GetData(); placables_skeleton.push_back(std::make_pair(plac, skele)); } } break; } } } if(!found) { eqLogMessage(LogWarn, "Could not find model for placeable %s", plac->GetName().c_str()); } } } eqLogMessage(LogTrace, "Processing s3d placeables."); size_t pl_sz = placables.size(); for(size_t i = 0; i < pl_sz; ++i) { auto plac = placables[i].first; auto model = placables[i].second; auto &mod_polys = model->GetPolygons(); auto &mod_verts = model->GetVertices(); float offset_x = plac->GetX(); float offset_y = plac->GetY(); float offset_z = plac->GetZ(); float rot_x = plac->GetRotateX() * 3.14159f / 180.0f; float rot_y = plac->GetRotateY() * 3.14159f / 180.0f; float rot_z = plac->GetRotateZ() * 3.14159f / 180.0f; float scale_x = plac->GetScaleX(); float scale_y = plac->GetScaleY(); float scale_z = plac->GetScaleZ(); if (map_models.count(model->GetName()) == 0) { map_models[model->GetName()] = model; } std::shared_ptr<EQEmu::Placeable> gen_plac(new EQEmu::Placeable()); gen_plac->SetFileName(model->GetName()); gen_plac->SetLocation(offset_x, offset_y, offset_z); //y rotation seems backwards on s3ds, probably cause of the weird coord system they used back then //x rotation might be too but there are literally 0 x rotated placeables in all the s3ds so who knows gen_plac->SetRotation(rot_x, -rot_y, rot_z); gen_plac->SetScale(scale_x, scale_y, scale_z); map_placeables.push_back(gen_plac); eqLogMessage(LogTrace, "Adding placeable %s at (%f, %f, %f)", model->GetName().c_str(), offset_x, offset_y, offset_z); } eqLogMessage(LogTrace, "Processing s3d animated placeables."); pl_sz = placables_skeleton.size(); for (size_t i = 0; i < pl_sz; ++i) { auto &plac = placables_skeleton[i].first; auto &bones = placables_skeleton[i].second->GetBones(); if(bones.size() > 0) { float offset_x = plac->GetX(); float offset_y = plac->GetY(); float offset_z = plac->GetZ(); float rot_x = plac->GetRotateX() * 3.14159f / 180.0f; float rot_y = plac->GetRotateY() * 3.14159f / 180.0f; float rot_z = plac->GetRotateZ() * 3.14159f / 180.0f; float scale_x = plac->GetScaleX(); float scale_y = plac->GetScaleY(); float scale_z = plac->GetScaleZ(); TraverseBone(bones[0], glm::vec3(offset_x, offset_y, offset_z), glm::vec3(rot_x, rot_y, rot_z), glm::vec3(scale_x, scale_y, scale_z)); } } return true; }
bool Map::CompileEQG( std::vector<std::shared_ptr<EQEmu::EQG::Geometry>> &models, std::vector<std::shared_ptr<EQEmu::Placeable>> &placeables, std::vector<std::shared_ptr<EQEmu::EQG::Region>> ®ions, std::vector<std::shared_ptr<EQEmu::Light>> &lights ) { collide_verts.clear(); collide_indices.clear(); non_collide_verts.clear(); non_collide_indices.clear(); current_collide_index = 0; current_non_collide_index = 0; collide_vert_to_index.clear(); non_collide_vert_to_index.clear(); map_models.clear(); map_eqg_models.clear(); map_placeables.clear(); for(uint32_t i = 0; i < placeables.size(); ++i) { std::shared_ptr<EQEmu::Placeable> &plac = placeables[i]; std::shared_ptr<EQEmu::EQG::Geometry> model; bool is_ter = false; if(plac->GetName().substr(0, 3).compare("TER") == 0 || plac->GetFileName().substr(plac->GetFileName().length() - 4, 4).compare(".ter") == 0) is_ter = true; for(uint32_t j = 0; j < models.size(); ++j) { if(models[j]->GetName().compare(plac->GetFileName()) == 0) { model = models[j]; break; } } if (!model) { eqLogMessage(LogWarn, "Could not find placeable %s.", plac->GetFileName().c_str()); continue; } float offset_x = plac->GetX(); float offset_y = plac->GetY(); float offset_z = plac->GetZ(); float rot_x = plac->GetRotateX() * 3.14159f / 180.0f; float rot_y = plac->GetRotateY() * 3.14159f / 180.0f; float rot_z = plac->GetRotateZ() * 3.14159f / 180.0f; float scale_x = plac->GetScaleX(); float scale_y = plac->GetScaleY(); float scale_z = plac->GetScaleZ(); if(!is_ter) { if (map_eqg_models.count(model->GetName()) == 0) { map_eqg_models[model->GetName()] = model; } std::shared_ptr<EQEmu::Placeable> gen_plac(new EQEmu::Placeable()); gen_plac->SetFileName(model->GetName()); gen_plac->SetLocation(offset_x, offset_y, offset_z); gen_plac->SetRotation(rot_x, rot_y, rot_z); gen_plac->SetScale(scale_x, scale_y, scale_z); map_placeables.push_back(gen_plac); eqLogMessage(LogTrace, "Adding placeable %s at (%f, %f, %f)", model->GetName().c_str(), offset_x, offset_y, offset_z); continue; } auto &mod_polys = model->GetPolygons(); auto &mod_verts = model->GetVertices(); for (uint32_t j = 0; j < mod_polys.size(); ++j) { auto ¤t_poly = mod_polys[j]; auto v1 = mod_verts[current_poly.verts[0]]; auto v2 = mod_verts[current_poly.verts[1]]; auto v3 = mod_verts[current_poly.verts[2]]; float t = v1.pos.x; v1.pos.x = v1.pos.y; v1.pos.y = t; t = v2.pos.x; v2.pos.x = v2.pos.y; v2.pos.y = t; t = v3.pos.x; v3.pos.x = v3.pos.y; v3.pos.y = t; if (current_poly.flags & 0x01) AddFace(v1.pos, v2.pos, v3.pos, false); else AddFace(v1.pos, v2.pos, v3.pos, true); } } return true; }
static std::shared_ptr<asd::Mesh> CreateMesh(asd::Graphics* graphics) { uint8_t weights1[4]; weights1[0] = 255; weights1[1] = 0; weights1[2] = 0; weights1[3] = 0; int* pweights1 = (int*) weights1; uint8_t weights2[4]; weights2[0] = 0; weights2[1] = 255; weights2[2] = 0; weights2[3] = 0; int* pweights2 = (int*) weights2; uint8_t indexes[4]; indexes[0] = 0; indexes[1] = 1; indexes[2] = 0; indexes[3] = 0; int* pindexes = (int*) indexes; auto mesh = graphics->CreateMesh(); mesh->AddVertex(asd::Vector3DF(-0.5, 0.5, 0.5), asd::Vector3DF(0, 0, 1), asd::Vector3DF(0, 1, 0), asd::Vector2DF(0, 0), asd::Vector2DF(0, 0), asd::Color(255, 255, 255, 255), *pweights1, *pindexes); mesh->AddVertex(asd::Vector3DF(-0.5, -0.5, 0.5), asd::Vector3DF(0, 0, 1), asd::Vector3DF(0, 1, 0), asd::Vector2DF(0, 1), asd::Vector2DF(0, 1), asd::Color(255, 255, 255, 255), *pweights2, *pindexes); mesh->AddVertex(asd::Vector3DF(0.5, 0.5, 0.5), asd::Vector3DF(0, 0, 1), asd::Vector3DF(0, 1, 0), asd::Vector2DF(1, 0), asd::Vector2DF(1, 0), asd::Color(255, 255, 255, 255), *pweights1, *pindexes); mesh->AddVertex(asd::Vector3DF(0.5, -0.5, 0.5), asd::Vector3DF(0, 0, 1), asd::Vector3DF(0, 1, 0), asd::Vector2DF(1, 1), asd::Vector2DF(1, 1), asd::Color(255, 255, 255, 255), *pweights2, *pindexes); mesh->AddVertex(asd::Vector3DF(0.5, 0.5, -0.5), asd::Vector3DF(1, 0, 0), asd::Vector3DF(0, 1, 0), asd::Vector2DF(1, 0), asd::Vector2DF(1, 0), asd::Color(255, 255, 255, 255), *pweights1, *pindexes); mesh->AddVertex(asd::Vector3DF(0.5, -0.5, -0.5), asd::Vector3DF(1, 0, 0), asd::Vector3DF(0, 1, 0), asd::Vector2DF(1, 1), asd::Vector2DF(1, 1), asd::Color(255, 255, 255, 255), *pweights2, *pindexes); mesh->AddVertex(asd::Vector3DF(-0.5, 0.5, -0.5), asd::Vector3DF(0, 0, -1), asd::Vector3DF(0, 1, 0), asd::Vector2DF(1, 0), asd::Vector2DF(1, 0), asd::Color(255, 255, 255, 255), *pweights1, *pindexes); mesh->AddVertex(asd::Vector3DF(-0.5, -0.5, -0.5), asd::Vector3DF(0, 0, -1), asd::Vector3DF(0, 1, 0), asd::Vector2DF(1, 1), asd::Vector2DF(1, 1), asd::Color(255, 255, 255, 255), *pweights2, *pindexes); mesh->AddVertex(asd::Vector3DF(-0.5, 0.5, 0.5), asd::Vector3DF(-1, 0, 0), asd::Vector3DF(0, 1, 0), asd::Vector2DF(1, 0), asd::Vector2DF(1, 0), asd::Color(255, 255, 255, 255), *pweights1, *pindexes); mesh->AddVertex(asd::Vector3DF(-0.5, 0.5, 0.5), asd::Vector3DF(0, 1, 0), asd::Vector3DF(0, 0, -1), asd::Vector2DF(0, 1), asd::Vector2DF(0, 1), asd::Color(255, 255, 255, 255), *pweights1, *pindexes); mesh->AddVertex(asd::Vector3DF(-0.5, -0.5, 0.5), asd::Vector3DF(-1, 0, 0), asd::Vector3DF(0, 1, 0), asd::Vector2DF(1, 1), asd::Vector2DF(1, 1), asd::Color(255, 255, 255, 255), *pweights2, *pindexes); mesh->AddVertex(asd::Vector3DF(-0.5, -0.5, 0.5), asd::Vector3DF(0, -1, 0), asd::Vector3DF(0, 0, 1), asd::Vector2DF(0, 0), asd::Vector2DF(0, 0), asd::Color(255, 255, 255, 255), *pweights2, *pindexes); mesh->AddVertex(asd::Vector3DF(0.5, 0.5, 0.5), asd::Vector3DF(1, 0, 0), asd::Vector3DF(0, 1, 0), asd::Vector2DF(0, 0), asd::Vector2DF(0, 0), asd::Color(255, 255, 255, 255), *pweights1, *pindexes); mesh->AddVertex(asd::Vector3DF(0.5, 0.5, 0.5), asd::Vector3DF(0, 1, 0), asd::Vector3DF(0, 0, -1), asd::Vector2DF(1, 1), asd::Vector2DF(1, 1), asd::Color(255, 255, 255, 255), *pweights1, *pindexes); mesh->AddVertex(asd::Vector3DF(0.5, -0.5, 0.5), asd::Vector3DF(1, 0, 0), asd::Vector3DF(0, 1, 0), asd::Vector2DF(0, 1), asd::Vector2DF(0, 1), asd::Color(255, 255, 255, 255), *pweights2, *pindexes); mesh->AddVertex(asd::Vector3DF(0.5, -0.5, 0.5), asd::Vector3DF(0, -1, 0), asd::Vector3DF(0, 0, 1), asd::Vector2DF(1, 0), asd::Vector2DF(1, 0), asd::Color(255, 255, 255, 255), *pweights2, *pindexes); mesh->AddVertex(asd::Vector3DF(0.5, 0.5, -0.5), asd::Vector3DF(0, 0, -1), asd::Vector3DF(0, 1, 0), asd::Vector2DF(0, 0), asd::Vector2DF(0, 0), asd::Color(255, 255, 255, 255), *pweights1, *pindexes); mesh->AddVertex(asd::Vector3DF(0.5, 0.5, -0.5), asd::Vector3DF(0, 1, 0), asd::Vector3DF(0, 0, -1), asd::Vector2DF(1, 0), asd::Vector2DF(1, 0), asd::Color(255, 255, 255, 255), *pweights1, *pindexes); mesh->AddVertex(asd::Vector3DF(0.5, -0.5, -0.5), asd::Vector3DF(0, 0, -1), asd::Vector3DF(0, 1, 0), asd::Vector2DF(0, 1), asd::Vector2DF(0, 1), asd::Color(255, 255, 255, 255), *pweights2, *pindexes); mesh->AddVertex(asd::Vector3DF(0.5, -0.5, -0.5), asd::Vector3DF(0, -1, 0), asd::Vector3DF(0, 0, 1), asd::Vector2DF(1, 1), asd::Vector2DF(1, 1), asd::Color(255, 255, 255, 255), *pweights2, *pindexes); mesh->AddVertex(asd::Vector3DF(-0.5, 0.5, -0.5), asd::Vector3DF(-1, 0, 0), asd::Vector3DF(0, 1, 0), asd::Vector2DF(0, 0), asd::Vector2DF(0, 0), asd::Color(255, 255, 255, 255), *pweights1, *pindexes); mesh->AddVertex(asd::Vector3DF(-0.5, 0.5, -0.5), asd::Vector3DF(0, 1, 0), asd::Vector3DF(0, 0, -1), asd::Vector2DF(0, 0), asd::Vector2DF(0, 0), asd::Color(255, 255, 255, 255), *pweights1, *pindexes); mesh->AddVertex(asd::Vector3DF(-0.5, -0.5, -0.5), asd::Vector3DF(-1, 0, 0), asd::Vector3DF(0, 1, 0), asd::Vector2DF(0, 1), asd::Vector2DF(0, 1), asd::Color(255, 255, 255, 255), *pweights2, *pindexes); mesh->AddVertex(asd::Vector3DF(-0.5, -0.5, -0.5), asd::Vector3DF(0, -1, 0), asd::Vector3DF(0, 0, 1), asd::Vector2DF(0, 1), asd::Vector2DF(0, 1), asd::Color(255, 255, 255, 255), *pweights2, *pindexes); mesh->AddFace(0, 2, 3, 0); mesh->AddFace(0, 3, 1, 0); mesh->AddFace(12, 4, 5, 0); mesh->AddFace(12, 5, 14, 0); mesh->AddFace(16, 6, 7, 0); mesh->AddFace(16, 7, 18, 0); mesh->AddFace(20, 8, 10, 0); mesh->AddFace(20, 10, 22, 0); mesh->AddFace(21, 17, 13, 0); mesh->AddFace(21, 13, 9, 0); mesh->AddFace(11, 15, 19, 0); mesh->AddFace(11, 19, 23, 0); mesh->AddMaterial(); auto texture = graphics->CreateTexture2D(asd::ToAString(L"Data/Texture/Sample1.png").c_str()); mesh->SetColorTexture(0, texture.get()); return mesh; }
BOOL CSSolid::SplitFaceByVertices(CSSVertex *pVertex1, CSSVertex *pVertex2) { if(GetEdgeIndex(pVertex1->id, pVertex2->id) != -1) return FALSE; // already an edge there! // find the face, first - get a list of affected edges and find // two with a common face int iNumEdges1, iNumEdges2; SSHANDLE hFace = 0; CSSEdge *pEdges1[64], *pEdges2[64], **pTmp; pTmp = FindAffectedEdges(&pVertex1->id, 1, iNumEdges1); memcpy(pEdges1, pTmp, iNumEdges1 * sizeof(CSSEdge*)); pTmp = FindAffectedEdges(&pVertex2->id, 1, iNumEdges2); memcpy(pEdges2, pTmp, iNumEdges2 * sizeof(CSSEdge*)); for(int i = 0; i < iNumEdges1; i++) { SSHANDLE hFace0 = pEdges1[i]->Faces[0]; SSHANDLE hFace1 = pEdges1[i]->Faces[1]; for(int i2 = 0; i2 < iNumEdges2; i2++) { if(hFace0 == pEdges2[i2]->Faces[0] || hFace0 == pEdges2[i2]->Faces[1]) { hFace = hFace0; break; } else if(hFace1 == pEdges2[i2]->Faces[0] || hFace1 == pEdges2[i2]->Faces[1]) { hFace = hFace1; break; } } } // couldn't find a common face if(hFace == 0) return FALSE; CSSFace *pFace = (CSSFace*) GetHandleData(hFace); // create a new face CSSFace *pNewFace = AddFace(); memcpy(&pNewFace->texture, &pFace->texture, sizeof(TEXTURE)); // create a new edge between two vertices CSSEdge *pNewEdge = AddEdge(); pNewEdge->hvStart = pVertex1->id; pNewEdge->hvEnd = pVertex2->id; CalcEdgeCenter(pNewEdge); // assign face ids to the new edge AssignFace(pNewEdge, pFace->id); AssignFace(pNewEdge, pNewFace->id); // set up edges - start with newvertex1 SSHANDLE hNewEdges[64]; int nNewEdges; BOOL bFirst = TRUE; CSSFace *pStoreFace = pFace; SSHANDLE *phVertexList = CreatePointHandleList(*pFace); int nVertices = pFace->nEdges; int v1index, v2index; // find where the vertices are and // kill face references in edges first for(i = 0; i < nVertices; i++) { int iNextVertex = GetNext(i, 1, nVertices); int iEdgeIndex = GetEdgeIndex(phVertexList[i], phVertexList[iNextVertex]); CSSEdge *pEdge = &m_Edges[iEdgeIndex]; AssignFace(pEdge, pFace->id, TRUE); if(phVertexList[i] == pVertex1->id) v1index = i; else if(phVertexList[i] == pVertex2->id) v2index = i; } DoNextFace: nNewEdges = 0; for(i = v1index; ; i++) { if(i == nVertices) i = 0; if(i == v2index) break; int iNextVertex = GetNext(i, 1, nVertices); int iEdgeIndex = GetEdgeIndex(phVertexList[i], phVertexList[iNextVertex]); ASSERT(iEdgeIndex != -1); hNewEdges[nNewEdges++] = m_Edges[iEdgeIndex].id; AssignFace(&m_Edges[iEdgeIndex], pFace->id); } // now add the middle edge hNewEdges[nNewEdges++] = pNewEdge->id; // now set up in face pStoreFace->nEdges = nNewEdges; memcpy(pStoreFace->Edges, hNewEdges, sizeof(SSHANDLE) * nNewEdges); if(bFirst) { int tmp = v1index; v1index = v2index; v2index = tmp; pStoreFace = pNewFace; bFirst = FALSE; goto DoNextFace; } delete phVertexList; return(TRUE); }
// to read in a filed mesh // Currently ignores material info. int Mesh::readFile(std::string fileName) { int nVertis = 0; int nFaces = 0; int nFaceVerts = 0; int nVNormals = 0; int nFNormals = 0; int nFNormVerts = 0; int nTexCoors = 0; int nMaterials = 0; int nMaterialFacesAdded = 0; std::string line; std::string token; bool bInMesh = false; bool bInVertices = false; bool bInFaces = false; bool bFirstLine = false; bool bSecondLine = false; bool bInVNormals = false; bool bInFNormals = false; bool bInMaterials = false; bool bInMaterialList = false; bool bInTexCoors = false; size_t pos; Vector3 p3; int index[4]; // support triangles or quads only float vert[4]; // also used for RGBA std::ifstream myfile (fileName.c_str()); if (myfile.is_open()) { while ( myfile.good() ) { getline (myfile,line); //std::cout << line << std::endl; if ((pos = line.find("//")) != std::string::npos) { line = line.substr(0, pos); } if ((pos = line.find("#")) != std::string::npos) { line = line.substr(0, pos); } if (line.length() == 0) { continue; } else if ((pos = line.find("Mesh ")) != std::string::npos) { bInMesh = true; bInVertices = true; bFirstLine = true; } else if (bInVertices && bFirstLine) { bFirstLine = false; pos = line.find(";"); if (pos != std::string::npos) { line.erase(pos); nVertis = atoi(line.c_str()); } else { myfile.close(); return(1); } } else if (bInVertices) { int i = 0; while (i < 3) { if ((pos = line.find(";")) != std::string::npos) { token = line.substr(0, pos); line = line.substr(pos+1); vert[i] = atof(token.c_str()); i++; } else { myfile.close(); return(1); } } p3 = vert; AddVertex(p3); if (nVertis == numVerts) { bInVertices = false; bInFaces = true; bFirstLine = true; } } else if (bInFaces && bFirstLine) { bFirstLine = false; pos = line.find(";"); if (pos != std::string::npos) { line.erase(pos); nFaces = atoi(line.c_str()); } else { myfile.close(); return(1); } } else if (bInFaces) { int i = 0; if ((pos = line.find(";")) != std::string::npos) { token = line.substr(0, pos); line = line.substr(pos+1); nFaceVerts = atoi(token.c_str()); } else { myfile.close(); return(1); } while (i < nFaceVerts) { if ((pos = line.find(",")) != std::string::npos) { token = line.substr(0, pos); line = line.substr(pos+1); index[i] = atoi(token.c_str()); i++; } else if ((pos = line.find(";")) != std::string::npos) { token = line.substr(0, pos); line = line.substr(pos+1); index[i] = atoi(token.c_str()); i++; } else { myfile.close(); return(1); } } AddFace(nFaceVerts, index); if (nFaces == numFaces) { bInFaces = false; } } else if ((pos = line.find("MeshNormals")) != std::string::npos) { bInVNormals = true; bFirstLine = true; } else if (bInVNormals && bFirstLine) { bFirstLine = false; pos = line.find(";"); if (pos != std::string::npos) { line.erase(pos); nVNormals = atoi(line.c_str()); } else { myfile.close(); return(1); } } else if (bInVNormals) { int i = 0; while (i < 3) { if ((pos = line.find(";")) != std::string::npos) { token = line.substr(0, pos); line = line.substr(pos+1); vert[i] = atof(token.c_str()); i++; } else { myfile.close(); return(1); } } p3 = vert; AddNormal(p3); if (nVNormals == numNormals) { bInVNormals = false; bInFNormals = true; bFirstLine = true; } } else if (bInFNormals && bFirstLine) { bFirstLine = false; pos = line.find(";"); if (pos != std::string::npos) { line.erase(pos); //nFNormals = atoi(line.c_str()); } else { myfile.close(); return(1); } } else if (bInFNormals) { int i = 0; if ((pos = line.find(";")) != std::string::npos) { token = line.substr(0, pos); line = line.substr(pos+1); nFNormVerts = atoi(token.c_str()); } else { myfile.close(); return(1); } while (i < nFNormVerts) { if ((pos = line.find(",")) != std::string::npos) { token = line.substr(0, pos); line = line.substr(pos+1); index[i] = atoi(token.c_str()); i++; } else if ((pos = line.find(";")) != std::string::npos) { token = line.substr(0, pos); line = line.substr(pos+1); index[i] = atoi(token.c_str()); i++; } else { myfile.close(); return(1); } } AddNormal(nFNormals, index); nFNormals++; if (nFNormals == numFaces) { bInFNormals = false; } } else if ((pos = line.find("MaterialList ")) != std::string::npos) { bInMaterialList = true; bFirstLine = true; } else if (bInMaterialList && bFirstLine) { bFirstLine = false; bSecondLine = true; int numMat = atoi(line.c_str()); if (numMat == 0) { bInMaterialList = false; bSecondLine = false; } } else if (bInMaterialList && bSecondLine) { bFirstLine = false; bSecondLine = false; } else if (bInMaterialList) { vecFaces[nMaterialFacesAdded].materialIndex = atoi(line.c_str()); nMaterialFacesAdded++; if (nMaterialFacesAdded == nFaces) { bInMaterialList = false; } } else if ((pos = line.find("Material ")) != std::string::npos) { bInMaterials = true; bFirstLine = true; } else if (bInMaterials && bFirstLine) { bInMaterials = false; bFirstLine = false; int i = 0; while (i < 4) { if ((pos = line.find(";")) != std::string::npos) { token = line.substr(0, pos); line = line.substr(pos+1); vert[i] = atof(token.c_str()); i++; } else { myfile.close(); return(1); } } AddMaterial(vert); } else if ((pos = line.find("MeshTextureCoords")) != std::string::npos) { bInTexCoors = true; bFirstLine = true; } else if (bInTexCoors && bFirstLine) { bFirstLine = false; pos = line.find(";"); if (pos != std::string::npos) { line.erase(pos); nTexCoors = atoi(line.c_str()); } else { myfile.close(); return(1); } } else if (bInTexCoors) { int i = 0; while (i < 2) { if ((pos = line.find(";")) != std::string::npos) { token = line.substr(0, pos); line = line.substr(pos+1); vert[i] = atof(token.c_str()); i++; } else { myfile.close(); return(1); } } p3 = vert; AddTexCoor(p3); if (nTexCoors == numTexCoors) { bInTexCoors = false; bFirstLine = true; } } } myfile.close(); } else { std::cout << "Unable to open file" << std::endl; } return(0); }
void BuildChCylinderMesh(Mesh &mesh, int segs, int smooth, int llsegs, int capsegs, int csegs,int doPie, float radius1, float radius2, float height, float pie1, float pie2, int genUVs) { Point3 p; BOOL minush=height<0.0f; if (minush) height=-height; int ix,jx,ic = 1; int nf=0,nv=0, lsegs,VertexPerLevel; float delta,ang,hh=height*0.5f; float totalPie, startAng = 0.0f; if (radius2>radius1) radius2=radius1; if (radius2>hh) radius2=hh; if (doPie) doPie = 1; else doPie = 0; lsegs = llsegs-1 + 2*capsegs; // Make pie2 < pie1 and pie1-pie2 < TWOPI while (pie1 < pie2) pie1 += TWOPI; while (pie1 > pie2+TWOPI) pie1 -= TWOPI; if (pie1==pie2) totalPie = TWOPI; else totalPie = pie1-pie2; int nfaces,ntverts,levels=csegs*2+(llsegs-1); int capv=segs,sideedge=capsegs+csegs,*edgelstr,*edgelstl,totlevels,incap; // capv=vertex in one cap layer totlevels=levels+capsegs*2+2; incap=capsegs+1; int tvinslice=totlevels+totlevels-2; if (doPie) { delta = totalPie/(float)(segs); startAng = pie2; capv++; VertexPerLevel=segs+2; nfaces=2*segs*(levels+1)+(sideedge+llsegs)*4; ntverts=tvinslice+2*(segs+1); // 2 faces between every 2 vertices, with 2 ends, except in central cap) } else { delta = (float)2.0*PI/(float)segs; VertexPerLevel=segs; nfaces=2*segs*(levels+1); ntverts=2*(segs+1)+llsegs-1; } if (height<0) {delta = -delta;} edgelstl=new int[totlevels]; edgelstr=new int[totlevels]; int lastlevel=totlevels-1,dcapv=capv-1,dvertper=VertexPerLevel-1; edgelstr[0]=0;edgelstl[0]=0; edgelstr[1]=1; edgelstl[1]=capv; for (int i=2;i<=sideedge;i++) { edgelstr[i]=edgelstr[i-1]+capv; edgelstl[i]=edgelstr[i]+dcapv; } while (i<=totlevels-sideedge) { edgelstr[i]=edgelstr[i-1]+VertexPerLevel; edgelstl[i]=edgelstr[i]+dcapv; i++; } while (i<lastlevel) { edgelstr[i]=edgelstr[i-1]+capv; edgelstl[i]=edgelstr[i]+dcapv; i++; } edgelstl[lastlevel]=(edgelstr[lastlevel]=edgelstl[i-1]+1); int nverts=edgelstl[lastlevel]+1; nfaces+=2*segs*(2*capsegs-1); mesh.setNumVerts(nverts); mesh.setNumFaces(nfaces); mesh.setSmoothFlags(smooth != 0); if (genUVs) { ntverts+=nverts; mesh.setNumTVerts(ntverts); mesh.setNumTVFaces(nfaces); } else { mesh.setNumTVerts(0); mesh.setNumTVFaces(0); } mesh.setSmoothFlags((smooth != 0) | ((doPie != 0) << 1)); // bottom vertex mesh.setVert(nv, Point3(0.0f,0.0f,height)); mesh.setVert(nverts-1, Point3(0.0f,0.0f,0.0f)); float ru,cang,sang,rotz,botz,deltacsegs=PI/(2.0f*csegs),radius=radius1-radius2; int iy,msegs=segs,deltaend=nverts-capv-1; // Bottom cap vertices ang = startAng; if (!doPie) msegs--; for (jx = 0; jx<=msegs; jx++) { cang=(float)cos(ang); sang=(float)sin(ang); iy=0; for(ix=1; ix<=sideedge; ix++) { if (ix<=capsegs) { botz=0.0f; p.z = height; ru=radius*float(ix)/float(capsegs); } else { iy++; ru=radius+radius2*(float)sin(rotz=deltacsegs*float(iy)); if (jx==0) { p.z=(iy==csegs?height-radius2:height-radius2*(1.0f-(float)cos(rotz))); } else p.z=mesh.verts[edgelstr[ix]].z; botz=height-p.z; if ((doPie)&&((jx==0)&&(ix==sideedge))) { mesh.setVert(edgelstl[ix]+1,Point3(0.0f,0.0f,p.z)); mesh.setVert(edgelstl[lastlevel-ix]+1,Point3(0.0f,0.0f,botz)); } } p.x = cang*ru; p.y = sang*ru; mesh.setVert(edgelstr[ix]+jx, p); mesh.setVert(edgelstr[lastlevel-ix]+jx,Point3(p.x,p.y,botz)); } ang += delta; } //top layer done, now reflect sides down int sidevs,startv=edgelstr[sideedge],deltav; if (llsegs>1) { float sideheight=height-2.0f*radius2,topd=height-radius2,sincr=sideheight/llsegs; for (sidevs=0;sidevs<VertexPerLevel;sidevs++) { p=mesh.verts[startv]; deltav=VertexPerLevel; for (ic=1;ic<llsegs;ic++) { p.z =topd-sincr*ic; mesh.setVert(startv+deltav, p); deltav+=VertexPerLevel; } startv++; } } int lasttvl=0,lasttvr=0; if (genUVs) { int tvcount=0,nexttv; float udenom=2.0f*radius1; for (i=0;i<=sideedge;i++) { nexttv=edgelstr[i]; while (nexttv<=edgelstl[i]) { mesh.setTVert(tvcount++,(radius1+mesh.verts[nexttv].x)/udenom,(radius1+mesh.verts[nexttv].y)/udenom,0.0f); nexttv++; } } int iseg,hcount=0; float hlevel; for (i=sideedge;i<=lastlevel-sideedge;i++) { hlevel=1.0f-hcount++/(float)llsegs; for (iseg=0;iseg<=segs;iseg++) mesh.setTVert(tvcount++,(float)iseg/segs,hlevel,0.0f); } i--; while (i<=lastlevel) { nexttv=edgelstr[i]; while (nexttv<=edgelstl[i]) { mesh.setTVert(tvcount++,(radius1+mesh.verts[nexttv].x)/udenom,(radius1+mesh.verts[nexttv].y)/udenom,0.0f); nexttv++; } i++; } if (doPie) { lasttvl=lasttvr=tvcount; float u,v; mesh.setTVert(tvcount++,0.0f,1.0f,0.0f); for (i=sideedge;i<=sideedge+llsegs;i++) { mesh.setTVert(tvcount++,0.0f,mesh.verts[edgelstl[i]].z/height,0.0f); } mesh.setTVert(tvcount++,0.0f,0.0f,0.0f); for (i=1;i<lastlevel;i++) { u=(float)sqrt(mesh.verts[edgelstl[i]].x*mesh.verts[edgelstl[i]].x+mesh.verts[edgelstl[i]].y*mesh.verts[edgelstl[i]].y)/radius1; v=mesh.verts[edgelstl[i]].z/height; mesh.setTVert(tvcount++,u,v,0.0f); mesh.setTVert(tvcount++,u,v,0.0f); } } } int lvert=(doPie?segs+1:segs); int t0,t1,b0,b1,tvt0=0,tvt1=0,tvb0=1,tvb1=2,fc=0,smoothgr=(smooth?4:0),vseg=segs+1; int tvcount=0,lowerside=lastlevel-sideedge,onside=0; BOOL ok,wrap; // Now make faces --- for (int clevel=0;clevel<lastlevel-1;clevel++) { t1=(t0=edgelstr[clevel])+1; b1=(b0=edgelstr[clevel+1])+1; ok=!doPie; wrap=FALSE; if ((clevel>0)&&((doPie)||(onside==1))) {tvt0++;tvt1++;tvb0++,tvb1++;} if (clevel==1) {tvt0=1;tvt1=2;} if (clevel==sideedge) {tvt1+=lvert;tvt0+=lvert;tvb0+=vseg;tvb1+=vseg;onside++;} else if (clevel==lowerside) {tvt1+=vseg;tvt0+=vseg;tvb0+=lvert;tvb1+=lvert;onside++;} while ((b0<edgelstl[clevel+1])||ok) { if (b1==edgelstr[clevel+2]) { b1=edgelstr[clevel+1]; t1=edgelstr[clevel]; ok=FALSE;wrap=(onside!=1);} if (smooth) { if (csegs>1) smoothgr=4; else {if ((clevel<capsegs)||(clevel>=lastlevel-capsegs)) smoothgr=4; else if ((clevel<sideedge)||(clevel>=lowerside)) smoothgr=8; else smoothgr=16; } } if (genUVs) mesh.tvFace[fc].setTVerts(tvt0,tvb0,(wrap?tvb1-segs:tvb1)); AddFace(&mesh.faces[fc++],t0,b0,b1,0,smoothgr); if (clevel>0) { if (genUVs) { if (wrap) mesh.tvFace[fc].setTVerts(tvt0++,tvb1-segs,tvt1-segs); else mesh.tvFace[fc].setTVerts(tvt0++,tvb1,tvt1); tvt1++; } AddFace(&mesh.faces[fc++],t0,b1,t1,1,smoothgr); t0++;t1++; } b0++;b1++;tvb0++,tvb1++; } } smoothgr=(smooth?4:0); t1=(t0=edgelstr[lastlevel-1])+1;b0=edgelstr[lastlevel]; int lastpt=(doPie?lastlevel-1:lastlevel); if (doPie){tvt0++;tvt1++;tvb0++,tvb1++;} while (t0<edgelstl[lastpt]) { if ((!doPie)&&(t1==edgelstr[lastlevel])) { t1=edgelstr[lastlevel-1];tvt1-=segs;} if (genUVs) mesh.tvFace[fc].setTVerts(tvt0++,tvb0,tvt1++); AddFace(&mesh.faces[fc++],t0,b0,t1,1,smoothgr); t0++;t1++; } int chv=edgelstl[sideedge]+1,botcap=lastlevel-sideedge; int chb=edgelstl[botcap]+1,chm0,chm1,last=0,sg0=(smooth?2:0),sg1=(smooth?1:0); if (doPie) {int topctv=lasttvl+1,tvcount=topctv+llsegs+2; for (i=1;i<=lastlevel;i++) { if (i<=sideedge) { if (genUVs) { mesh.tvFace[fc].setTVerts(tvcount,topctv,lasttvl);lasttvl=tvcount++; mesh.tvFace[fc+1].setTVerts(lasttvr,topctv,tvcount);lasttvr=tvcount++; } AddFace(&mesh.faces[fc++],edgelstl[i],chv,edgelstl[last],(i==1?1:2),sg0); AddFace(&mesh.faces[fc++],edgelstr[last],chv,edgelstr[i],(i==1?3:2),sg1); } else if (i<=botcap) { if (genUVs) { topctv++; mesh.tvFace[fc].setTVerts(lasttvl,tvcount,topctv); mesh.tvFace[fc+1].setTVerts(lasttvl,topctv,topctv-1);lasttvl=tvcount++; mesh.tvFace[fc+2].setTVerts(topctv-1,topctv,tvcount); mesh.tvFace[fc+3].setTVerts(topctv-1,tvcount,lasttvr);lasttvr=tvcount++; } AddFace(&mesh.faces[fc++],edgelstl[last],edgelstl[i],chm1=(edgelstl[i]+1),0,sg0); AddFace(&mesh.faces[fc++],edgelstl[last],chm1,chm0=(edgelstl[last]+1),1,sg0); AddFace(&mesh.faces[fc++],chm0,chm1,edgelstr[i],0,sg1); AddFace(&mesh.faces[fc++],chm0,edgelstr[i],edgelstr[last],1,sg1); } else {if (genUVs) { if (i==lastlevel) tvcount=topctv+1; mesh.tvFace[fc].setTVerts(tvcount,topctv,lasttvl); if (i<lastlevel) lasttvl=tvcount++; mesh.tvFace[fc+1].setTVerts(lasttvr,topctv,tvcount);lasttvr=tvcount++; } AddFace(&mesh.faces[fc++],edgelstl[i],chb,edgelstl[last],(i==lastlevel?3:2),sg0); AddFace(&mesh.faces[fc++],edgelstr[last],chb,edgelstr[i],(i==lastlevel?1:2),sg1); } last++; } } if (minush) for (i=0;i<nverts;i++) { mesh.verts[i].z-=height; } if (edgelstr) delete []edgelstr; if (edgelstl) delete []edgelstl; assert(fc==mesh.numFaces); // assert(nv==mesh.numVerts); mesh.InvalidateTopologyCache(); }
void BuildCExtMesh(Mesh &mesh, int hsegs, int tsegs, int ssegs, int bsegs, int wsegs, float height, float toplen, float sidelen, float botlen, float topwidth, float sidewidth, float botwidth, int genUVs, BOOL create, BOOL usePhysUVs) { int nf=0; int nfaces,ntverts=0; BOOL minush=height<0.0f; if (minush) height=-height; BOOL minusx=(toplen<0.0f),minusy=(sidelen<0.0f); toplen=(float)fabs(toplen); botlen=(float)fabs(botlen); sidelen=(float)fabs(sidelen); // sides + top/bot int VertexPerLevel=2*(wsegs+tsegs+ssegs+bsegs); int topverts=(wsegs+1)*(1+tsegs+ssegs+bsegs); int nverts=2*topverts+(hsegs+1)*VertexPerLevel; nfaces=hsegs*4*(wsegs+bsegs+tsegs+ssegs)+4*wsegs*(tsegs+ssegs+bsegs); mesh.setNumVerts(nverts); mesh.setNumFaces(nfaces); if (genUVs) { ntverts=nverts+hsegs+1; mesh.setNumTVerts(ntverts); mesh.setNumTVFaces(nfaces); } else { mesh.setNumTVerts(0); mesh.setNumTVFaces(0); } Point3 p; p.x=p.y=p.z=0.0f; float minx=(botlen>toplen?0.0f:botlen-toplen),maxx=botlen; float xlen=(botlen>toplen?botlen:toplen); float xincr,xpos=0.0f,yincr; float uvdist=2.0f*(botlen+toplen+sidelen)-2.0f*sidewidth; float ystart,xstart; float xtv = 0.0f, ytv = 0.0f,ypos = 0.0f,dx=sidewidth/wsegs,tdy=topwidth/wsegs,bdy=botwidth/wsegs; int i,j,nv=0,fc=0,dlevel=bsegs+ssegs+tsegs+1,botv=nverts-topverts; int tlast,tendcount=ntverts-hsegs-1,tnv=0,bottv=tendcount-topverts; float mirrorFix = (usePhysUVs && (minusx^minusy)) ? -1.0f : 1.0f; tlast=tendcount; for (j=0;j<=wsegs;j++) { xstart=0.0f;xincr=(botlen-j*dx)/bsegs; yincr=botwidth/wsegs;ystart=j*yincr; for (i=0;i<=bsegs;i++) { mesh.setVert(nv,xpos=xstart+i*xincr,ystart,height); mesh.setVert(botv,xpos,ystart,0.0f); if (genUVs) { xtv=(xpos-minx)/(usePhysUVs?1.0:xlen); mesh.setTVert(tnv,mirrorFix*xtv,ytv=ystart/(usePhysUVs?1.0:sidelen),0.0f); mesh.setTVert(bottv,mirrorFix*xtv,(usePhysUVs?sidelen:1.0f)-ytv,0.0f); } nv++;botv++;bottv++;tnv++; } yincr=(sidelen-j*(tdy+bdy))/ssegs;xpos=mesh.verts[nv-1].x; for (i=1;i<=ssegs;i++) { mesh.setVert(nv,xpos,ypos=ystart+i*yincr,height); mesh.setVert(botv,xpos,ypos,0.0f); if (genUVs) { mesh.setTVert(tnv,mirrorFix*xtv,ytv=ypos/(usePhysUVs?1.0:sidelen),0.0f); mesh.setTVert(bottv,mirrorFix*xtv,(usePhysUVs?sidelen:1.0f)-ytv,0.0f); } nv++;botv++;bottv++;tnv++; } xstart=xpos;xincr=(toplen-j*dx)/tsegs; for (i=1;i<=tsegs;i++) { mesh.setVert(nv,xpos=xstart-i*xincr,ypos,height); mesh.setVert(botv,xpos,ypos,0.0f); if (genUVs) { xtv=(xpos-minx)/(usePhysUVs?1.0:xlen); mesh.setTVert(tnv,mirrorFix*xtv,ytv,0.0f); mesh.setTVert(bottv,mirrorFix*xtv,(usePhysUVs?xlen:1.0f)-ytv,0.0f); } nv++;botv++;bottv++;tnv++; } } xstart=0.0f;xpos=0.0f;ypos=0.0f; float uval=0.0f; int refnv=nv; xincr=botlen/bsegs; float heightScale = usePhysUVs ? height : 1.0f; float uScale = (usePhysUVs?1.0:uvdist); for (i=0;i<=bsegs;i++) { mesh.setVert(nv,xpos=xstart+i*xincr,0.0f,height); if (genUVs) { xtv=(uval=xpos)/uScale; mesh.setTVert(tnv,mirrorFix*xtv,heightScale,0.0f); } nv++;tnv++; } yincr=sidelen/ssegs;xpos=mesh.verts[nv-1].x; for (i=1;i<=ssegs;i++) { mesh.setVert(nv,xpos,ypos+=yincr,height); if (genUVs) { mesh.setTVert(tnv,mirrorFix*((uval+=yincr)/uScale),heightScale,0.0f); } nv++;tnv++; } xincr=toplen/tsegs; for (i=1;i<=tsegs;i++) { mesh.setVert(nv,xpos-=xincr,ypos,height); if (genUVs) mesh.setTVert(tnv,mirrorFix*((uval+=xincr)/uScale),heightScale,0.0f); nv++;;tnv++; } yincr=topwidth/wsegs; for (i=1;i<=wsegs;i++) { mesh.setVert(nv,xpos,ypos-=yincr,height); if (genUVs) mesh.setTVert(tnv,mirrorFix*((uval+=yincr)/uScale),heightScale,0.0f); nv++;;tnv++; } xincr=(toplen-sidewidth)/tsegs; for (i=1;i<=tsegs;i++) { mesh.setVert(nv,xpos+=xincr,ypos,height); if (genUVs) mesh.setTVert(tnv,mirrorFix*((uval+=xincr)/uScale),heightScale,0.0f); nv++;;tnv++; } yincr=(sidelen-topwidth-botwidth)/ssegs; for (i=1;i<=ssegs;i++) { mesh.setVert(nv,xpos,ypos-=yincr,height); if (genUVs) mesh.setTVert(tnv,mirrorFix*((uval+=yincr)/uScale),heightScale,0.0f); nv++;;tnv++; } xincr=(botlen-sidewidth)/bsegs; for (i=1;i<=bsegs;i++) { mesh.setVert(nv,xpos-=xincr,ypos,height); if (genUVs) mesh.setTVert(tnv,mirrorFix*((uval+=xincr)/uScale),heightScale,0.0f); nv++;;tnv++; } yincr=botwidth/wsegs; for (i=1;i<wsegs;i++) { mesh.setVert(nv,xpos,ypos-=yincr,height); if (genUVs) mesh.setTVert(tnv,mirrorFix*((uval+=yincr)/uScale),heightScale,0.0f); nv++;tnv++; } if (genUVs) mesh.setTVert(tendcount++,mirrorFix*(usePhysUVs?uvdist:1.0f),heightScale,0.0f); float zval,hincr=height/hsegs,zv; for (j=0;j<VertexPerLevel;j++) { zval=height; for (i=1;i<=hsegs;i++) { zval-=hincr; mesh.setVert(refnv+VertexPerLevel*i,mesh.verts[refnv].x,mesh.verts[refnv].y,zval); if (genUVs) { mesh.setTVert(refnv+VertexPerLevel*i,mesh.tVerts[refnv].x,zv=zval/(usePhysUVs?1.0:height),0.0f); if (j==VertexPerLevel-1) mesh.setTVert(tendcount++,mirrorFix*(usePhysUVs?uvdist:1.0f),zv,0.0f); } } refnv++; } int base=0,top=dlevel,alevel=dlevel-1; for (i=0;i<wsegs;i++) { for (j=0;j<alevel;j++) { if (genUVs) { mesh.tvFace[fc].setTVerts(top,base,base+1); mesh.tvFace[fc+1].setTVerts(top,base+1,top+1); } AddFace(&mesh.faces[fc++],top,base,base+1,0,1); AddFace(&mesh.faces[fc++],top,base+1,top+1,1,1); top++;base++; } top++;base++; } base=top+VertexPerLevel; tendcount=tlast; int b1,smgroup=2,s0=bsegs+1,s1=s0+ssegs,s2=s1+tsegs,s3=s2+wsegs; int s4=s3+tsegs,s5=s4+ssegs,s6=s5+bsegs; for (i=0;i<hsegs;i++) { for (j=1;j<=VertexPerLevel;j++) { if (genUVs) { b1=(j<VertexPerLevel?base+1:tendcount+1); mesh.tvFace[fc].setTVerts(top,base,b1); mesh.tvFace[fc+1].setTVerts(top,b1,(j<VertexPerLevel?top+1:tendcount++)); } b1=(j<VertexPerLevel?base+1:base-VertexPerLevel+1); smgroup=(j<s0?2:(j<s1?4:(j<s2?2:(j<s3?4:(j<s4?2:(j<s5?4:(j<s6?2:4))))))); AddFace(&mesh.faces[fc++],top,base,b1,0,smgroup); AddFace(&mesh.faces[fc++],top,b1,(j<VertexPerLevel?top+1:top-VertexPerLevel+1),1,smgroup); top++;base++; } } top=base;base=top+alevel; base=top+dlevel; // Just for Jack for (i=0;i<wsegs;i++) { for (j=0;j<alevel;j++) { if (genUVs) { mesh.tvFace[fc].setTVerts(top,base,base+1); mesh.tvFace[fc+1].setTVerts(top,base+1,top+1); } AddFace(&mesh.faces[fc++],top,base,base+1,0,1); AddFace(&mesh.faces[fc++],top,base+1,top+1,1,1); top++;base++; } top++;base++; } if (minusx || minusy || minush) { float centerx=(create?toplen:0),centery=(create?sidelen:0); for (i=0;i<nverts;i++) { if (minusx) mesh.verts[i].x=-mesh.verts[i].x+centerx; if (minusy) mesh.verts[i].y=-mesh.verts[i].y+centery; if (minush) mesh.verts[i].z-=height; } DWORD hold; int tedge; if (minusx!=minusy) for (i=0;i<nfaces;i++) { hold=mesh.faces[i].v[0];mesh.faces[i].v[0]=mesh.faces[i].v[2];mesh.faces[i].v[2]=hold; tedge=mesh.faces[i].getEdgeVis(0);mesh.faces[i].setEdgeVis(0,mesh.faces[i].getEdgeVis(1)); mesh.faces[i].setEdgeVis(1,tedge); if (genUVs) { hold=mesh.tvFace[i].t[0];mesh.tvFace[i].t[0]=mesh.tvFace[i].t[2];mesh.tvFace[i].t[2]=hold;} } } assert(fc==mesh.numFaces); // assert(nv==mesh.numVerts); */ mesh.InvalidateTopologyCache(); }
WShape::WShape(WShape& iBrother) { _Id = iBrother.GetId(); _Name = iBrother._Name; _FrsMaterials = iBrother._FrsMaterials; _meanEdgeSize = iBrother._meanEdgeSize; iBrother.bbox(_min, _max); vector<WVertex *>& vertexList = iBrother.getVertexList(); vector<WVertex *>::iterator v = vertexList.begin(), vend = vertexList.end(); for (; v != vend; ++v) { //WVertex *newVertex = new WVertex(*(*v)); WVertex *newVertex = (*v)->duplicate(); newVertex->setShape(this); AddVertex(newVertex); } vector<WEdge *>& edgeList = iBrother.getEdgeList(); vector<WEdge *>::iterator e = edgeList.begin(), eend = edgeList.end(); for (; e != eend; ++e) { //WEdge *newEdge = new WEdge(*(*e)); WEdge *newEdge = (*e)->duplicate(); AddEdge(newEdge); } vector<WFace *>& faceList = iBrother.GetFaceList(); vector<WFace *>::iterator f = faceList.begin(), fend = faceList.end(); for (; f != fend; ++f) { //WFace *newFace = new WFace(*(*f)); WFace *newFace = (*f)->duplicate(); AddFace(newFace); } // update all pointed addresses thanks to the newly created objects: vend = _VertexList.end(); for (v = _VertexList.begin(); v != vend; ++v) { const vector<WEdge *>& vedgeList = (*v)->GetEdges(); vector<WEdge *> newvedgelist; unsigned int i; for (i = 0; i < vedgeList.size(); i++) { WEdge *current = vedgeList[i]; edgedata *currentvedata = (edgedata *)current->userdata; newvedgelist.push_back(currentvedata->_copy); } (*v)->setEdges(newvedgelist); } eend = _EdgeList.end(); for (e = _EdgeList.begin(); e != eend; ++e) { // update aOedge: WOEdge *aoEdge = (*e)->GetaOEdge(); aoEdge->setaVertex(((vertexdata *)(aoEdge->GetaVertex()->userdata))->_copy); aoEdge->setbVertex(((vertexdata *)(aoEdge->GetbVertex()->userdata))->_copy); if (aoEdge->GetaFace()) aoEdge->setaFace(((facedata *)(aoEdge->GetaFace()->userdata))->_copy); aoEdge->setbFace(((facedata *)(aoEdge->GetbFace()->userdata))->_copy); aoEdge->setOwner(((edgedata *)(aoEdge->GetOwner()->userdata))->_copy); // update bOedge: WOEdge *boEdge = (*e)->GetbOEdge(); if (boEdge) { boEdge->setaVertex(((vertexdata *)(boEdge->GetaVertex()->userdata))->_copy); boEdge->setbVertex(((vertexdata *)(boEdge->GetbVertex()->userdata))->_copy); if (boEdge->GetaFace()) boEdge->setaFace(((facedata *)(boEdge->GetaFace()->userdata))->_copy); boEdge->setbFace(((facedata *)(boEdge->GetbFace()->userdata))->_copy); boEdge->setOwner(((edgedata *)(boEdge->GetOwner()->userdata))->_copy); } } fend = _FaceList.end(); for (f = _FaceList.begin(); f != fend; ++f) { unsigned int i; const vector<WOEdge *>& oedgeList = (*f)->getEdgeList(); vector<WOEdge *> newoedgelist; unsigned int n = oedgeList.size(); for (i = 0; i < n; i++) { WOEdge *current = oedgeList[i]; oedgedata *currentoedata = (oedgedata *)current->userdata; newoedgelist.push_back(currentoedata->_copy); //oedgeList[i] = currentoedata->_copy; //oedgeList[i] = ((oedgedata *)(oedgeList[i]->userdata))->_copy; } (*f)->setEdgeList(newoedgelist); } // Free all memory (arghh!) // Vertex vend = iBrother.getVertexList().end(); for (v = iBrother.getVertexList().begin(); v != vend; ++v) { delete (vertexdata *)((*v)->userdata); (*v)->userdata = NULL; } // Edges and OEdges: eend = iBrother.getEdgeList().end(); for (e = iBrother.getEdgeList().begin(); e != eend; ++e) { delete (edgedata *)((*e)->userdata); (*e)->userdata = NULL; // OEdge a: delete (oedgedata *)((*e)->GetaOEdge()->userdata); (*e)->GetaOEdge()->userdata = NULL; // OEdge b: WOEdge *oedgeb = (*e)->GetbOEdge(); if (oedgeb) { delete (oedgedata *)(oedgeb->userdata); oedgeb->userdata = NULL; } } // Faces fend = iBrother.GetFaceList().end(); for (f = iBrother.GetFaceList().begin(); f != fend; ++f) { delete (facedata *)((*f)->userdata); (*f)->userdata = NULL; } }
void OgreNewtonMesh::ParseEntity (MeshPtr mesh, const Matrix4& matrix) { //find number of sub-meshes unsigned short sub = mesh->getNumSubMeshes(); for (unsigned short cs = 0; cs < sub; cs++) { SubMesh* const sub_mesh = mesh->getSubMesh(cs); //vertex data! VertexData* v_data; if (sub_mesh->useSharedVertices) { v_data = mesh->sharedVertexData; } else { v_data = sub_mesh->vertexData; } //let's find more information about the Vertices... VertexDeclaration* const v_decl = v_data->vertexDeclaration; const VertexElement* const vertexElem = v_decl->findElementBySemantic(VES_POSITION); HardwareVertexBufferSharedPtr vertexPtr = v_data->vertexBufferBinding->getBuffer(vertexElem->getSource()); dNewtonScopeBuffer<Vector3> points(vertexPtr->getNumVertices()); { int size = vertexPtr->getVertexSize(); int offset = vertexElem->getOffset() / sizeof (float); unsigned char* const ptr = static_cast<unsigned char*> (vertexPtr->lock(HardwareBuffer::HBL_READ_ONLY)); for (int i = 0; i < points.GetElementsCount(); i ++) { float* data; vertexElem->baseVertexPointerToElement(ptr + i * size, &data); points[i] = matrix.transformAffine (Vector3 (data[offset + 0], data[offset + 1], data[offset + 2])); } vertexPtr->unlock(); } dNewtonScopeBuffer<Vector3> normals; const VertexElement* const normalElem = v_decl->findElementBySemantic(VES_NORMAL); if (normalElem) { HardwareVertexBufferSharedPtr normalPtr = v_data->vertexBufferBinding->getBuffer(normalElem->getSource()); normals.Init (normalPtr->getNumVertices()); int size = normalPtr->getVertexSize(); int offset = vertexElem->getOffset() / sizeof (float); unsigned char* const ptr = static_cast<unsigned char*> (normalPtr->lock(HardwareBuffer::HBL_READ_ONLY)); for (int i = 0; i < normals.GetElementsCount(); i ++) { float* data; vertexElem->baseVertexPointerToElement(ptr + i * size, &data); normals[i] = matrix * Vector3 (data[offset + 0], data[offset + 1], data[offset + 2]); normals[i] = normals[i].normalise(); } normalPtr->unlock(); } dNewtonScopeBuffer<Vector3> uvs; const VertexElement* const uvElem = v_decl->findElementBySemantic(VES_TEXTURE_COORDINATES); if (uvElem) { HardwareVertexBufferSharedPtr uvPtr = v_data->vertexBufferBinding->getBuffer(uvElem->getSource()); uvs.Init (uvPtr->getNumVertices()); int size = uvPtr->getVertexSize(); int offset = vertexElem->getOffset() / sizeof (float); unsigned char* const ptr = static_cast<unsigned char*> (uvPtr->lock(HardwareBuffer::HBL_READ_ONLY)); for (int i = 0; i < uvs.GetElementsCount(); i ++) { float* data; uvElem->baseVertexPointerToElement(ptr + i * size, &data); uvs[i] = Vector3 (data[offset + 0], data[offset + 1], 0.0f); } uvPtr->unlock(); } //now find more about the index!! IndexData* const i_data = sub_mesh->indexData; size_t index_count = i_data->indexCount; size_t poly_count = index_count / 3; // get pointer! HardwareIndexBufferSharedPtr i_sptr = i_data->indexBuffer; // 16 or 32 bit indices? bool uses32bit = (i_sptr->getType() == HardwareIndexBuffer::IT_32BIT); unsigned long* i_Longptr = NULL; unsigned short* i_Shortptr = NULL; if (uses32bit) { i_Longptr = static_cast<unsigned long*> (i_sptr->lock(HardwareBuffer::HBL_READ_ONLY)); } else { i_Shortptr = static_cast<unsigned short*> (i_sptr->lock(HardwareBuffer::HBL_READ_ONLY)); } //now loop through the indices, getting polygon info! int i_offset = 0; Real poly_verts[3][12]; memset (poly_verts, 0, sizeof (poly_verts)); for (size_t i = 0; i < poly_count; i++) { for (int j = 0; j < 3; j++) { // index to first vertex! int idx = uses32bit ? i_Longptr[i_offset + j] : i_Shortptr[i_offset + j]; poly_verts[j][0] = points[idx].x; poly_verts[j][1] = points[idx].y; poly_verts[j][2] = points[idx].z; poly_verts[j][3] = 0.0f; if (normals.GetElementsCount()) { poly_verts[j][4] = normals[idx].x; poly_verts[j][5] = normals[idx].y; poly_verts[j][6] = normals[idx].z; } if (uvs.GetElementsCount()) { poly_verts[j][7] = uvs[idx].x; poly_verts[j][8] = uvs[idx].y; } } AddFace(3, &poly_verts[0][0], 12 * sizeof (Real), cs); i_offset += 3; } i_sptr->unlock(); } }
WFace *WShape::MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial, WFace *face) { int id = _FaceList.size(); face->setFrsMaterialIndex(iMaterial); // Check whether we have a degenerated face: // LET'S HACK IT FOR THE TRIANGLE CASE: if (3 == iVertexList.size()) { if ((iVertexList[0] == iVertexList[1]) || (iVertexList[0] == iVertexList[2]) || (iVertexList[2] == iVertexList[1])) { cerr << "Warning: degenerated triangle detected, correcting" << endl; return NULL; } } vector<WVertex *>::iterator it; // compute the face normal (v1v2 ^ v1v3) WVertex *v1, *v2, *v3; it = iVertexList.begin(); v1 = *it; it++; v2 = *it; it++; v3 = *it; Vec3r vector1(v2->GetVertex() - v1->GetVertex()); Vec3r vector2(v3->GetVertex() - v1->GetVertex()); Vec3r normal(vector1 ^ vector2); normal.normalize(); face->setNormal(normal); vector<bool>::iterator mit = iFaceEdgeMarksList.begin(); face->setMark(*mit); mit++; // vertex pointers used to build each edge vector<WVertex *>::iterator va, vb; va = iVertexList.begin(); vb = va; for (; va != iVertexList.end(); va = vb) { ++vb; // Adds va to the vertex list: //face->AddVertex(*va); WOEdge *oedge; if (*va == iVertexList.back()) oedge = face->MakeEdge(*va, iVertexList.front()); //for the last (closing) edge else oedge = face->MakeEdge(*va, *vb); if (!oedge) return NULL; WEdge *edge = oedge->GetOwner(); if (1 == edge->GetNumberOfOEdges()) { // means that we just created a new edge and that we must add it to the shape's edges list edge->setId(_EdgeList.size()); AddEdge(edge); // compute the mean edge value: _meanEdgeSize += edge->GetaOEdge()->GetVec().norm(); } edge->setMark(*mit); ++mit; } // Add the face to the shape's faces list: face->setId(id); AddFace(face); return face; }
void ChBoxObject::BuildMesh(TimeValue t) { int smooth,dsegs,vertices; int WLines,HLines,DLines,CLines,VertexPerSlice; int VertexPerFace,FacesPerSlice,chamferend; float usedw,usedd,usedh,cradius,zdelta,CurRadius; Point3 va,vb,p; float depth, width, height; int genUVs = 1,sqvertex,CircleLayers; BOOL bias = 0,minusd; // Start the validity interval at forever and widdle it down. ivalid = FOREVER; pblock->GetValue(PB_LENGTH,t,height,ivalid); pblock->GetValue(PB_WIDTH,t,width,ivalid); pblock->GetValue(PB_HEIGHT,t,depth,ivalid); minusd=depth<0.0f; depth=(float)fabs(depth); pblock->GetValue(PB_RADIUS,t,cradius,ivalid); pblock->GetValue(PB_LSEGS,t,hsegs,ivalid); pblock->GetValue(PB_WSEGS,t,wsegs,ivalid); pblock->GetValue(PB_HSEGS,t,dsegs,ivalid); pblock->GetValue(PB_CSEGS,t,csegs,ivalid); pblock->GetValue(PB_GENUVS,t,genUVs,ivalid); pblock->GetValue(PB_SMOOTH,t,smooth,ivalid); LimitValue(csegs, MIN_SEGMENTS, MAX_SEGMENTS); LimitValue(dsegs, MIN_SEGMENTS, MAX_SEGMENTS); LimitValue(wsegs, MIN_SEGMENTS, MAX_SEGMENTS); LimitValue(hsegs, MIN_SEGMENTS, MAX_SEGMENTS); smooth=(smooth>0?1:0); mesh.setSmoothFlags(smooth); float twocrad,usedm,mindim=(height>width?(width>depth?depth:width):(height>depth?depth:height)); usedm=mindim-2*cradius; if (usedm<0.01f) cradius=(mindim-0.01f)/2.0f; twocrad=2.0f*cradius; usedh=height-twocrad; usedw=width-twocrad; usedd=depth-twocrad; float cangincr=PI/(2.0f*csegs),cudelta,udist; CircleLayers=csegs; cudelta=cradius*(float)sqrt(2.0f*(1.0f-(float)cos(cangincr))); udist=4.0f*csegs*cudelta+2.0f*width+2.0f*height-4.0f*cradius; chamferinfo[0].surface=1;chamferinfo[0].deltavert=1; chamferinfo[1].surface=2;chamferinfo[1].deltavert=1; chamferinfo[2].surface=1;chamferinfo[2].deltavert=-1; chamferinfo[3].surface=2;chamferinfo[3].deltavert=-1; WLines=wsegs-1; HLines=hsegs-1; DLines=dsegs-1; CLines=csegs+1; VertexPerSlice=2*(WLines+HLines)+4*CLines; /* WLines*HLines on middle, 2*Clines*(WLines+HLines) on sides, 4*CLines*csegs+4 for circles */ VertexPerFace=WLines*HLines+2*CLines*(WLines+HLines+2*csegs)+4; vertices=VertexPerFace*2+VertexPerSlice*DLines; sqvertex=(wsegs+1)*(hsegs+1); /* 4 vertices, 2 faces/cseg + 2 each hseg & wseg sides, each seg w/ 2 faces*/ SidesPerSlice=2*(2*csegs+hsegs+wsegs); FacesPerSlice=SidesPerSlice*2; /* this one only has 1 face/ cseg */ topchamferfaces=4*(csegs+hsegs+wsegs); /*top chamfer + top face(2 faces/seg)(*2 for bottom) plus any depth faces*/ maxfaces=2*(topchamferfaces+2*hsegs*wsegs)+(2*(CircleLayers-1)+dsegs)*FacesPerSlice; chamferstart=2*hsegs*wsegs; chamferend=chamferstart+topchamferfaces+(CircleLayers-1)*FacesPerSlice; chamferinfo[0].deltavert +=wsegs; chamferinfo[2].deltavert -=wsegs; int bottomvertex,vertexnum,tverts; int twomapped,endvert=vertices+(twomapped=2*VertexPerSlice); float xmax,ymax; mesh.setNumVerts(vertices); mesh.setNumFaces(maxfaces); tverts=endvert+DLines+2; if (genUVs) { mesh.setNumTVerts(tverts); mesh.setNumTVFaces(maxfaces); } else { mesh.setNumTVerts(0); mesh.setNumTVFaces(0); } zdelta=depth/2; wsegcount=0;vertexnum=0; bottomvertex=vertices-1; CornerPt.z=zdelta; CornerPt.x=(xmax=width/2)-cradius; CornerPt.y=(ymax=height/2)-cradius; NewPt.x=Toppt.x=-CornerPt.x; NewPt.y=Toppt.y=CornerPt.y; NewPt.z=Toppt.z=zdelta; /* Do top and bottom faces */ hincr=usedh/hsegs; //yincr wincr=usedw/wsegs; //xincr BOOL usePhysUVs = GetUsePhysicalScaleUVs(); int segcount,topvertex,tvcounter=0,tvbottom=endvert-1; float udiv=usePhysUVs ? 1.0f : 2.0f*xmax,vdiv=usePhysUVs ? 1.0f :2.0f*ymax, u = 0.0f, v = 0.0f; for (hseg=0;hseg<=hsegs;hseg++) { if (hseg>0) {NewPt.y=(hseg==hsegs?-CornerPt.y:Toppt.y-hseg*hincr); NewPt.x=Toppt.x; } for (segcount=0;segcount<=wsegs;segcount++) { /* make top point */ NewPt.z=Toppt.z; NewPt.x=(segcount==wsegs?CornerPt.x:Toppt.x+segcount*wincr); if (genUVs) mesh.setTVert(vertexnum,u=(xmax+NewPt.x)/udiv,v=(ymax+NewPt.y)/vdiv,0.0f); mesh.setVert(vertexnum++,NewPt); /* make bottom pt */ NewPt.z=-zdelta; if (genUVs) mesh.setTVert(tvbottom--,u,(usePhysUVs ? 2.0f*ymax : 1.0f)-v,0.0f); mesh.setVert(bottomvertex--,NewPt); } } /* start on the chamfer */ int layer,vert; layer=0; hseg=0; tvcounter=vertexnum; bottomvertex-=(VertexPerSlice-1); topvertex=vertexnum; BOOL done = FALSE,atedge = FALSE; float dincr=usedd/dsegs,cincr=2.0f*CircleLayers,RotationAngle; float dx,dy; int cornervert[4],PtRotation; for (layer=1;layer<=CircleLayers;layer++) /* add chamfer layer */ { if (layer==CircleLayers) {zdelta=cradius;CurRadius=cradius;} else { RotationAngle=(PI*layer)/cincr; zdelta=cradius-(cradius*(float)cos(RotationAngle)); CurRadius=cradius*(float)sin(RotationAngle); } zdelta=CornerPt.z-zdelta; atedge=(layer==CircleLayers); int vfromedge=0,oldside=0,vfromstart=0; sidenum=0; float u1 = 0.0f, v1 = 0.0f; BOOL atstart=TRUE; while (vertexnum<topvertex+csegs) /* add vertex loop */ { PtRotation=hseg=wsegcount=0;done=FALSE; RotationAngle=(vertexnum-topvertex)*cangincr; curvertex=vert=vertexnum; NewPt.x=Toppt.x-(dx=CurRadius*(float)sin(RotationAngle)); NewPt.y=Toppt.y+(dy=CurRadius*(float)cos(RotationAngle)); NewPt.z=zdelta; while (!done) { mesh.setVert(vert,NewPt); if (genUVs) mesh.setTVert(vert,u1=(xmax+NewPt.x)/udiv,v1=(ymax+NewPt.y)/vdiv,0.0f); /* reflected vertex to second face */ vert=bottomvertex+curvertex-topvertex; NewPt.z=-zdelta; mesh.setVert(vert,NewPt); if (genUVs) mesh.setTVert(vert+twomapped,u1,(usePhysUVs ? 2.0f*ymax : 1.0f)-v1,0.0f); if ((atedge)&&(DLines>0)) /* add non-corner points */ for (segcount=1;segcount<=DLines;segcount++) { NewPt.z=zdelta-segcount*dincr; mesh.setVert(vert=curvertex+VertexPerSlice*segcount,NewPt); } /* Rotate Pt */ done=PtRotation>5; if (done == FALSE) { if (vertexnum==topvertex) { FillinSquare(&PtRotation,cornervert,CurRadius); if (curvertex==topvertex+VertexPerSlice-1) (PtRotation)=6; } else CalculateNewPt(dx,dy,&PtRotation,cornervert,vertexnum-topvertex); vert=curvertex; NewPt.z=zdelta; } } vertexnum++; /* done rotation */ } vertexnum=topvertex +=VertexPerSlice; bottomvertex -=VertexPerSlice; } float dfromedge=0.0f; int tvnum,j,i,chsegs=csegs+1,cwsegs=wsegs; if (genUVs) { u=0.0f; dfromedge=-cudelta; tvnum=vertexnum; vertexnum=topvertex-VertexPerSlice; float uDenom = usePhysUVs ? 1.0f : udist; float vScale = usePhysUVs ? usedd : 1.0f; float maxU = 0.0f; for (j=0;j<2;j++) { int gverts; for (gverts=0;gverts<chsegs;gverts++) { dfromedge+=cudelta; mesh.setTVert(tvnum,u=dfromedge/uDenom,vScale,0.0f); if (u > maxU) maxU = u; for (i=1;i<=dsegs;i++) mesh.setTVert(tvnum+VertexPerSlice*i,u,vScale*(1.0f-(float)i/dsegs),0.0f); vertexnum++; tvnum++; } chsegs=csegs; for (gverts=0;gverts<hsegs;gverts++) { dfromedge+=(float)fabs(mesh.verts[vertexnum].y-mesh.verts[vertexnum-1].y); mesh.setTVert(tvnum,u=dfromedge/uDenom,vScale,0.0f); if (u > maxU) maxU = u; for (i=1;i<=dsegs;i++) mesh.setTVert(tvnum+VertexPerSlice*i,u,vScale*(1.0f-(float)i/dsegs),0.0f); vertexnum++; tvnum++; } for (gverts=0;gverts<csegs;gverts++) { dfromedge+=cudelta; mesh.setTVert(tvnum,u=dfromedge/uDenom,vScale,0.0f); if (u > maxU) maxU = u; for (i=1;i<=dsegs;i++) mesh.setTVert(tvnum+VertexPerSlice*i,u,vScale*(1.0f-(float)i/dsegs),0.0f); vertexnum++; tvnum++; } if (j==1) cwsegs--; for (gverts=0;gverts<cwsegs;gverts++) { dfromedge+=(float)fabs(mesh.verts[vertexnum].x-mesh.verts[vertexnum-1].x); mesh.setTVert(tvnum,u=dfromedge/uDenom,vScale,0.0f); if (u > maxU) maxU = u; for (i=1;i<=dsegs;i++) mesh.setTVert(tvnum+VertexPerSlice*i,u,vScale*(1.0f-(float)i/dsegs),0.0f); vertexnum++; tvnum++; } } int lastvert=endvert; float uScale = usePhysUVs ? udist-4*cradius : 1.0f; mesh.setTVert(lastvert++,uScale, vScale,0.0f); for (j=1;j<dsegs;j++) mesh.setTVert(lastvert++,uScale, vScale*(1.0f-(float)j/dsegs),0.0f); mesh.setTVert(lastvert,uScale, 0.0f,0.0f); } /* all vertices calculated - Now specify faces*/ int tvdelta=0; sidenum=topnum=face=fcount=scount=circleseg=0; curvertex=wsegs+1; firstface=layer=1; // smooth=(csegs>1?1:0); tstartpt=cstartpt=endpt=0; boxpos=topsquare;cstartpt=chamferinfo[0].deltavert; AddFace(&mesh.faces[face],smooth,tvdelta,&mesh.tvFace[face],genUVs); while (face<chamferstart) /* Do Square Layer */ { firstface=!firstface; AddFace(&mesh.faces[face],smooth,tvdelta,&mesh.tvFace[face],genUVs); } boxpos=messyedge;firstface=1; topnum=tstartpt=0; cstartpt=curvertex=topnum+sqvertex;circleseg=1; endpt=hsegs*(wsegs+1); /* Do Chamfer */ while (face<chamferend) { AddFace(&mesh.faces[face],smooth,tvdelta,&mesh.tvFace[face],genUVs); if (circleseg==0) firstface=!firstface; } fcount=scount=0; boxpos=middle;tvdelta+=VertexPerSlice; /*Do box sides */ int tpt,lastv=tverts-1; BOOL inside=TRUE; while (face<maxfaces-chamferstart-topchamferfaces) { tpt=face; AddFace(&mesh.faces[face],smooth,tvdelta,&mesh.tvFace[face],genUVs); if (genUVs && inside) { if ((firstface)&&(mesh.tvFace[tpt].t[2]<mesh.tvFace[tpt].t[1])) mesh.tvFace[tpt].t[2]=endvert+1; else if (mesh.tvFace[tpt].t[2]<mesh.tvFace[tpt].t[0]) { mesh.tvFace[tpt].t[1]=endvert+1; mesh.tvFace[tpt].t[2]=endvert; endvert++; inside=endvert<lastv; if (inside==FALSE) tvdelta+=VertexPerSlice; } } firstface=!firstface; } /* back in chamfer */ circleseg=2;firstface=0; boxpos=bottomedge; sidenum=0;tstartpt=topnum; cstartpt=curvertex=vertices-1; endpt=cstartpt-hsegs*chamferinfo[0].deltavert; while (face<maxfaces-chamferstart) /* Do Second Chamfer */ { AddFace(&mesh.faces[face],smooth,tvdelta,&mesh.tvFace[face],genUVs); if (circleseg==0) firstface=!firstface; } boxpos=bottomsquare; curvertex=topnum; topnum=curvertex+chamferinfo[0].deltavert; firstface=1;fcount=0; while (face<maxfaces) { AddFace(&mesh.faces[face],smooth,tvdelta,&mesh.tvFace[face],genUVs); firstface=!firstface; } float deltaz=(minusd?-depth/2.0f:depth/2.0f); for (i=0;i<vertices;i++) { mesh.verts[i].z+=deltaz; } mesh.InvalidateTopologyCache(); }
void BuildPrismMesh(Mesh &mesh, int s1segs, int s2segs, int s3segs, int llsegs, float s1len, float s2len, float s3len, float height, int genUVs) { BOOL minush=(height<0.0f); if (minush) height=-height; int nf=0,totalsegs=s1segs+s2segs+s3segs; float s13len=s1len*s3len; if ((s1len<=0.0f)||(s2len<=0.0f)||(s3len<=0.0f)) { mesh.setNumVerts(0); mesh.setNumFaces(0); mesh.setNumTVerts(0); mesh.setNumTVFaces(0); } else { float acvalue=(s2len*s2len-s1len*s1len-s3len*s3len)/(-2.0f*s13len); acvalue=(acvalue<-1.0f?-1.0f:(acvalue>1.0f?acvalue=1.0f:acvalue)); float theta=(float)acos(acvalue); int nfaces = 0; int ntverts = 0; nfaces=2*totalsegs*(llsegs+1); int nverts=totalsegs*(llsegs+1)+2; mesh.setNumVerts(nverts); mesh.setNumFaces(nfaces); if (genUVs) { ntverts=nverts+2*totalsegs+llsegs+1; mesh.setNumTVerts(ntverts); mesh.setNumTVFaces(nfaces); } else { ntverts = 0; mesh.setNumTVerts(0); mesh.setNumTVFaces(0); } Point3 Pt0=Point3(0.0f,0.0f,height),Pt1=Point3(s1len,0.0f,height); Point3 Pt2=Point3(s3len*(float)cos(theta),s3len*(float)sin(theta),height); Point3 CenterPt=(Pt0+Pt1+Pt2)/3.0f,Mins; float maxx; if (s1len<Pt2.x) {Mins.x=s1len;maxx=Pt2.x;} else {Mins.x=Pt2.x;maxx=s1len;} if (maxx<0.0f) maxx=0.0f; if (Mins.x>0.0f) Mins.x=0.0f; Mins.y=0.0f; float xdist=maxx-Mins.x,ydist=Pt2.y; if (xdist==0.0f) xdist=0.001f;if (ydist==0.0f) ydist=0.001f; mesh.setVert(0,CenterPt); mesh.setVert(nverts-1, Point3(CenterPt.x,CenterPt.y,0.0f)); mesh.setVert(1,Pt0); int botstart=ntverts-totalsegs-1,tnv=totalsegs+1; float u=0.0f,yval=Pt2.y,bu,tu,tb; if (genUVs) { mesh.setTVert(0,tu=(CenterPt.x-Mins.x)/xdist,tb=(CenterPt.y-Mins.y)/ydist,0.0f); mesh.setTVert(1,bu=(-Mins.x/xdist),0.0f,0.0f); mesh.setTVert(tnv++,0.0f,1.0f,0.0f); mesh.setTVert(botstart++,1.0f-bu,1.0f,0.0f); mesh.setTVert(ntverts-1,1.0f-tu,1.0f-tb,0.0f); } int i,nv=2; float sincr=s1len/s1segs,tdist=s1len+s2len+s3len,udiv=sincr/tdist,pos; if (tdist==0.0f) tdist=0.0001f; for (i=1;i<s1segs;i++) { mesh.setVert(nv,Point3(pos=sincr*i,0.0f,height)); if (genUVs) { mesh.setTVert(nv,bu=(pos-Mins.x)/xdist,0.0f,0.0f); mesh.setTVert(tnv++,u+=udiv,1.0f,0.0f); mesh.setTVert(botstart++,1.0f-bu,1.0f,0.0f); } nv++; } mesh.setVert(nv,Pt1); if (genUVs) { mesh.setTVert(nv,bu=(Pt1.x-Mins.x)/xdist,0.0f,0.0f); mesh.setTVert(tnv++,u+=udiv,1.0f,0.0f); mesh.setTVert(botstart++,1.0f-bu,1.0f,0.0f); } Point3 slope=(Pt2-Pt1)/(float)s2segs; float ypos,bv; nv++;udiv=(s2len/s2segs)/tdist; for (i=1;i<s2segs;i++) { mesh.setVert(nv,Point3(pos=(Pt1.x+slope.x*i),ypos=(Pt1.y+slope.y*i),height)); if (genUVs) { mesh.setTVert(nv,bu=(pos-Mins.x)/xdist,bv=(ypos-Mins.y)/ydist,0.0f); mesh.setTVert(tnv++,u+=udiv,1.0f,0.0f); mesh.setTVert(botstart++,1.0f-bu,1.0f-bv,0.0f); } nv++; } mesh.setVert(nv,Pt2); if (genUVs) { mesh.setTVert(nv,bu=(Pt2.x-Mins.x)/xdist,1.0f,0.0f); mesh.setTVert(tnv++,u+=udiv,1.0f,0.0f); mesh.setTVert(botstart++,1.0f-bu,0.0f,0.0f); } nv++; slope=(Pt0-Pt2)/(float)s3segs;udiv=(s2len/s2segs)/tdist; for (i=1;i<s3segs;i++) { mesh.setVert(nv,Point3(pos=(Pt2.x+slope.x*i),ypos=(Pt2.y+slope.y*i),height)); if (genUVs) { mesh.setTVert(nv,bu=(pos-Mins.x)/xdist,bv=(ypos-Mins.y)/ydist,0.0f); mesh.setTVert(tnv++,u+=udiv,1.0f,0.0f); mesh.setTVert(botstart++,1.0f-bu,1.0f-bv,0.0f); } nv++; } if (genUVs) mesh.setTVert(tnv++,1.0f,1.0f,0.0f); //top layer done, now reflect sides down int sidevs,startv=1,deltav,ic; startv=1; sincr=height/llsegs; Point3 p; for (sidevs=0;sidevs<totalsegs;sidevs++) { p=mesh.verts[startv]; deltav=totalsegs; for (ic=1;ic<=llsegs;ic++) { p.z =height-sincr*ic; mesh.setVert(startv+deltav, p); deltav+=totalsegs; } startv++; } if (genUVs) { startv=totalsegs+1; int tvseg=totalsegs+1; for (sidevs=0;sidevs<=totalsegs;sidevs++) { p=mesh.tVerts[startv]; deltav=tvseg; for (ic=1;ic<=llsegs;ic++) { p.y =1.0f-ic/(float)llsegs; mesh.setTVert(startv+deltav,p); deltav+=tvseg; } startv++; } } int fc=0,sidesm=2; int last=totalsegs-1; // Now make faces --- int j,b0=1,b1=2,tb0,tb1,tt0,tt1,t0,t1,ecount=0,s2end=s1segs+s2segs; for (i=0;i<totalsegs;i++) { if (genUVs) mesh.tvFace[fc].setTVerts(0,b0,(i<last?b1:1)); AddFace(&mesh.faces[fc++],0,b0++,(i<last?b1++:1),0,1); } tt1=(tt0=i+1)+1;t0=1;t1=2;b1=(b0=t0+totalsegs)+1; tb1=(tb0=tt1+totalsegs)+1; for (i=1;i<=llsegs;i++) { for (j=0;j<totalsegs;j++) { if (genUVs) { mesh.tvFace[fc].setTVerts(tt0,tb0++,tb1); mesh.tvFace[fc+1].setTVerts(tt0++,tb1++,tt1++); } if (j<s1segs) sidesm=2; else if (j<s2end) sidesm=4; else sidesm=8; AddFace(&mesh.faces[fc++],t0,b0++,(j==last?t1:b1),0,sidesm); if (j<last) AddFace(&mesh.faces[fc++],t0++,b1,t1,1,sidesm); else AddFace(&mesh.faces[fc++],t0++,b1-totalsegs,t1-totalsegs,1,sidesm); t1++;b1++; } tt0++;tt1++;tb0++;tb1++; } if (genUVs) {tt0=(tt1=ntverts-totalsegs)-1;tb0=ntverts-1;} for (i=0;i<totalsegs;i++) { if (genUVs) { mesh.tvFace[fc].setTVerts(tt0++,tb0,(i==last?tt1-totalsegs:tt1)); tt1++; } AddFace(&mesh.faces[fc++],t0++,b0,(i==last?t1-totalsegs:t1),1,1); t1++; } if (minush) for (i=0;i<nverts;i++) mesh.verts[i].z-=height; assert(fc==mesh.numFaces); // assert(nv==mesh.numVerts); */ } mesh.InvalidateTopologyCache(); }
void MarchingCubeTriangulator::Triangulate(ScalarFieldBuilders::ScalarFieldCreator& inData,const SpatialDiscretization::weight_t& volId, progressOperation& mainProcess) { weigh_parameters_t weigh_parameters; weigh_parameters.volId=volId; BeginFeedingFaces(); ivec3 coordinates; long cellCount_m_one(inData.GetDomainSize()-1); ivec3 i1(1,0,0), i2(1,0,1), i3(0,0,1), i4(0,1,0), i5(1,1,0), i6(1,1,1), i7(0,1,1); PolygoniseAlgo::GRIDCELL grid; PolygoniseAlgo::TRIANGLE triList[5]; int nbtri; progressOperation thisProcess(&mainProcess, (unsigned int) (cellCount_m_one * cellCount_m_one)); for(coordinates.x=0;coordinates.x<cellCount_m_one;coordinates.x++) { for(coordinates.y=0;coordinates.y<cellCount_m_one;coordinates.y++) { progressOperation thisSubProcess(&thisProcess,1); if(VariationWithinFourZ(ivec2(coordinates.x,coordinates.y),inData)) { grid.p[3] = inData.GetCenterCellCoordinates(coordinates+i3); grid.p[2] = inData.GetCenterCellCoordinates(coordinates+i2); grid.p[7] = inData.GetCenterCellCoordinates(coordinates+i7); grid.p[6] = inData.GetCenterCellCoordinates(coordinates+i6); grid.val[3]=WeightEvaluation(inData.GetMatrixValue(coordinates),weigh_parameters); grid.val[2]=WeightEvaluation(inData.GetMatrixValue(coordinates+i1),weigh_parameters); grid.val[7]=WeightEvaluation(inData.GetMatrixValue(coordinates+i4),weigh_parameters); grid.val[6]=WeightEvaluation(inData.GetMatrixValue(coordinates+i5),weigh_parameters); for(coordinates.z=0;coordinates.z<cellCount_m_one;coordinates.z++) { //TODO Computation on x,y loop grid.p[0] = grid.p[3]; grid.p[1] = grid.p[2]; grid.p[4]= grid.p[7]; grid.p[5] = grid.p[6]; grid.p[2] = inData.GetCenterCellCoordinates(coordinates+i2); grid.p[3] = inData.GetCenterCellCoordinates(coordinates+i3); grid.p[6] = inData.GetCenterCellCoordinates(coordinates+i6); grid.p[7] = inData.GetCenterCellCoordinates(coordinates+i7); grid.val[0]=grid.val[3]; grid.val[1]=grid.val[2]; grid.val[4]=grid.val[7]; grid.val[5]=grid.val[6]; grid.val[2]=WeightEvaluation(inData.GetMatrixValue(coordinates+i2),weigh_parameters); grid.val[3]=WeightEvaluation(inData.GetMatrixValue(coordinates+i3),weigh_parameters); grid.val[6]=WeightEvaluation(inData.GetMatrixValue(coordinates+i6),weigh_parameters); grid.val[7]=WeightEvaluation(inData.GetMatrixValue(coordinates+i7),weigh_parameters); nbtri=PolygoniseAlgo::Polygonise(grid,0,triList); if(nbtri>0) { for(int idtri=0;idtri<nbtri;idtri++) { AddFace((const decimal *)&(triList[idtri].p[2]), (const decimal *)&(triList[idtri].p[1]), (const decimal *)&(triList[idtri].p[0])); } } } } } } FinishFeedingFaces(); }