//-------------------------------------------------------------------------------------
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();
}
Exemple #2
0
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);
			}
		}
	}
}
Exemple #7
0
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;
}
Exemple #9
0
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();
}
Exemple #11
0
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
}
Exemple #16
0
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;
}