Ejemplo n.º 1
0
bool ccTorus::buildUp()
{
	if (m_drawPrecision<4)
		return false;

	//invalid parameters?
	if ((m_rectSection && m_rectSectionHeight < ZERO_TOLERANCE) || m_insideRadius >= m_outsideRadius || m_angle_rad < ZERO_TOLERANCE)
		return false;

	//topology
	bool closed = (m_angle_rad >= 2.0*M_PI);

	const unsigned steps = m_drawPrecision;

	unsigned sweepSteps = 4*(closed ? steps : (unsigned)ceil(m_angle_rad*(double)steps/(2.0*M_PI)));
	unsigned sectSteps = (m_rectSection ? 4 : steps);

	//vertices
	unsigned vertCount = (sweepSteps+(closed ? 0 : 1))*sectSteps; //DGM: +1 row for non closed loops
	//faces
	unsigned facesCount = sweepSteps*sectSteps*2;
	//faces normals
	unsigned faceNormCount = (sweepSteps+(closed ? 0 : 1))*sectSteps; //DGM: +1 row for non closed loops
	if (!closed)
		facesCount += (m_rectSection ? 2 : sectSteps)*2;

	if (!init(vertCount+(closed || m_rectSection ? 0 : 2),false,facesCount,faceNormCount+(closed ? 0 : 2)))
	{
		ccLog::Error("[ccTorus::buildUp] Not enough memory");
		return false;
	}

	//2D section
	CCVector3* sectPoints = new CCVector3[sectSteps];
	if (!sectPoints)
	{
		init(0,false,0,0);
		ccLog::Error("[ccTorus::buildUp] Not enough memory");
		return false;
	}

	PointCoordinateType sectionRadius = (m_outsideRadius-m_insideRadius)/2;
	if (m_rectSection)
	{
		//rectangular section
		sectPoints[0].x = (m_outsideRadius-m_insideRadius)/2;
		sectPoints[0].z = m_rectSectionHeight/2;
		sectPoints[1].x = -sectPoints[0].x;
		sectPoints[1].z = sectPoints[0].z;
		sectPoints[2].x = sectPoints[1].x;
		sectPoints[2].z = -sectPoints[1].z;
		sectPoints[3].x = -sectPoints[2].x;
		sectPoints[3].z = sectPoints[2].z;
	}
	else
	{
		//circular section
		for (unsigned i=0;i<sectSteps;++i)
		{
			float sect_angle_rad = (float)i/(float)sectSteps*(float)(2.0*M_PI);
			sectPoints[i].x = cos(sect_angle_rad) * sectionRadius;
			sectPoints[i].z = sin(sect_angle_rad) * sectionRadius;
		}
	}

	ccPointCloud* verts = vertices();
	assert(verts);
	assert(m_triNormals);

	//main sweep
	PointCoordinateType sweepRadius = (m_insideRadius+m_outsideRadius)/(PointCoordinateType)2.0;
	double sweepStep_rad = m_angle_rad/(double)sweepSteps;
	for (unsigned t=0; t<(closed ? sweepSteps : sweepSteps+1); ++t)
	{
		//unit director vector
		CCVector3 sweepU(static_cast<PointCoordinateType>(cos(t*sweepStep_rad)),
						 static_cast<PointCoordinateType>(sin(t*sweepStep_rad)),
						 0);

		//section points
		for (unsigned i=0;i<sectSteps;++i)
		{
			CCVector3 P(sweepU.x * (sweepRadius + sectPoints[i].x),
						sweepU.y * (sweepRadius + sectPoints[i].x),
						sectPoints[i].z);
			verts->addPoint(P);
		}

		//normals
		if (m_rectSection)
		{
			m_triNormals->addElement(ccNormalVectors::GetNormIndex(CCVector3(0.0,0.0,1.0).u));
			m_triNormals->addElement(ccNormalVectors::GetNormIndex((-sweepU).u));
			m_triNormals->addElement(ccNormalVectors::GetNormIndex(CCVector3(0.0,0.0,-1.0).u));
			m_triNormals->addElement(ccNormalVectors::GetNormIndex((-sweepU).u));
		}
		else //circular section
		{
			for (unsigned i=0;i<sectSteps;++i)
			{
				float sectAngle_rad = (float)i/(float)sectSteps*(float)(2.0*M_PI);
				CCVector3 sectU(cos(sectAngle_rad),0.0,sin(sectAngle_rad));
				CCVector3 N(sweepU.x * sectU.x,
					sweepU.y * sectU.x,
					sectU.z);
				m_triNormals->addElement(ccNormalVectors::GetNormIndex(N.u));
			}
		}
	}

	if (!closed && !m_rectSection)
	{
		CCVector3 P(sweepRadius,0,0);
		verts->addPoint(P);
		CCVector3 P2(	static_cast<PointCoordinateType>(cos(m_angle_rad))*sweepRadius,
						static_cast<PointCoordinateType>(sin(m_angle_rad))*sweepRadius,
						 0);
		verts->addPoint(P2);
	}

	if (!closed)
	{
		//first section (left side)
		m_triNormals->addElement(ccNormalVectors::GetNormIndex(CCVector3(0,-1,0).u));
		//last section (right side)
		m_triNormals->addElement(ccNormalVectors::GetNormIndex(CCVector3(	static_cast<PointCoordinateType>(-sin(m_angle_rad)),
																			static_cast<PointCoordinateType>(cos(m_angle_rad)),
																			0).u));
	}

	delete[] sectPoints;
	sectPoints=0;

	//mesh faces
	{
		assert(m_triVertIndexes);

		for (unsigned t=0;t<sweepSteps;++t)
		{
			unsigned sweepStart = t*sectSteps;
			for (unsigned i=0;i<sectSteps;++i)
			{
				unsigned iNext = (i+1)%sectSteps;
				addTriangle(sweepStart+i,(sweepStart+i+sectSteps)%vertCount,(sweepStart+iNext+sectSteps)%vertCount);
				if (m_rectSection)
					addTriangleNormalIndexes(sweepStart+i,(sweepStart+i+sectSteps)%faceNormCount,(sweepStart+i+sectSteps)%faceNormCount);
				else
					addTriangleNormalIndexes(sweepStart+i,(sweepStart+i+sectSteps)%faceNormCount,(sweepStart+iNext+sectSteps)%faceNormCount);
				addTriangle(sweepStart+i,(sweepStart+iNext+sectSteps)%vertCount,sweepStart+iNext);
				if (m_rectSection)
					addTriangleNormalIndexes(sweepStart+i,(sweepStart+i+sectSteps)%faceNormCount,sweepStart+i);
				else
					addTriangleNormalIndexes(sweepStart+i,(sweepStart+iNext+sectSteps)%faceNormCount,sweepStart+iNext);
			}
		}

		if (!closed)
		{
			unsigned lastSectionShift = sweepSteps*sectSteps;
			if (m_rectSection)
			{
				//rectangular left section
				addTriangle(0,1,2);
				addTriangleNormalIndexes(faceNormCount,faceNormCount,faceNormCount);
				addTriangle(0,2,3);
				addTriangleNormalIndexes(faceNormCount,faceNormCount,faceNormCount);
				//rectangular right section
				addTriangle(lastSectionShift,lastSectionShift+2,lastSectionShift+1);
				addTriangleNormalIndexes(faceNormCount+1,faceNormCount+1,faceNormCount+1);
				addTriangle(lastSectionShift,lastSectionShift+3,lastSectionShift+2);
				addTriangleNormalIndexes(faceNormCount+1,faceNormCount+1,faceNormCount+1);
			}
			else
			{
				unsigned lastSectionCenterShift = vertCount;
				//circular 'left' section
				for (unsigned i=0;i<sectSteps;++i)
				{
					unsigned iNext = (i+1)%sectSteps;
					addTriangle(lastSectionCenterShift,i,iNext);
					addTriangleNormalIndexes(faceNormCount,faceNormCount,faceNormCount);
				}
				//circular 'right' section
				for (unsigned i=0;i<sectSteps;++i)
				{
					unsigned iNext = (i+1)%sectSteps;
					addTriangle(lastSectionCenterShift+1,lastSectionShift+iNext,lastSectionShift+i);
					addTriangleNormalIndexes(faceNormCount+1,faceNormCount+1,faceNormCount+1);
				}
			}
		}
	}

	notifyGeometryUpdate();
	showTriNorms(true);

	return true;
}
Ejemplo n.º 2
0
void ccGenericMesh::showNormals(bool state)
{
	showTriNorms(state);
	ccHObject::showNormals(state);
}
Ejemplo n.º 3
0
bool ccCone::buildUp()
{
	if (m_drawPrecision < MIN_DRAWING_PRECISION)
		return false;

	//invalid dimensions?
	if (m_height < ZERO_TOLERANCE || m_bottomRadius + m_topRadius < ZERO_TOLERANCE)
		return false;

	//topology
	bool singlePointBottom = (m_bottomRadius < ZERO_TOLERANCE);
	bool singlePointTop = (m_topRadius < ZERO_TOLERANCE);
	assert(!singlePointBottom || !singlePointTop);

	unsigned steps = m_drawPrecision;

	//vertices
	unsigned vertCount = 2;
	if (!singlePointBottom)
		vertCount += steps;
	if (!singlePointTop)
		vertCount += steps;
	//normals
	unsigned faceNormCounts = steps+2;
	//vertices
	unsigned facesCount = steps;
	if (!singlePointBottom)
		facesCount += steps;
	if (!singlePointTop)
		facesCount += steps;
	if (!singlePointBottom && !singlePointTop)
		facesCount += steps;

	//allocate (& clear) structures
	if (!init(vertCount,false,facesCount,faceNormCounts))
	{
		ccLog::Error("[ccCone::buildUp] Not enough memory");
		return false;
	}

	ccPointCloud* verts = vertices();
	assert(verts);
	assert(m_triNormals);

	//2 first points: centers of the top & bottom surfaces
	CCVector3 bottomCenter = CCVector3(m_xOff,m_yOff,-m_height)/2;
	CCVector3 topCenter = CCVector3(-m_xOff,-m_yOff,m_height)/2;
	{
		//bottom center
		verts->addPoint(bottomCenter);
		CompressedNormType nIndex = ccNormalVectors::GetNormIndex(CCVector3(0,0,-1).u);
		m_triNormals->addElement(nIndex);
		//top center
		verts->addPoint(topCenter);
		nIndex = ccNormalVectors::GetNormIndex(CCVector3(0,0,1).u);
		m_triNormals->addElement(nIndex);
	}
	
	//then, angular sweep for top and/or bottom surfaces
	{
		PointCoordinateType angle_rad_step = static_cast<PointCoordinateType>(2.0*M_PI)/static_cast<PointCoordinateType>(steps);
		//bottom surface
		if (!singlePointBottom)
		{
			for (unsigned i=0; i<steps; ++i)
			{
				CCVector3 P(bottomCenter.x + cos(angle_rad_step*i)*m_bottomRadius,
							bottomCenter.y + sin(angle_rad_step*i)*m_bottomRadius,
							bottomCenter.z);
				verts->addPoint(P);
			}
		}
		//top surface
		if (!singlePointTop)
		{
			for (unsigned i=0; i<steps; ++i)
			{
				CCVector3 P(topCenter.x + cos(angle_rad_step*i)*m_topRadius,
							topCenter.y + sin(angle_rad_step*i)*m_topRadius,
							topCenter.z);
				verts->addPoint(P);
			}
		}
		//side normals
		{
			for (unsigned i=0; i<steps; ++i)
			{
				//slope
				CCVector3 u(-sin(angle_rad_step*i),cos(angle_rad_step*i),0);
				CCVector3 v(bottomCenter.x-topCenter.x + u.y*(m_bottomRadius-m_topRadius),
							bottomCenter.y-topCenter.y - u.x*(m_bottomRadius-m_topRadius),
							bottomCenter.z-topCenter.z);
				CCVector3 N = v.cross(u);
				N.normalize();

				CompressedNormType nIndex = ccNormalVectors::GetNormIndex(N.u);
				m_triNormals->addElement(nIndex);
			}
		}
	}
	
	//mesh faces
	{
		assert(m_triVertIndexes);

		unsigned bottomIndex = 2;
		unsigned topIndex = 2+(singlePointBottom ? 0 : steps);

		//bottom surface
		if (!singlePointBottom)
		{
			for (unsigned i=0;i<steps;++i)
			{
				addTriangle(0,bottomIndex+(i+1)%steps,bottomIndex+i);
				addTriangleNormalIndexes(0,0,0);
			}
		}
		//top surface
		if (!singlePointTop)
		{
			for (unsigned i=0;i<steps;++i)
			{
				addTriangle(1,topIndex+i,topIndex+(i+1)%steps);
				addTriangleNormalIndexes(1,1,1);
			}
		}

		if (!singlePointBottom && !singlePointTop)
		{
			for (unsigned i=0;i<steps;++i)
			{
				unsigned iNext = (i+1)%steps;
				addTriangle(bottomIndex+i,bottomIndex+iNext,topIndex+i);
				addTriangleNormalIndexes(2+i,2+iNext,2+i);
				addTriangle(topIndex+i,bottomIndex+iNext,topIndex+iNext);
				addTriangleNormalIndexes(2+i,2+iNext,2+iNext);
			}
		}
		else if (!singlePointTop)
		{
			for (unsigned i=0;i<steps;++i)
			{
				unsigned iNext = (i+1)%steps;
				addTriangle(topIndex+i,0,topIndex+iNext);
				addTriangleNormalIndexes(2+i,2+iNext,2+iNext); //TODO: middle normal should be halfbetween?!
			}
		}
		else //if (!singlePointBottom)
		{
			for (unsigned i=0;i<steps;++i)
			{
				unsigned iNext = (i+1)%steps;
				addTriangle(bottomIndex+i,bottomIndex+iNext,1);
				addTriangleNormalIndexes(2+i,2+iNext,2+i); //TODO: last normal should be halfbetween?!
			}
		}
	}

	notifyGeometryUpdate();
	showTriNorms(true);

	return true;
}