//------------------------------------------------------------------------------------- void EntityCoordinateNode::update() { // 在这里做一下更新的原因是,很可能在CoordinateNode::update()的过程中导致实体位置被移动 // 而导致次数update被调用,在某种情况下会出现问题 // 例如:// A->B, B-A(此时old_*是B), A->B(此时old_*是B,而xx等目的地就是B),此时update中会误判为没有移动。 // https://github.com/kbengine/kbengine/issues/407 old_xx(x()); old_yy(y()); old_zz(z()); CoordinateNode::update(); addFlags(COORDINATE_NODE_FLAG_ENTITY_NODE_UPDATING); ++entityNodeUpdating_; // 此处必须使用watcherNodes_.size()而不能使用迭代器遍历,防止在update中导致增加了watcherNodes_数量而破坏迭代器 for (std::vector<CoordinateNode*>::size_type i = 0; i < watcherNodes_.size(); ++i) { CoordinateNode* pCoordinateNode = watcherNodes_[i]; if (!pCoordinateNode) continue; pCoordinateNode->update(); } --entityNodeUpdating_; if (entityNodeUpdating_ == 0) removeFlags(COORDINATE_NODE_FLAG_ENTITY_NODE_UPDATING); clearDelWatcherNodes(); }
static void DrawPointSet(PointSetNode *pointSet) { CoordinateNode *coordinate = pointSet->getCoordinateNodes(); if (!coordinate) return; NormalNode *normal = pointSet->getNormalNodes(); ColorNode *color = pointSet->getColorNodes(); float vpoint[3]; float pcolor[3]; glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_POINTS); int nCoordinatePoint = coordinate->getNPoints(); for (int n=0; n<nCoordinatePoint; n++) { if (color) { color->getColor(n, pcolor); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, pcolor); // glColor3fv(pcolor); } coordinate->getPoint(n, vpoint); glVertex3fv(vpoint); } glEnd(); }
static void DrawIdxLineSet(IndexedLineSetNode *idxLineSet) { CoordinateNode *coordinate = idxLineSet->getCoordinateNodes(); if (!coordinate) return; NormalNode *normal = idxLineSet->getNormalNodes(); ColorNode *color = idxLineSet->getColorNodes(); int bColorPerVertex =idxLineSet->getColorPerVertex(); bool bLineBegin = true; bool bLineClose = true; int nLine = 0; float vpoint[3]; float pcolor[3]; glColor3f(1.0f, 1.0f, 1.0f); int nCoordIndexes = idxLineSet->getNCoordIndexes(); for (int nCoordIndex=0; nCoordIndex<nCoordIndexes; nCoordIndex++) { int coordIndex = idxLineSet->getCoordIndex(nCoordIndex); if (bLineBegin) { glBegin(GL_LINE_STRIP); bLineBegin = false; bLineClose = false; if (color && !bColorPerVertex) { color->getColor(nLine, pcolor); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, pcolor); // glColor3fv(pcolor); } nLine++; } if (coordIndex != -1) { coordinate->getPoint(coordIndex, vpoint); glVertex3fv(vpoint); if (color && bColorPerVertex) { color->getColor(coordIndex, pcolor); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, pcolor); // glColor3fv(pcolor); } } else { glEnd(); bLineBegin = true; bLineClose = true; } } if (bLineClose == false) glEnd(); }
//------------------------------------------------------------------------------------- void CoordinateSystem::moveNodeY(CoordinateNode* pNode, float py, CoordinateNode* pCurrNode) { if(pCurrNode != NULL) { if(pCurrNode->y() > py) { CoordinateNode* pPreNode = pCurrNode->pPrevY(); pCurrNode->pPrevY(pNode); if(pPreNode) { pPreNode->pNextY(pNode); if(pNode == first_y_coordinateNode_ && pNode->pNextY()) first_y_coordinateNode_ = pNode->pNextY(); } else { first_y_coordinateNode_ = pNode; } if(pNode->pPrevY()) pNode->pPrevY()->pNextY(pNode->pNextY()); if(pNode->pNextY()) pNode->pNextY()->pPrevY(pNode->pPrevY()); pNode->pPrevY(pPreNode); pNode->pNextY(pCurrNode); } else { CoordinateNode* pNextNode = pCurrNode->pNextY(); if(pNextNode != pNode) { pCurrNode->pNextY(pNode); if(pNextNode) pNextNode->pPrevY(pNode); if(pNode->pPrevY()) pNode->pPrevY()->pNextY(pNode->pNextY()); if(pNode->pNextY()) { pNode->pNextY()->pPrevY(pNode->pPrevY()); if(pNode == first_y_coordinateNode_) first_y_coordinateNode_ = pNode->pNextY(); } pNode->pPrevY(pCurrNode); pNode->pNextY(pNextNode); } } } }
//------------------------------------------------------------------------------------- void CoordinateSystem::moveNodeX(CoordinateNode* pNode, float px, CoordinateNode* pCurrNode) { if(pCurrNode != NULL) { if(pCurrNode->x() > px) { CoordinateNode* pPreNode = pCurrNode->pPrevX(); pCurrNode->pPrevX(pNode); if(pPreNode) { pPreNode->pNextX(pNode); if(pNode == first_x_coordinateNode_ && pNode->pNextX()) first_x_coordinateNode_ = pNode->pNextX(); } else { first_x_coordinateNode_ = pNode; } if(pNode->pPrevX()) pNode->pPrevX()->pNextX(pNode->pNextX()); if(pNode->pNextX()) pNode->pNextX()->pPrevX(pNode->pPrevX()); pNode->pPrevX(pPreNode); pNode->pNextX(pCurrNode); } else { CoordinateNode* pNextNode = pCurrNode->pNextX(); if(pNextNode != pNode) { pCurrNode->pNextX(pNode); if(pNextNode) pNextNode->pPrevX(pNode); if(pNode->pPrevX()) pNode->pPrevX()->pNextX(pNode->pNextX()); if(pNode->pNextX()) { pNode->pNextX()->pPrevX(pNode->pPrevX()); if(pNode == first_x_coordinateNode_) first_x_coordinateNode_ = pNode->pNextX(); } pNode->pPrevX(pCurrNode); pNode->pNextX(pNextNode); } } } }
//------------------------------------------------------------------------------------- void CoordinateSystem::moveNodeZ(CoordinateNode* pNode, float pz, CoordinateNode* pCurrNode) { if(pCurrNode != NULL) { if(pCurrNode->z() > pz) { CoordinateNode* pPreNode = pCurrNode->pPrevZ(); pCurrNode->pPrevZ(pNode); if(pPreNode) { pPreNode->pNextZ(pNode); if(pNode == first_z_coordinateNode_ && pNode->pNextZ()) first_z_coordinateNode_ = pNode->pNextZ(); } else { first_z_coordinateNode_ = pNode; } if(pNode->pPrevZ()) pNode->pPrevZ()->pNextZ(pNode->pNextZ()); if(pNode->pNextZ()) pNode->pNextZ()->pPrevZ(pNode->pPrevZ()); pNode->pPrevZ(pPreNode); pNode->pNextZ(pCurrNode); } else { CoordinateNode* pNextNode = pCurrNode->pNextZ(); if(pNextNode != pNode) { pCurrNode->pNextZ(pNode); if(pNextNode) pNextNode->pPrevZ(pNode); if(pNode->pPrevZ()) pNode->pPrevZ()->pNextZ(pNode->pNextZ()); if(pNode->pNextZ()) { pNode->pNextZ()->pPrevZ(pNode->pPrevZ()); if(pNode == first_z_coordinateNode_) first_z_coordinateNode_ = pNode->pNextZ(); } pNode->pPrevZ(pCurrNode); pNode->pNextZ(pNextNode); } } } }
CoordinateNode *SceneGraph::findCoordinateNode(char *name) { if (!name || strlen(name) <= 0) return NULL; for (CoordinateNode *node = findCoordinateNode(); node; node = node->nextTraversal()) { const char *nodeName = node->getName(); if (nodeName && strlen(nodeName)) { if (!strcmp(name, nodeName)) return node; } } return NULL; }
bool IndexedFaceSetNode::generateNormals() { NormalNode *normal = getNormalNodes(); if (normal) return false; CoordinateNode *coordinateNode = getCoordinateNodes(); if (!coordinateNode) return false; normal = new NormalNode(); int nPolygon = 0; int nVertex = 0; float point[3][3]; float vector[3]; int nCoordIndexes = getNCoordIndexes(); for (int nCoordIndex=0; nCoordIndex<nCoordIndexes; nCoordIndex++) { int coordIndex = getCoordIndex(nCoordIndex); if (coordIndex != -1) { if (nVertex < 3) coordinateNode->getPoint(coordIndex, point[nVertex]); nVertex++; } else { GetNormalFromVertices(point, vector); normal->addVector(vector); nVertex = 0; nPolygon++; } } addChildNode(normal); setNormalPerVertex(false); return true; }
void PointSetNode::recomputeBoundingBox() { CoordinateNode *coordinate = getCoordinateNodes(); if (!coordinate) { setBoundingBoxCenter(0.0f, 0.0f, 0.0f); setBoundingBoxSize(-1.0f, -1.0f, -1.0f); return; } BoundingBox bbox; float point[3]; int nCoordinatePoints = coordinate->getNPoints(); for (int n=0; n<nCoordinatePoints; n++) { coordinate->getPoint(n, point); bbox.addPoint(point); } setBoundingBox(&bbox); }
//------------------------------------------------------------------------------------- void EntityCoordinateNode::onRemove() { for (std::vector<CoordinateNode*>::size_type i = 0; i < watcherNodes_.size(); ++i) { CoordinateNode* pCoordinateNode = watcherNodes_[i]; if (!pCoordinateNode) continue; // 先设置为NULL, 在后面update时进行删除 // 此处不能对watcherNodes_做大小做修改,因为可能由EntityCoordinateNode::update()中导致该处调用 // 那么可能导致EntityCoordinateNode::update()在循环watcherNodes_中被修改而出错。 watcherNodes_[i] = NULL; ++delWatcherNodeNum_; pCoordinateNode->onParentRemove(this); } CoordinateNode::onRemove(); }
void PointSetNode::outputContext(std::ostream &printStream, const char *indentString) const { ColorNode *color = getColorNodes(); if (color != NULL) { if (color->isInstanceNode() == false) { if (color->getName() != NULL && strlen(color->getName())) printStream << indentString << "\t" << "color " << "DEF " << color->getName() << " Color {" << std::endl; else printStream << indentString << "\t" << "color Color {" << std::endl; color->Node::outputContext(printStream, indentString, "\t"); printStream << indentString << "\t" << "}" << std::endl; } else printStream << indentString << "\t" << "color USE " << color->getName() << std::endl; } CoordinateNode *coord = getCoordinateNodes(); if (coord != NULL) { if (coord->isInstanceNode() == false) { if (coord->getName() != NULL && strlen(coord->getName())) printStream << indentString << "\t" << "coord " << "DEF " << coord->getName() << " Coordinate {" << std::endl; else printStream << indentString << "\t" << "coord Coordinate {" << std::endl; coord->Node::outputContext(printStream, indentString, "\t"); printStream << indentString << "\t" << "}" << std::endl; } else printStream << indentString << "\t" << "coord USE " << coord->getName() << std::endl; } }
//------------------------------------------------------------------------------------- void EntityCoordinateNode::update() { CoordinateNode::update(); addFlags(COORDINATE_NODE_FLAG_ENTITY_NODE_UPDATING); ++entityNodeUpdating_; // 此处必须使用watcherNodes_.size()而不能使用迭代器遍历,防止在update中导致增加了watcherNodes_数量而破坏迭代器 for (std::vector<CoordinateNode*>::size_type i = 0; i < watcherNodes_.size(); ++i) { CoordinateNode* pCoordinateNode = watcherNodes_[i]; if (!pCoordinateNode) continue; pCoordinateNode->update(); } --entityNodeUpdating_; if (entityNodeUpdating_ == 0) removeFlags(COORDINATE_NODE_FLAG_ENTITY_NODE_UPDATING); clearDelWatcherNodes(); }
static void DrawIdxFaceSet(IndexedFaceSetNode *idxFaceSet) { CoordinateNode *coordinateNode = idxFaceSet->getCoordinateNodes(); if (!coordinateNode) return; TextureCoordinateNode *texCoordNode = idxFaceSet->getTextureCoordinateNodes(); NormalNode *normalNode = idxFaceSet->getNormalNodes(); ColorNode *colorNode = idxFaceSet->getColorNodes(); bool colorPerVertex =idxFaceSet->getColorPerVertex(); bool normalPerVertex =idxFaceSet->getNormalPerVertex(); bool ccw = idxFaceSet->getCCW(); if (ccw == true) glFrontFace(GL_CCW); else glFrontFace(GL_CW); bool solid = idxFaceSet->getSolid(); if (solid == false) glDisable(GL_CULL_FACE); else glEnable(GL_CULL_FACE); bool convex = idxFaceSet->getConvex(); GLUtriangulatorObj *tessObj = NULL; if (convex == false) { tessObj = gluNewTess(); gluTessCallback(tessObj, GLU_BEGIN, (GLUtessCallBackFunc)glBegin); gluTessCallback(tessObj, GLU_VERTEX, (GLUtessCallBackFunc)glVertex3dv); gluTessCallback(tessObj, GLU_END, (GLUtessCallBackFunc)glEnd); } bool bPolygonBegin = true; bool bPolygonClose = true; int nPolygon = 0; int nVertex = 0; float point[3]; float vector[3]; float color[4]; color[3] = 1.0f; float coord[2]; double (*tessPoint)[3]; if ((idxFaceSet->getColorPerVertex() && idxFaceSet->getColorNodes()) || (idxFaceSet->getNormalPerVertex() && idxFaceSet->getNormalNodes())) glShadeModel (GL_SMOOTH); else glShadeModel (GL_FLAT); int nColorIndexes = idxFaceSet->getNColorIndexes(); int nNormalIndexes = idxFaceSet->getNNormalIndexes(); int nTexCoordIndexes = idxFaceSet->getNTexCoordIndexes(); int nCoordIndexes = idxFaceSet->getNCoordIndexes(); for (int nCoordIndex=0; nCoordIndex<nCoordIndexes; nCoordIndex++) { int coordIndex = idxFaceSet->getCoordIndex(nCoordIndex); if (bPolygonBegin) { if (convex == false) gluBeginPolygon(tessObj); else glBegin(GL_POLYGON); bPolygonBegin = false; bPolygonClose = false; int nVertices = 0; int index = coordIndex; while (index != -1) { nVertices++; int nIndex = nCoordIndex + nVertices; if (nIndex < nCoordIndexes) index = idxFaceSet->getCoordIndex(nIndex); else break; } if (convex == false) tessPoint = new double[nVertices][3]; // dafault color //glColor3f(1.0f, 1.0f, 1.0f); // default normal if ((nCoordIndex + 2) < nCoordIndexes) { float point[3][3]; float normal[3]; for (int n=0; n<3; n++) { int index = idxFaceSet->getCoordIndex(nCoordIndex+n); coordinateNode->getPoint(index, point[n]); } GetNormalFromVertices(point, normal); glNormal3fv(normal); } else glNormal3f(0.0f, 0.0f, 1.0f); if (colorNode && !colorPerVertex) { if (0 < nColorIndexes) colorNode->getColor(idxFaceSet->getColorIndex(nPolygon), color); else colorNode->getColor(nPolygon, color); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); // glColor3fv(color); } if (normalNode && !normalPerVertex) { if (0 < nNormalIndexes) normalNode->getVector(idxFaceSet->getNormalIndex(nPolygon), vector); else normalNode->getVector(nPolygon, vector); glNormal3fv(vector); } nPolygon++; nVertex = 0; } if (coordIndex != -1) { if (colorNode && colorPerVertex) { if (0 < nColorIndexes) colorNode->getColor(idxFaceSet->getColorIndex(nCoordIndex), color); else colorNode->getColor(coordIndex, color); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); // glColor3fv(color); } if (normalNode && normalPerVertex) { if (0 < nNormalIndexes) normalNode->getVector(idxFaceSet->getNormalIndex(nCoordIndex), vector); else normalNode->getVector(coordIndex, vector); glNormal3fv(vector); } if (texCoordNode) { if (0 < nTexCoordIndexes) texCoordNode->getPoint(idxFaceSet->getTexCoordIndex(nCoordIndex), coord); else texCoordNode->getPoint(coordIndex, coord); coord[1] = 1.0f - coord[1]; glTexCoord2fv(coord); } coordinateNode->getPoint(coordIndex, point); if (convex == false) { tessPoint[nVertex][0] = point[0]; tessPoint[nVertex][1] = point[1]; tessPoint[nVertex][2] = point[2]; gluTessVertex(tessObj, tessPoint[nVertex], tessPoint[nVertex]); } else glVertex3fv(point); nVertex++; } else { if (convex == false) { gluEndPolygon(tessObj); delete[] tessPoint; } else glEnd(); bPolygonBegin = true; bPolygonClose = true; } } if (bPolygonClose == false) { if (convex == false) { gluEndPolygon(tessObj); delete[] tessPoint; } else glEnd(); } if (ccw == false) glFrontFace(GL_CCW); if (solid == false) glEnable(GL_CULL_FACE); if (convex == false) gluDeleteTess(tessObj); glShadeModel(GL_SMOOTH); }
//------------------------------------------------------------------------------------- CoordinateSystem::~CoordinateSystem() { dels_.clear(); dels_count_ = 0; if(first_x_coordinateNode_) { CoordinateNode* pNode = first_x_coordinateNode_; while(pNode != NULL) { CoordinateNode* pNextNode = pNode->pNextX(); if (pNextNode) pNextNode->pPrevX(NULL); pNode->pCoordinateSystem(NULL); pNode->pPrevX(NULL); pNode->pNextX(NULL); pNode->pPrevY(NULL); pNode->pNextY(NULL); pNode->pPrevZ(NULL); pNode->pNextZ(NULL); delete pNode; pNode = pNextNode; } // 上面已经销毁过了 first_x_coordinateNode_ = NULL; first_y_coordinateNode_ = NULL; first_z_coordinateNode_ = NULL; } releaseNodes(); }
//------------------------------------------------------------------------------------- void CoordinateSystem::update(CoordinateNode* pNode) { AUTO_SCOPED_PROFILE("coordinateSystemUpdates"); #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update enter:[{:p}]: ({} {} {})\n", (void*)pNode, pNode->xx(), pNode->yy(), pNode->zz())); #endif // 没有计数器支持,这个标记很可能中途被update子分支取消,因此没有意义 //pNode->addFlags(COORDINATE_NODE_FLAG_PENDING); ++updating_; if(pNode->xx() != pNode->old_xx()) { while(true) { CoordinateNode* pCurrNode = pNode->pPrevX(); while(pCurrNode && pCurrNode != pNode && pCurrNode->x() > pNode->xx()) { pNode->x(pCurrNode->x()); #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update start: [-X] ({}), pCurrNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif // 先把节点移动过去 moveNodeX(pNode, pNode->xx(), pCurrNode); if (!pNode->hasFlags(COORDINATE_NODE_FLAG_HIDE_OR_REMOVED)) { #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update1: [-X] ({}), passNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif pCurrNode->onNodePassX(pNode, true); } if (!pCurrNode->hasFlags(COORDINATE_NODE_FLAG_HIDE_OR_REMOVED)) { #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update2: [-X] ({}), passNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif pNode->onNodePassX(pCurrNode, false); } #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update end: [-X] ({}), pCurrNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif if (pNode->pPrevX() == NULL) break; pCurrNode = pNode->pPrevX(); } pCurrNode = pNode->pNextX(); while(pCurrNode && pCurrNode != pNode && pCurrNode->x() < pNode->xx()) { pNode->x(pCurrNode->x()); #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update start: [+X] ({}), pCurrNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif // 先把节点移动过去 moveNodeX(pNode, pNode->xx(), pCurrNode); if (!pNode->hasFlags(COORDINATE_NODE_FLAG_HIDE_OR_REMOVED)) { #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update1: [+X] ({}), passNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif pCurrNode->onNodePassX(pNode, true); } if (!pCurrNode->hasFlags(COORDINATE_NODE_FLAG_HIDE_OR_REMOVED)) { #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update2: [+X] ({}), passNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif pNode->onNodePassX(pCurrNode, false); } #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update end: [+X] ({}), pCurrNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif if (pNode->pNextX() == NULL) break; pCurrNode = pNode->pNextX(); } if((pNode->pPrevX() == NULL || (pNode->xx() >= pNode->pPrevX()->x())) && (pNode->pNextX() == NULL || (pNode->xx() <= pNode->pNextX()->x()))) { pNode->x(pNode->xx()); break; } } } if(CoordinateSystem::hasY && pNode->yy() != pNode->old_yy()) { while(true) { CoordinateNode* pCurrNode = pNode->pPrevY(); while(pCurrNode && pCurrNode != pNode && pCurrNode->y() > pNode->yy()) { pNode->y(pCurrNode->y()); #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update start: [-Y] ({}), pCurrNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif // 先把节点移动过去 moveNodeY(pNode, pNode->yy(), pCurrNode); if (!pNode->hasFlags(COORDINATE_NODE_FLAG_HIDE_OR_REMOVED)) { #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update1: [-Y] ({}), passNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif pCurrNode->onNodePassY(pNode, true); } if (!pCurrNode->hasFlags(COORDINATE_NODE_FLAG_HIDE_OR_REMOVED)) { #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update2: [-Y] ({}), passNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif pNode->onNodePassY(pCurrNode, false); } #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update end: [-Y] ({}), pCurrNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif if (pNode->pPrevY() == NULL) break; pCurrNode = pNode->pPrevY(); } pCurrNode = pNode->pNextY(); while(pCurrNode && pCurrNode != pNode && pCurrNode->y() < pNode->yy()) { pNode->y(pCurrNode->y()); #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update start: [+Y] ({}), pCurrNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif // 先把节点移动过去 moveNodeY(pNode, pNode->yy(), pCurrNode); if (!pNode->hasFlags(COORDINATE_NODE_FLAG_HIDE_OR_REMOVED)) { #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update1: [+Y] ({}), passNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif pCurrNode->onNodePassY(pNode, true); } if (!pCurrNode->hasFlags(COORDINATE_NODE_FLAG_HIDE_OR_REMOVED)) { #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update2: [+Y] ({}), passNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif pNode->onNodePassY(pCurrNode, false); } #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update end: [+Y] ({}), pCurrNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif if (pNode->pNextY() == NULL) break; pCurrNode = pNode->pNextY(); } if((pNode->pPrevY() == NULL || (pNode->yy() >= pNode->pPrevY()->y())) && (pNode->pNextY() == NULL || (pNode->yy() <= pNode->pNextY()->y()))) { pNode->y(pNode->yy()); break; } } } if(pNode->zz() != pNode->old_zz()) { while(true) { CoordinateNode* pCurrNode = pNode->pPrevZ(); while(pCurrNode && pCurrNode != pNode && pCurrNode->z() > pNode->zz()) { pNode->z(pCurrNode->z()); #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update start: [-Z] ({}), pCurrNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif // 先把节点移动过去 moveNodeZ(pNode, pNode->zz(), pCurrNode); if (!pNode->hasFlags(COORDINATE_NODE_FLAG_HIDE_OR_REMOVED)) { #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update1: [-Z] ({}), passNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif pCurrNode->onNodePassZ(pNode, true); } if (!pCurrNode->hasFlags(COORDINATE_NODE_FLAG_HIDE_OR_REMOVED)) { #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update2: [-Z] ({}), passNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif pNode->onNodePassZ(pCurrNode, false); } #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update end: [-Z] ({}), pCurrNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif if (pNode->pPrevZ() == NULL) break; pCurrNode = pNode->pPrevZ(); } pCurrNode = pNode->pNextZ(); while(pCurrNode && pCurrNode != pNode && pCurrNode->z() < pNode->zz()) { pNode->z(pCurrNode->z()); #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update start: [+Z] ({}), pCurrNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif // 先把节点移动过去 moveNodeZ(pNode, pNode->zz(), pCurrNode); if (!pNode->hasFlags(COORDINATE_NODE_FLAG_HIDE_OR_REMOVED)) { #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update:1 [+Z] ({}), passNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif pCurrNode->onNodePassZ(pNode, true); } if (!pCurrNode->hasFlags(COORDINATE_NODE_FLAG_HIDE_OR_REMOVED)) { #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update:2 [+Z] ({}), passNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif pNode->onNodePassZ(pCurrNode, false); } #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::update end: [+Z] ({}), pCurrNode=>({})\n", pNode->c_str(), pCurrNode->c_str())); #endif if (pNode->pNextZ() == NULL) break; pCurrNode = pNode->pNextZ(); } if((pNode->pPrevZ() == NULL || (pNode->zz() >= pNode->pPrevZ()->z())) && (pNode->pNextZ() == NULL || (pNode->zz() <= pNode->pNextZ()->z()))) { pNode->z(pNode->zz()); break; } } } pNode->resetOld(); //pNode->removeFlags(COORDINATE_NODE_FLAG_PENDING); --updating_; //if (updating_ == 0) // releaseNodes(); #ifdef DEBUG_COORDINATE_SYSTEM DEBUG_MSG(fmt::format("CoordinateSystem::debugX[ x ]:[{:p}]\n", (void*)pNode)); first_x_coordinateNode_->debugX(); DEBUG_MSG(fmt::format("CoordinateSystem::debugY[ y ]:[{:p}]\n", (void*)pNode)); if (first_y_coordinateNode_)first_y_coordinateNode_->debugY(); DEBUG_MSG(fmt::format("CoordinateSystem::debugZ[ z ]:[{:p}]\n", (void*)pNode)); first_z_coordinateNode_->debugZ(); #endif }
int ColModel::add_triangles_face(TransformNode* tnode, IndexedFaceSetNode* inode) { CoordinateNode* cnode = inode->getCoordinateNodes(); if(!cnode) return -1; int n_my_vertex = cnode->getNPoints(); int n_index = inode->getNCoordIndexes(); if(n_my_vertex == 0 || n_index == 0) return 0; int i; int vertex_id_base = n_vertex; n_vertex += n_my_vertex; // reallocate memory for saving vertices and save current vertices #if 1 fVec3* tmp_vertices = vertices; vertices = new fVec3 [n_vertex]; if(tmp_vertices) { for(i=0; i<vertex_id_base; i++) vertices[i].set(tmp_vertices[i]); delete[] tmp_vertices; } #else fVec3* tmp_vertices = 0; if(vertices) { tmp_vertices = new fVec3 [vertex_id_base]; for(i=0; i<vertex_id_base; i++) tmp_vertices[i].set(vertices[i]); delete[] vertices; } vertices = new fVec3 [n_vertex]; for(i=0; i<vertex_id_base; i++) vertices[i].set(tmp_vertices[i]); if(tmp_vertices) delete[] tmp_vertices; #endif float fp[3]; for(i=0; i<n_my_vertex; i++) { cnode->getPoint(i, fp); vertices[i+vertex_id_base](0) = fp[0]; vertices[i+vertex_id_base](1) = fp[1]; vertices[i+vertex_id_base](2) = fp[2]; apply_all_transforms(tnode, (Node*)cnode, vertices[i+vertex_id_base]); } // process polygons (all changed to ccw) int ccw = inode->getCCW(); for(i=0; i<n_index; i++) { int c1, c2, c3; c1 = inode->getCoordIndex(i); i++; while( (c2 = inode->getCoordIndex(i)) != -1 && (c3 = inode->getCoordIndex(i+1)) != -1 ) { TriangleInfo* ti = 0; if(ccw) ti = new TriangleInfo(c1+vertex_id_base, c2+vertex_id_base, c3+vertex_id_base); else ti = new TriangleInfo(c1+vertex_id_base, c3+vertex_id_base, c2+vertex_id_base); triangles.append(ti); n_triangle++; i++; } i += 1; } return 0; }
bool IndexedFaceSetNode::generateTextureCoordinate() { TextureCoordinateNode *texCoord = getTextureCoordinateNodes(); if (texCoord) return false; CoordinateNode *coordinateNode = getCoordinateNodes(); if (!coordinateNode) return false; texCoord = new TextureCoordinateNode(); int nPolygon = getNPolygons(); if (nPolygon <= 0) return false; float (*normal)[3] = new float[nPolygon][3]; SFVec3f *center = new SFVec3f[nPolygon]; SFVec3f *maxExtents = new SFVec3f[nPolygon]; SFVec3f *minExtents = new SFVec3f[nPolygon]; bool bPolygonBegin; int polyn; float point[3][3]; float coord[3]; int vertexn = 0; int n; bPolygonBegin = true; polyn = 0; /* int nColorIndexes = idxFaceSet->getNColorIndexes(); int nNormalIndexes = idxFaceSet->getNNormalIndexes(); int nTexCoordIndexes = idxFaceSet->getNTexCoordIndexes(); */ int nCoordIndexes = getNCoordIndexes(); for (n=0; n<nCoordIndexes; n++) { int coordIndex = getCoordIndex(n); if (coordIndex != -1) { if (vertexn < 3) coordinateNode->getPoint(coordIndex, point[vertexn]); float point[3]; coordinateNode->getPoint(coordIndex, point); if (bPolygonBegin) { maxExtents[polyn].setValue(point); minExtents[polyn].setValue(point); center[polyn].setValue(point); bPolygonBegin = false; } else { SetExtents(maxExtents[polyn], minExtents[polyn], point); center[polyn].add(point); } vertexn++; } else { GetNormalFromVertices(point, normal[polyn]); center[polyn].scale(1.0f / (float)vertexn); maxExtents[polyn].sub(center[polyn]); minExtents[polyn].sub(center[polyn]); vertexn = 0; bPolygonBegin = true; polyn++; } } float minx, miny, maxx, maxy, xlength, ylength; SFMatrix matrix; bPolygonBegin = true; polyn = 0; for (n=0; n<nCoordIndexes; n++) { int coordIndex = getCoordIndex(n); if (coordIndex != -1) { if (bPolygonBegin) { GetRotateMatrixFromNormal(normal[polyn], matrix); matrix.multi(&minExtents[polyn]); matrix.multi(&maxExtents[polyn]); minx = minExtents[polyn].getX(); miny = minExtents[polyn].getY(); maxx = maxExtents[polyn].getX(); maxy = maxExtents[polyn].getY(); xlength = (float)fabs(maxExtents[polyn].getX() - minExtents[polyn].getX()); ylength = (float)fabs(maxExtents[polyn].getY() - minExtents[polyn].getY()); if (xlength == 0.0f || ylength == 0.0f) { delete texCoord; delete []minExtents; delete []maxExtents; delete []center; delete []normal; return false; } bPolygonBegin = false; } coordinateNode->getPoint(coordIndex, coord); coord[0] -= center[polyn].getX(); coord[1] -= center[polyn].getY(); coord[2] -= center[polyn].getZ(); matrix.multi(coord); coord[0] = (float)fabs(coord[0] - minx) / xlength; coord[1] = (float)fabs(coord[1] - miny) / ylength; texCoord->addPoint(coord); } else { // coord[0] = coord[1] = 0.0f; // texCoord->addPoint(coord); bPolygonBegin = true; polyn++; } } addChildNode(texCoord); delete []minExtents; delete []maxExtents; delete []center; delete []normal; return true; }