コード例 #1
0
void CubeMapRenderer::render(const CubeMapTextureObject& cubeMapTexture, const ICamera<float>& camera, const TriangleBuffer& buffer)
{
	const auto& positions = buffer.getPositions().get();// buffers[0].get();
	const auto& normals = buffer.getNormals().get();//buffers[1].get();
	if (positions.empty()) {
		return;
	}

	cubeMapTexture.bind();


	glEnable(GL_DEPTH_TEST);

	glUseProgram(shader.getId());

	//cubeMapTexture.bind();

//	glUniform1f(shader.getUniformLocation("reflectFactor"), 0.8f);
//	glUniform1f(shader.getUniformLocation("refractFactor"), 1.2f);

	assert(GL_NO_ERROR == glGetError());

	glUniform1i(shader.getUniformLocation("cubeMapTex"), cubeMapTexture.getId());// volumeTexture.getId());
	glUniform3fv(shader.getUniformLocation("eyePosition"), 1, camera.getPosition().toArray().data());
	assert(GL_NO_ERROR == glGetError());


	glUniformMatrix4fv(shader.getUniformLocation("modelviewMatrix"), 1, false, camera.getModelviewMatrix().toArray().data());
	glUniformMatrix4fv(shader.getUniformLocation("projectionMatrix"), 1, false, camera.getProjectionMatrix().toArray().data());


	assert(GL_NO_ERROR == glGetError());

	glVertexAttribPointer(shader.getAttribLocation("position"), 3, GL_FLOAT, GL_FALSE, 0, positions.data());
	glVertexAttribPointer(shader.getAttribLocation("normal"), 3, GL_FLOAT, GL_FALSE, 0, normals.data());

	assert(GL_NO_ERROR == glGetError());

	assert(GL_NO_ERROR == glGetError());

	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);

	for (const auto& b : buffer.getBlocks()) {
		const auto& indices = b.getIndices();
		glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(indices.size()), GL_UNSIGNED_INT, indices.data());
	}

	glDisableVertexAttribArray(0);
	glDisableVertexAttribArray(1);

	glBindFragDataLocation(shader.getId(), 0, "fragColor");

	cubeMapTexture.unbind();
	glDisable(GL_DEPTH_TEST);


	glUseProgram(0);

}
コード例 #2
0
void TorusGenerator::AddToTriangleBuffer(TriangleBuffer& Buffer) const
{
    Buffer.RebaseOffset();
    Buffer.EstimateVertexCount( ( this->NumPoloidalSeg + 1 ) * ( this->NumToroidalSeg + 1 ) );
    Buffer.EstimateIndexCount( ( this->NumPoloidalSeg ) * ( this->NumToroidalSeg + 1 ) * 6 );

    Real deltaSection = ( MathTools::GetTwoPi() / this->NumToroidalSeg );
    Real deltaCircle = ( MathTools::GetTwoPi() / this->NumPoloidalSeg );
    Integer Offset = 0;

    for( Whole i = 0 ; i <= this->NumPoloidalSeg ; i++ )
    {
        for( Whole j = 0 ; j<= this->NumToroidalSeg ; j++ )
        {
            Vector3 c0( this->TorusPoloidalRadius, 0.0, 0.0 );
            Vector3 v0( this->TorusPoloidalRadius + this->TorusToroidalRadius * cosf( j * deltaSection ), this->TorusToroidalRadius * sinf( j * deltaSection ), 0.0 );
            Quaternion q( i * deltaCircle, Vector3::Unit_Y() );
            Vector3 v = q * v0;
            Vector3 c = q * c0;
            this->AddPoint( Buffer, v,
                            ( v - c ).GetNormal(),
                            Vector2( i / (Real)this->NumPoloidalSeg, j / (Real)this->NumToroidalSeg ) );

            if( i != this->NumPoloidalSeg ) {
                Buffer.AddIndex( Offset + this->NumToroidalSeg + 1 );
                Buffer.AddIndex( Offset );
                Buffer.AddIndex( Offset + this->NumToroidalSeg );
                Buffer.AddIndex( Offset + this->NumToroidalSeg + 1 );
                Buffer.AddIndex( Offset + 1 );
                Buffer.AddIndex( Offset );
            }
            Offset++;
        }
    }
}
コード例 #3
0
void LegacyRenderer::render(const ICamera<float>& camera, const PointLight<float>& light, const TriangleBuffer& buffer)
{
	const auto& positions = buffer.getPositions().get();// buffers[0].get();
	const auto& normals = buffer.getNormals().get();//buffers[1].get();

	if (positions.empty()) {
		return;
	}

	glEnable(GL_DEPTH_TEST);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);

	const auto& projectionMatrix = camera.getProjectionMatrix();
	const auto& modelviewMatrix = camera.getModelviewMatrix();;

	std::vector<float> lightPos = { light.getPos().getX(), light.getPos().getY(), light.getPos().getZ(), 1.0 };
	glLightfv(GL_LIGHT0, GL_POSITION, lightPos.data());
	glLightfv(GL_LIGHT0, GL_DIFFUSE, light.getDiffuse().toArray4().data());
//	glLightfv(GL_LIGHT0, GL_SPECULAR, light.getSpecular().toArray4().data());
	glLightfv(GL_LIGHT0, GL_AMBIENT, white);


	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glLoadMatrixf(projectionMatrix.toArray().data());

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glLoadMatrixf(modelviewMatrix.toArray().data());


	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, yellow);

	glEnableClientState(GL_VERTEX_ARRAY);
	glVertexPointer(3, GL_FLOAT, 0, positions.data());

	glEnableClientState(GL_NORMAL_ARRAY);
	glNormalPointer(GL_FLOAT, 0, normals.data());

	//glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(positions.size()) / 3);
	for (const auto& b : buffer.getBlocks()) {
		const auto& indices = b.getIndices();
		glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(indices.size()), GL_UNSIGNED_INT, indices.data());
	}

	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_NORMAL_ARRAY);

	glDisable(GL_LIGHTING);
	glDisable(GL_LIGHT0);
	glDisable(GL_DEPTH_TEST);

}
コード例 #4
0
void TorusKnotGenerator::addToTriangleBuffer(TriangleBuffer& buffer) const
{
	assert(mNumSegSection>0 && mNumSegCircle>0 && "Num seg and circle must be positive");
	assert(mRadius>0. && mSectionRadius>0. && "Radius and section radius must be positive");
	assert(mP>0 && mQ>0 && "p and q must be positive");

	buffer.rebaseOffset();
	buffer.estimateVertexCount((mNumSegCircle*mP+1)*(mNumSegSection+1));
	buffer.estimateIndexCount((mNumSegCircle*mP)*(mNumSegSection+1)*6);

	int offset = 0;

	for (int i = 0; i <= mNumSegCircle * mP;i++)
	{
		Real phi = Math::TWO_PI * i/(Real)mNumSegCircle;
		Real x0 = mRadius*(2 + cos(mQ*phi/(Real)mP)) * cos(phi) / 3.f;
		Real y0 = mRadius*sin(mQ*phi/(Real)mP) / 3.f;
		Real z0 = mRadius*(2 + cos(mQ*phi/(Real)mP)) * sin(phi) / 3.f;

		Real phi1 = Math::TWO_PI * (i+1)/(Real)mNumSegCircle;
		Real x1 = mRadius*(2 + cos(mQ*phi1/(Real)mP)) * cos(phi1) / 3.f;
		Real y1 = mRadius*sin(mQ*phi1/mP) / 3.f;
		Real z1 = mRadius*(2 + cos(mQ*phi1/(Real)mP)) * sin(phi1) / 3.f;

		Vector3 v0(x0,y0,z0);
		Vector3 v1(x1,y1,z1);
		Vector3 direction((v1-v0).normalisedCopy());
				
		Quaternion q = Utils::_computeQuaternion(direction);

		for (int j =0;j<=mNumSegSection;j++)
		{
			Real alpha = Math::TWO_PI *j/mNumSegSection;
			Vector3 vp = mSectionRadius*(q * Vector3(cos(alpha), sin(alpha),0));

			addPoint(buffer, v0+vp,
							 vp.normalisedCopy(),
							 Vector2(i/(Real)mNumSegCircle, j/(Real)mNumSegSection));

			if (i != mNumSegCircle * mP)
			{
				buffer.index(offset + mNumSegSection + 1);
				buffer.index(offset + mNumSegSection);
				buffer.index(offset);
				buffer.index(offset + mNumSegSection + 1);
				buffer.index(offset);
				buffer.index(offset + 1);
			}
			offset ++;
		}
	}
}
コード例 #5
0
 void SphereUVModifier::Modify(TriangleBuffer& Buffer)
 {
     for( VertexIterator VertIt = Buffer.GetVertices().begin() ; VertIt != Buffer.GetVertices().end() ; ++VertIt )
     {
         Vector3 NormalizedPos = VertIt->Position.GetNormal();
         Vector2 VecXZ(NormalizedPos.X,NormalizedPos.Z);
         VertIt->UV.X = Vector2::Unit_X().AngleTo(VecXZ) / MathTools::GetTwoPi();
         VertIt->UV.Y = ( MathTools::ATan(NormalizedPos.Y / VecXZ.Length()) + MathTools::GetHalfPi() ) / MathTools::GetPi();
     }
 }
コード例 #6
0
ファイル: ProceduralLathe.cpp プロジェクト: DavidEichmann/ode
//-----------------------------------------------------------------------
void Lathe::_latheBodyImpl(TriangleBuffer& buffer, const Shape* shapeToExtrude) const
{
	int numSegShape = shapeToExtrude->getSegCount();
	assert(numSegShape>1 && "Shape must contain at least two points");
	int offset =0;

	//int numSeg = mClosed?mNumSeg+1:mNumSeg;
	int numSeg = mNumSeg+1;
	buffer.rebaseOffset();
	buffer.estimateIndexCount(numSeg*numSegShape*6);
	buffer.estimateVertexCount((numSegShape+1)*(numSeg+1));
	
	Radian angleEnd(mAngleEnd);
	if (mAngleBegin>mAngleEnd)
		angleEnd+=(Radian)Math::TWO_PI;

	for (int i=0;i<numSeg;i++)
	{
		Radian angle;
		if (mClosed)
			angle = i/(Real)mNumSeg*Math::TWO_PI;
		else
			angle = mAngleBegin + i/(Real)mNumSeg*(angleEnd-mAngleBegin);
		Quaternion q;
		q.FromAngleAxis(angle,Vector3::UNIT_Y);

		for (int j=0;j<=numSegShape;j++)
		{
			const Vector2& v0 = shapeToExtrude->getPoint(j);
			Vector3 vp(v0.x,v0.y,0);
			const Vector2& vp2direction = shapeToExtrude->getAvgDirection(j);
			Vector2 vp2normal = vp2direction.perpendicular();
			Vector3 normal(vp2normal.x, vp2normal.y, 0);
			normal.normalise();
			if (shapeToExtrude->getOutSide() == SIDE_RIGHT)
				normal = -normal;

			addPoint(buffer, q*vp,
							 q*normal,
							 Vector2(i/(Real)mNumSeg, j/(Real)numSegShape));

			if (j <numSegShape && i <numSeg-1)
			{
				if (shapeToExtrude->getOutSide() == SIDE_RIGHT)
				{
					buffer.triangle(offset + numSegShape + 2, offset, offset + numSegShape + 1);
					buffer.triangle(offset + numSegShape + 2, offset + 1, offset);
				}
				else
				{
					buffer.triangle(offset + numSegShape + 2, offset + numSegShape + 1, offset);
					buffer.triangle(offset + numSegShape + 2, offset, offset + 1);
				}
			}
			offset ++;
		}
	}
}
コード例 #7
0
            void VertexNormalsModifier::Modify(TriangleBuffer& Buffer)
            {
                const IndexContainer& Indices = Buffer.GetIndices();
                VertexContainer& Vertices = Buffer.GetVertices();

                if( this->Compute == VertexNormalsModifier::CM_Triangle ) {
                    for( Whole Index = 0 ; Index < Indices.size() ; Index += 3 )
                    {
                        Vector3 v1 = Vertices[Indices[Index]].Position;
                        Vector3 v2 = Vertices[Indices[Index+1]].Position;
                        Vector3 v3 = Vertices[Indices[Index+2]].Position;
                        Vector3 VertNormal = (v2-v1).CrossProduct(v3-v1).GetNormal();
                        Vertices[Indices[Index]].Normal = VertNormal;
                        Vertices[Indices[Index+1]].Normal = VertNormal;
                        Vertices[Indices[Index+2]].Normal = VertNormal;
                    }
                }else if( this->Compute == VertexNormalsModifier::CM_Vertex ) {
                    std::vector< std::vector<Vector3> > TempNormals;
                    TempNormals.resize(Vertices.size());
                    for( Whole Index = 0 ; Index < Indices.size() ; Index += 3 )
                    {
                        Vector3 v1 = Vertices[Indices[Index]].Position;
                        Vector3 v2 = Vertices[Indices[Index+1]].Position;
                        Vector3 v3 = Vertices[Indices[Index+2]].Position;
                        Vector3 VertNormal = (v2-v1).CrossProduct(v3-v1);
                        TempNormals[Indices[Index]].push_back(VertNormal);
                        TempNormals[Indices[Index+1]].push_back(VertNormal);
                        TempNormals[Indices[Index+2]].push_back(VertNormal);
                    }
                    for( Whole CurrVertex = 0 ; CurrVertex < Vertices.size() ; ++CurrVertex )
                    {
                        Vector3 VertNormal(0.0,0.0,0.0);
                        for( Whole CurrNormal = 0 ; CurrNormal < TempNormals[CurrVertex].size() ; ++CurrNormal )
                        {
                            VertNormal += TempNormals[CurrVertex][CurrNormal];
                        }
                        Vertices[CurrVertex].Normal = VertNormal.GetNormal();
                    }
                }
            }
コード例 #8
0
            void BoxUVModifier::Modify(TriangleBuffer& Buffer)
            {
                static const Vector3 Directions[6] = { Vector3::Unit_X(), Vector3::Unit_Y(), Vector3::Unit_Z(), Vector3::Neg_Unit_X(), Vector3::Neg_Unit_Y(), Vector3::Neg_Unit_Z()  };

                for( VertexIterator VertIt = Buffer.GetVertices().begin() ; VertIt != Buffer.GetVertices().end() ; ++VertIt )
                {
                    Vector3 VertPos = VertIt->Position - this->BoxPosition;
                    if( !VertPos.IsZeroLength() ) {
                        //VertPos.Normalize();
                        VertPos.X /= ( this->BoxHalfExtents.X * 2.0 );
                        VertPos.Y /= ( this->BoxHalfExtents.Y * 2.0 );
                        VertPos.Z /= ( this->BoxHalfExtents.Z * 2.0 );
                        Vector3 VertNorm = VertIt->Normal;
                        Real MaxAxis = 0;
                        Integer PrincipalAxis = 0;
                        for( UInt8 AxisIndex = 0 ; AxisIndex < 6 ; ++AxisIndex )
                        {
                            if( Directions[AxisIndex].DotProduct(VertNorm) > MaxAxis ) {
                                MaxAxis = Directions[AxisIndex].DotProduct(VertNorm);
                                PrincipalAxis = AxisIndex;
                            }
                        }

                        Vector3 vX, vY;
                        if( PrincipalAxis % 3 == 1 ) {
                            vY = Vector3::Unit_X();
                        }else{
                            vY = Vector3::Unit_Y();
                        }
                        vX = Directions[PrincipalAxis].CrossProduct(vY);

                        Vector2 UVCoord( 0.5 - vX.DotProduct(VertPos), 0.5 - vY.DotProduct(VertPos) );
                        if( this->Mapping == BoxUVModifier::MT_Full ) {
                            VertIt->UV = UVCoord;
                        }else if( this->Mapping == BoxUVModifier::MT_Cross ) {
                            // Too lazy to think of a more elegant solution
                            switch( PrincipalAxis )
                            {
                                case 1:  VertIt->UV = Vector2( ( UVCoord.X + 2 ) / 4, ( UVCoord.Y + 1 ) / 3 );  break;  // 3,2
                                case 2:  VertIt->UV = Vector2( ( UVCoord.X + 1 ) / 4, UVCoord.Y / 3 );          break;  // 2,1
                                case 3:  VertIt->UV = Vector2( ( UVCoord.X + 3 ) / 4, ( UVCoord.Y + 1 ) / 3 );  break;  // 4,2
                                case 4:  VertIt->UV = Vector2( UVCoord.X / 4, ( UVCoord.Y + 1 ) / 3 );          break;  // 1,2
                                case 5:  VertIt->UV = Vector2( ( UVCoord.X + 1 ) / 4, ( UVCoord.Y + 2 ) / 3 );  break;  // 2,3
                                case 6:  VertIt->UV = Vector2( ( UVCoord.X + 1 ) / 4, ( UVCoord.Y + 1 ) / 3 );  break;  // 2,2
                            }
                        }else if( this->Mapping == BoxUVModifier::MT_Packed ) {
                            VertIt->UV = Vector2( ( UVCoord.X + PrincipalAxis % 3 ) / 3, ( UVCoord.Y + PrincipalAxis / 3 ) / 2 );
                        }
                    }
                }
            }
コード例 #9
0
void Lathe::addToTriangleBuffer(TriangleBuffer& buffer) const
	{
		assert( mShapeToExtrude && "Shape must not be null!");
		int numSegShape = mShapeToExtrude->getSegCount();
		assert(numSegShape>1 && "Shape must contain at least two points");
		int offset =0;

		buffer.rebaseOffset();
		buffer.estimateIndexCount(mNumSeg*numSegShape*6);
		buffer.estimateVertexCount((numSegShape+1)*(mNumSeg+1));

		for (int i=0;i<=mNumSeg;i++)
		{
			Real angle = i/(Real)mNumSeg*Math::TWO_PI;
			Quaternion q;
			q.FromAngleAxis((Radian)angle,Vector3::UNIT_Y);

			for (int j=0;j<=numSegShape;j++)
			{
				Vector2 v0 = mShapeToExtrude->getPoint(j);
				Vector3 vp(v0.x,v0.y,0);
				Vector2 vp2direction = mShapeToExtrude->getAvgDirection(j);
				Vector2 vp2normal = vp2direction.perpendicular();
				Vector3 normal(vp2normal.x, vp2normal.y, 0);
				normal.normalise();
				if (mShapeToExtrude->getOutSide() == SIDE_LEFT)
				{
					normal = -normal;
				}

				addPoint(buffer, q*vp,
								 q*normal,
								 Vector2(i/(Real)mNumSeg, j/(Real)numSegShape));

				if (j <numSegShape && i <mNumSeg)
				{
					buffer.index(offset + numSegShape + 2);
					buffer.index(offset);
					buffer.index(offset + numSegShape + 1);
					buffer.index(offset + numSegShape + 2);
					buffer.index(offset + 1);
					buffer.index(offset);
				}
				offset ++;
			}
		}
	}
コード例 #10
0
void SphereGenerator::addToTriangleBuffer(TriangleBuffer& buffer) const
{
	assert(mNumRings>0 && mNumSegments>0 && "Num seg must be positive");
	assert(mRadius>0 && "Radius must be positive");

	buffer.rebaseOffset();
	buffer.estimateVertexCount((mNumRings+1)*(mNumSegments+1));
	buffer.estimateIndexCount(mNumRings*(mNumSegments+1)*6);

	Real fDeltaRingAngle = (Math::PI / mNumRings);
	Real fDeltaSegAngle = (Math::TWO_PI / mNumSegments);
	int offset = 0;

	// Generate the group of rings for the sphere
	for(unsigned int ring = 0; ring <= mNumRings; ring++ ) {
		Real r0 = mRadius * sinf (ring * fDeltaRingAngle);
		Real y0 = mRadius * cosf (ring * fDeltaRingAngle);

		// Generate the group of segments for the current ring
		for(unsigned int seg = 0; seg <= mNumSegments; seg++) {
			Real x0 = r0 * sinf(seg * fDeltaSegAngle);
			Real z0 = r0 * cosf(seg * fDeltaSegAngle);

			// Add one vertex to the strip which makes up the sphere
			addPoint(buffer, Vector3(x0, y0, z0),
							 Vector3(x0, y0, z0).normalisedCopy(),
							 Vector2((Real) seg / (Real) mNumSegments, (Real) ring / (Real) mNumRings));

			if (ring != mNumRings) {
				// each vertex (except the last) has six indices pointing to it
				buffer.index(offset + mNumSegments + 1);
				buffer.index(offset);
				buffer.index(offset + mNumSegments);
				buffer.index(offset + mNumSegments + 1);
				buffer.index(offset + 1);
				buffer.index(offset);
				offset ++;
				}
		}; // end for seg
	} // end for ring
}
コード例 #11
0
ファイル: ProceduralLathe.cpp プロジェクト: DavidEichmann/ode
//-----------------------------------------------------------------------
void Lathe::_latheCapImpl(TriangleBuffer& buffer) const
{
		std::vector<int> indexBuffer;
		PointList pointList;

		buffer.rebaseOffset();

		Triangulator t;
		Shape shapeCopy;
		MultiShape multishapeCopy;
		
		if (mShapeToExtrude)
		{
			shapeCopy = *mShapeToExtrude;
			shapeCopy.close();
			t.setShapeToTriangulate(&shapeCopy);
		}
		else
		{
			multishapeCopy = *mMultiShapeToExtrude;
			multishapeCopy.close();
			t.setMultiShapeToTriangulate(mMultiShapeToExtrude);
		}
		t.triangulate(indexBuffer, pointList);
		buffer.estimateIndexCount(2*indexBuffer.size());
		buffer.estimateVertexCount(2*pointList.size());
		
		//begin cap
		buffer.rebaseOffset();
		Quaternion q;
		q.FromAngleAxis(mAngleBegin, Vector3::UNIT_Y);
		for (size_t j =0;j<pointList.size();j++)
		{
			Vector2 vp2 = pointList[j];
			Vector3 vp(vp2.x, vp2.y, 0);
			Vector3 normal = Vector3::UNIT_Z;				

			addPoint(buffer, q*vp,
				q*normal,
				vp2);
		}

		for (size_t i=0;i<indexBuffer.size()/3;i++)
		{				
			buffer.index(indexBuffer[i*3]);
			buffer.index(indexBuffer[i*3+1]);			
			buffer.index(indexBuffer[i*3+2]);
		}
		//end cap
		buffer.rebaseOffset();
		q.FromAngleAxis(mAngleEnd, Vector3::UNIT_Y);
		for (size_t j =0;j<pointList.size();j++)
		{
			Vector2 vp2 = pointList[j];
			Vector3 vp(vp2.x, vp2.y, 0);
			Vector3 normal = -Vector3::UNIT_Z;				

			addPoint(buffer, q*vp,
				q*normal,
				vp2);
		}

		for (size_t i=0;i<indexBuffer.size()/3;i++)
		{				
			buffer.index(indexBuffer[i*3]);
			buffer.index(indexBuffer[i*3+2]);
			buffer.index(indexBuffer[i*3+1]);
		}
}
コード例 #12
0
void CylinderGenerator::addToTriangleBuffer(TriangleBuffer& buffer) const
{
	assert(mHeight>0. && mRadius>0. && "height and radius must be positive");
	assert(mNumSegBase>0 && mNumSegHeight>0 && "Num seg must be positive integers");

	buffer.rebaseOffset();
	if (mCapped)
	{
		buffer.estimateVertexCount((mNumSegHeight+1)*(mNumSegBase+1)+2*(mNumSegBase+1)+2);
		buffer.estimateIndexCount(mNumSegHeight*(mNumSegBase+1)*6+6*mNumSegBase);		
	} else {
		buffer.estimateVertexCount((mNumSegHeight+1)*(mNumSegBase+1));
		buffer.estimateIndexCount(mNumSegHeight*(mNumSegBase+1)*6);
	}


	Real deltaAngle = (Math::TWO_PI / mNumSegBase);
	Real deltaHeight = mHeight/(Real)mNumSegHeight;
	int offset = 0;

	for (int i = 0; i <=mNumSegHeight; i++)
		for (int j = 0; j<=mNumSegBase; j++)
		{
			Real x0 = mRadius * cosf(j*deltaAngle);
			Real z0 = mRadius * sinf(j*deltaAngle);
			
			addPoint(buffer, Vector3(x0, i*deltaHeight, z0),
				Vector3(x0,0,z0).normalisedCopy(),
				Vector2(j/(Real)mNumSegBase, i/(Real)mNumSegHeight));

			if (i != mNumSegHeight) 
			{
				buffer.index(offset + mNumSegBase + 1);
				buffer.index(offset);
				buffer.index(offset + mNumSegBase);
				buffer.index(offset + mNumSegBase + 1);
				buffer.index(offset + 1);
				buffer.index(offset);
			}
			offset ++;
		}
	if (mCapped)
	{
		//low cap
		int centerIndex = offset;
		addPoint(buffer, Vector3::ZERO,
						 Vector3::NEGATIVE_UNIT_Y,
						 Vector2::UNIT_Y);
		offset++;
		for (int j=0;j<=mNumSegBase;j++)
		{
			Real x0 = mRadius * cosf(j*deltaAngle);
			Real z0 = mRadius * sinf(j*deltaAngle);

			addPoint(buffer, Vector3(x0, 0.0f, z0),
							Vector3::NEGATIVE_UNIT_Y,
							Vector2(j/(Real)mNumSegBase,0.0));
			if (j!=mNumSegBase)
			{
				buffer.index(centerIndex);
				buffer.index(offset);
				buffer.index(offset+1);
			}
			offset++;
		}
		// high cap
		centerIndex = offset;
		addPoint(buffer, Vector3(0,mHeight,0),
						 Vector3::UNIT_Y,
						 Vector2::ZERO);
		offset++;
		for (int j=0;j<=mNumSegBase;j++)
		{
			Real x0 = mRadius * cosf(j*deltaAngle);
			Real z0 = mRadius * sinf(j*deltaAngle);

			addPoint(buffer, Vector3(x0, mHeight, z0),
							 Vector3::UNIT_Y,
							 Vector2(j/(Real)mNumSegBase,1.));
			if (j!=mNumSegBase)
			{
				buffer.index(centerIndex);
				buffer.index(offset+1);
				buffer.index(offset);
			}
			offset++;
		}
	}
}
コード例 #13
0
            void ConeGenerator::AddToTriangleBuffer(TriangleBuffer& Buffer) const
            {
                Buffer.RebaseOffset();
                Buffer.EstimateVertexCount( ( this->NumSegHeight + 1 ) * ( this->NumSegCircle + 1 ) + this->NumSegCircle + 2 );
                Buffer.EstimateIndexCount( this->NumSegHeight * this->NumSegCircle * 6 + 3 * this->NumSegCircle );

                Real deltaAngle = ( MathTools::GetTwoPi() / this->NumSegCircle );
                Real deltaHeight = this->ConeHeight / (Real)this->NumSegHeight;
                Integer Offset = 0;

                Vector3 refNormal = Vector3( this->ConeRadius, this->ConeHeight, 0.f ).GetNormal();
                Quaternion q;

                for( Whole i = 0 ; i <= this->NumSegHeight ; i++ )
                {
                    Real r0 = this->ConeRadius * ( 1 - i / (Real)this->NumSegHeight );
                    for( Whole j = 0; j <= this->NumSegCircle ; j++ )
                    {
                        Real x0 = r0 * cosf( j * deltaAngle );
                        Real z0 = r0 * sinf( j * deltaAngle );

                        q.SetFromAxisAngle( -deltaAngle * j, Vector3::Unit_Y() );

                        this->AddPoint(Buffer, Vector3( x0, i * deltaHeight, z0 ),
                                       q * refNormal,
                                       Vector2( j / (Real)this->NumSegCircle, i / (Real)this->NumSegHeight ) );

                        if( i != this->NumSegHeight && j != this->NumSegCircle ) {
                            Buffer.AddIndex( Offset + this->NumSegCircle + 2 );
                            Buffer.AddIndex( Offset );
                            Buffer.AddIndex( Offset + this->NumSegCircle + 1 );
                            Buffer.AddIndex( Offset + this->NumSegCircle + 2 );
                            Buffer.AddIndex( Offset + 1 );
                            Buffer.AddIndex( Offset );
                        }

                        Offset++;
                    }
                }

                //low cap
                Integer CenterIndex = Offset;
                this->AddPoint(Buffer, Vector3(0.0,0.0,0.0),
                               Vector3::Neg_Unit_Y(),
                               Vector2(0.0,1.0) );
                Offset++;
                for( Whole j = 0 ; j <= this->NumSegCircle ; j++ )
                {
                    Real x0 = this->ConeRadius * cosf( j * deltaAngle );
                    Real z0 = this->ConeRadius * sinf( j * deltaAngle );

                    this->AddPoint(Buffer, Vector3(x0, 0.0f, z0),
                                   Vector3::Neg_Unit_Y(),
                                   Vector2( j / (Real)this->NumSegCircle, 0.0 ) );

                    if( j != this->NumSegCircle ) {
                        Buffer.AddIndex( CenterIndex );
                        Buffer.AddIndex( Offset );
                        Buffer.AddIndex( Offset + 1 );
                    }
                    Offset++;
                }
            }
コード例 #14
0
void DamBreakSample::demonstrate(const int width, const int height, const Crystal::Graphics::ICamera<float>& camera)
{
	this->width = width;
	this->height = height;
	this->rotationMatrix = camera.getRotationMatrix();
	glEnable(GL_DEPTH_TEST);

	interaction.simulate(1.0f / 60.0f);


	PointLight<float> light;
	light.setPos(Vector3d<float>(10.0f, 10.0f, -10.0f));
	light.setDiffuse(ColorRGBA<float>(1.0f, 0.0f, 0.0f, 1.0f));

	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	for (auto r : rigids) {
		const auto matrix = r->getTransformMatrix();
		auto p = r->getShape()->clone(r->getShape()->getId());
		p->transform(matrix);

		glViewport(0, 0, width, height);

		TriangleBuffer triangleBuffer;
		triangleBuffer.add(*p);
		//renderer.render(camera, lineBuffer);
		Material material;
		material.setAmbient(ColorRGBA<float>(0.2, 0.2, 0.2, 0.0));
		smoothRenderer.render(camera, triangleBuffer, light, material);

		glViewport(0, 0, fb.getWidth(), fb.getHeight());
		fb.bind();
		idRenderer.render(camera, triangleBuffer);
		fb.unbind();

		delete p;
	}

	glClearColor(0.7f, 0.7f, 0.7f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	for (auto r : rigids) {
		const auto matrix = r->getTransformMatrix();
		auto p = r->getShape()->clone(r->getShape()->getId());
		p->transform(matrix);

		glViewport(0, 0, width, height);

		TriangleBuffer triangleBuffer;
		triangleBuffer.add(*p);
		//renderer.render(camera, lineBuffer);
		Material material;
		smoothRenderer.render(camera, triangleBuffer, light, material);

		//glViewport(0, 0, fb.getWidth(), fb.getHeight());

		delete p;
	}

	glViewport(0, 0, width, height);

	const auto& particles = fluid->getParticles();
	float minPressure = +FLT_MAX;
	float maxPressure = -FLT_MAX;
	for (auto p : particles) {
		minPressure = std::min<float>(minPressure, p->getDensity());
		maxPressure = std::max<float>(maxPressure, p->getDensity());
	}
	colorMap.setMinMax(900.0f, 1400.0f);

	//colorMap.setMinMax(800.0f, 2000.0f);
	PointBuffer buffer;
	for (auto p : particles) {
		const auto pos = p->getPosition();
		auto color = colorMap.getColor(p->getDensity());
		color.setAlpha(0.5f);
		Crystal::Graphics::Point point(pos, color, 500.0f);
		buffer.add(point);
	}
	pointRenderer.render(camera, buffer);

}
コード例 #15
0
void CapsuleGenerator::addToTriangleBuffer(TriangleBuffer& buffer) const
{
	assert(mNumRings>0 && mNumSegments>0 && mNumSegHeight>0 && "Num seg must be positive integers");
	assert(mHeight>0. && mRadius>0. && "mHeight and radius must be positive");

	buffer.rebaseOffset();
	buffer.estimateVertexCount((2*mNumRings+2)*(mNumSegments+1) + (mNumSegHeight-1)*(mNumSegments+1));
	buffer.estimateIndexCount((2*mNumRings+1)*(mNumSegments+1)*6 + (mNumSegHeight-1)*(mNumSegments+1)*6);

	Real fDeltaRingAngle = (Math::HALF_PI / mNumRings);
	Real fDeltaSegAngle = (Math::TWO_PI / mNumSegments);

	Real sphereRatio = mRadius / (2 * mRadius + mHeight);
	Real cylinderRatio = mHeight / (2 * mRadius + mHeight);
	int offset = 0;
	// Top half sphere

	// Generate the group of rings for the sphere
	for(unsigned int ring = 0; ring <= mNumRings; ring++ ) 
	{
		Real r0 = mRadius * sinf ( ring * fDeltaRingAngle);
		Real y0 = mRadius * cosf (ring * fDeltaRingAngle);

		// Generate the group of segments for the current ring
		for(unsigned int seg = 0; seg <= mNumSegments; seg++) 
		{
			Real x0 = r0 * cosf(seg * fDeltaSegAngle);
			Real z0 = r0 * sinf(seg * fDeltaSegAngle);

			// Add one vertex to the strip which makes up the sphere
			addPoint(buffer, Vector3(x0, 0.5f*mHeight + y0, z0),
							 Vector3(x0, y0, z0).normalisedCopy(),
							 Vector2((Real) seg / (Real) mNumSegments, (Real) ring / (Real) mNumRings * sphereRatio));
			
			// each vertex (except the last) has six indices pointing to it
			buffer.index(offset + mNumSegments + 1);
			buffer.index(offset + mNumSegments);
			buffer.index(offset);
			buffer.index(offset + mNumSegments + 1);
			buffer.index(offset);
			buffer.index(offset + 1);
			
			offset ++;
		} // end for seg
	} // end for ring

	// Cylinder part
	Real deltaAngle = (Math::TWO_PI / mNumSegments);
	Real deltamHeight = mHeight/(Real)mNumSegHeight;

	for (unsigned short i = 1; i < mNumSegHeight; i++)
		for (unsigned short j = 0; j<=mNumSegments; j++)
		{
			Real x0 = mRadius * cosf(j*deltaAngle);
			Real z0 = mRadius * sinf(j*deltaAngle);

			addPoint(buffer, Vector3(x0, 0.5f*mHeight-i*deltamHeight, z0),
							 Vector3(x0,0,z0).normalisedCopy(),
							 Vector2(j/(Real)mNumSegments, i/(Real)mNumSegHeight * cylinderRatio + sphereRatio));

			buffer.index(offset + mNumSegments + 1);
			buffer.index(offset + mNumSegments);
			buffer.index(offset);
			buffer.index(offset + mNumSegments + 1);
			buffer.index(offset);
			buffer.index(offset + 1);

			offset ++;
		}

	// Bottom half sphere

	// Generate the group of rings for the sphere
	for(unsigned int ring = 0; ring <= mNumRings; ring++) 
	{
		Real r0 = mRadius * sinf (Math::HALF_PI + ring * fDeltaRingAngle);
		Real y0 =  mRadius * cosf (Math::HALF_PI + ring * fDeltaRingAngle);

		// Generate the group of segments for the current ring
		for(unsigned int seg = 0; seg <= mNumSegments; seg++) 
		{
			Real x0 = r0 * cosf(seg * fDeltaSegAngle);
			Real z0 = r0 * sinf(seg * fDeltaSegAngle);

			// Add one vertex to the strip which makes up the sphere
			addPoint(buffer, Vector3(x0, -0.5f*mHeight + y0, z0), 
							 Vector3(x0, y0, z0).normalisedCopy(), 
							 Vector2((Real) seg / (Real) mNumSegments, (Real) ring / (Real) mNumRings*sphereRatio + cylinderRatio + sphereRatio));
			
			if (ring != mNumRings) 
			{
				// each vertex (except the last) has six indices pointing to it
				buffer.index(offset + mNumSegments + 1);
				buffer.index(offset + mNumSegments);
				buffer.index(offset);
				buffer.index(offset + mNumSegments + 1);
				buffer.index(offset);
				buffer.index(offset + 1);
			}
			offset ++;
		} // end for seg
	} // end for ring		
}
コード例 #16
0
void IcoSphereGenerator::addToTriangleBuffer(TriangleBuffer& buffer) const
{
	assert(mRadius>0. && "Radius must me positive");
	assert(mNumIterations>0 && "numIterations must be positive");

	std::vector<Vector3> vertices;
	int offset = 0;

	/// Step 1 : Generate icosahedron
	Real phi = .5f*(1.f+sqrt(5.f));
	Real invnorm = 1/sqrt(phi*phi+1);

	vertices.push_back(invnorm*Vector3(-1,  phi, 0));//0
	vertices.push_back(invnorm*Vector3( 1,  phi, 0));//1
	vertices.push_back(invnorm*Vector3(0,   1,  -phi));//2
	vertices.push_back(invnorm*Vector3(0,   1,   phi));//3
	vertices.push_back(invnorm*Vector3(-phi,0,  -1));//4
	vertices.push_back(invnorm*Vector3(-phi,0,   1));//5
	vertices.push_back(invnorm*Vector3( phi,0,  -1));//6
	vertices.push_back(invnorm*Vector3( phi,0,   1));//7
	vertices.push_back(invnorm*Vector3(0,   -1, -phi));//8
	vertices.push_back(invnorm*Vector3(0,   -1,  phi));//9
	vertices.push_back(invnorm*Vector3(-1,  -phi,0));//10
	vertices.push_back(invnorm*Vector3( 1,  -phi,0));//11

	int firstFaces[] = {0,1,2,
						0,3,1,
						0,4,5,
						1,7,6,
						1,6,2,
						1,3,7,
						0,2,4,
						0,5,3,
						2,6,8,
						2,8,4,
						3,5,9,
						3,9,7,
						11,6,7,
						10,5,4,
						10,4,8,
						10,9,5,
						11,8,6,
						11,7,9,
						10,8,11,
						10,11,9
					   };

	std::vector<int> faces(firstFaces, firstFaces + sizeof(firstFaces)/sizeof(*firstFaces));
	int size = 60;

	/// Step 2 : tessellate
	for (unsigned short iteration = 0; iteration<mNumIterations; iteration++)
	{
		size*=4;
		std::vector<int> newFaces;
		newFaces.clear();
		//newFaces.resize(size);
		for (int i=0; i<size/12; i++)
		{
			int i1 = faces[i*3];
			int i2 = faces[i*3+1];
			int i3 = faces[i*3+2];
			int i12 = vertices.size();
			int i23 = i12+1;
			int i13 = i12+2;
			Vector3 v1 = vertices[i1];
			Vector3 v2 = vertices[i2];
			Vector3 v3 = vertices[i3];
			//make 1 vertice at the center of each edge and project it onto the sphere
			vertices.push_back((v1+v2).normalisedCopy());
			vertices.push_back((v2+v3).normalisedCopy());
			vertices.push_back((v1+v3).normalisedCopy());
			//now recreate indices
			newFaces.push_back(i1);
			newFaces.push_back(i12);
			newFaces.push_back(i13);
			newFaces.push_back(i2);
			newFaces.push_back(i23);
			newFaces.push_back(i12);
			newFaces.push_back(i3);
			newFaces.push_back(i13);
			newFaces.push_back(i23);
			newFaces.push_back(i12);
			newFaces.push_back(i23);
			newFaces.push_back(i13);
		}
		faces.swap(newFaces);
	}

	/// Step 3 : generate texcoords
	std::vector<Vector2> texCoords;
	for (unsigned short i=0;i<vertices.size();i++)
	{
		const Vector3& vec = vertices[i];
		Real u, v;
		Real r0 = sqrtf(vec.x*vec.x+vec.z*vec.z);
		Real alpha;
		alpha = atan2f(vec.z,vec.x);
		u = alpha/Math::TWO_PI+.5f;
		v = atan2f(vec.y, r0)/Math::PI + .5f;
		texCoords.push_back(Vector2(u,v));
	}

	/// Step 4 : fix texcoords
	// find vertices to split
	std::vector<int> indexToSplit;

	for (unsigned int i=0;i<faces.size()/3;i++)
	{
		Vector2& t0 = texCoords[faces[i*3+0]];
		Vector2& t1 = texCoords[faces[i*3+1]];
		Vector2& t2 = texCoords[faces[i*3+2]];
		if (Math::Abs(t2.x-t0.x)>0.5)
		{
			if (t0.x<0.5)
				indexToSplit.push_back(faces[i*3]);
			else
				indexToSplit.push_back(faces[i*3+2]);
		}
		if (Math::Abs(t1.x-t0.x)>0.5)
		{
			if (t0.x<0.5)
				indexToSplit.push_back(faces[i*3]);
			else
				indexToSplit.push_back(faces[i*3+1]);
		}
		if (Math::Abs(t2.x-t1.x)>0.5)
		{
			if (t1.x<0.5)
				indexToSplit.push_back(faces[i*3+1]);
			else
				indexToSplit.push_back(faces[i*3+2]);
		}
	}

	//split vertices
	for (unsigned short i=0;i<indexToSplit.size();i++)
	{
		int index = indexToSplit[i];
		//duplicate vertex
		Vector3 v = vertices[index];
		Vector2 t = texCoords[index] + Vector2::UNIT_X;
		vertices.push_back(v);
		texCoords.push_back(t);
		int newIndex = vertices.size()-1;
		//reassign indices
		for (unsigned short j=0;j<faces.size();j++)
		{
			if (faces[j]==index)
			{
				int index1 = faces[(j+1)%3+(j/3)*3];
				int index2 = faces[(j+2)%3+(j/3)*3];
				if ((texCoords[index1].x>0.5) || (texCoords[index2].x>0.5))
				{
					faces[j] = newIndex;
				}
			}
		}
	}
	
	/// Step 5 : realize
	buffer.rebaseOffset();
	buffer.estimateVertexCount(vertices.size());
	buffer.estimateIndexCount(size);

	for (unsigned short i=0; i<vertices.size(); i++)
	{
		addPoint(buffer, mRadius*vertices[i],
						 vertices[i],//note : vertices are already normalised
						 Vector2(texCoords[i].x,texCoords[i].y));
	}
	for (unsigned short i=0; i<size; i++)
	{
		buffer.index(offset+faces[i]);
	}
	offset+=vertices.size();
}
コード例 #17
0
void PlaneGenerator::addToTriangleBuffer(TriangleBuffer& buffer) const
{
	assert(mNumSegX>0 && mNumSegY>0 && "Num seg must be positive");
	assert(!mNormal.isZeroLength() && "Normal must not be null");
	assert(mSizeX>0. && mSizeY>0. && "Size must be positive");
	
	buffer.rebaseOffset();
	buffer.estimateVertexCount((mNumSegX+1)*(mNumSegY+1));
	buffer.estimateIndexCount(mNumSegX*mNumSegY*6);
	int offset = 0;

	Vector3 vX = mNormal.perpendicular();
	Vector3 vY = mNormal.crossProduct(vX);
	Vector3 delta1 = mSizeX / (Real)mNumSegX * vX;
	Vector3 delta2 = mSizeY / (Real)mNumSegY * vY;
	// build one corner of the square
	Vector3 orig = -0.5f*mSizeX*vX - 0.5f*mSizeY*vY;

	for (unsigned short i1 = 0; i1<=mNumSegX; i1++)
		for (unsigned short i2 = 0; i2<=mNumSegY; i2++)
		{
			addPoint(buffer, orig+i1*delta1+i2*delta2,
						     mNormal,
							 Vector2(i1/(Real)mNumSegX, i2/(Real)mNumSegY));
		}

	bool reverse = false;
	if (delta1.crossProduct(delta2).dotProduct(mNormal)>0)
		reverse= true;
	for (unsigned short n1 = 0; n1<mNumSegX; n1++)
	{
		for (unsigned short n2 = 0; n2<mNumSegY; n2++)
		{
			if (reverse)
			{
				buffer.index(offset+0);
				buffer.index(offset+(mNumSegY+1));
				buffer.index(offset+1);
				buffer.index(offset+1);
				buffer.index(offset+(mNumSegY+1));
				buffer.index(offset+(mNumSegY+1)+1);
			}
			else
			{
				buffer.index(offset+0);
				buffer.index(offset+1);
				buffer.index(offset+(mNumSegY+1));
				buffer.index(offset+1);
				buffer.index(offset+(mNumSegY+1)+1);
				buffer.index(offset+(mNumSegY+1));
			}
			offset++;
		}
		offset++;
	}
}
コード例 #18
0
void CapsuleGenerator::addToTriangleBuffer(TriangleBuffer& buffer) const
{
	assert(numRings>0 && numSegments>0 && numSegHeight>0 && "Num seg must be positive integers");
	assert(height>0. && radius>0. && "Height and radius must be positive");

	buffer.rebaseOffset();
	buffer.estimateVertexCount((2*numRings+2)*(numSegments+1) + (numSegHeight-1)*(numSegments+1));
	buffer.estimateIndexCount((2*numRings+1)*(numSegments+1)*6 + (numSegHeight-1)*(numSegments+1)*6);

	Ogre::Real fDeltaRingAngle = (Ogre::Math::HALF_PI / numRings);
	Ogre::Real fDeltaSegAngle = (Ogre::Math::TWO_PI / numSegments);

	Ogre::Real sphereRatio = radius / (2 * radius + height);
	Ogre::Real cylinderRatio = height / (2 * radius + height);
	int offset = 0;
	// Top half sphere

	// Generate the group of rings for the sphere
	for(unsigned int ring = 0; ring <= numRings; ring++ ) 
	{
		Ogre::Real r0 = radius * sinf ( ring * fDeltaRingAngle);
		Ogre::Real y0 = radius * cosf (ring * fDeltaRingAngle);

		// Generate the group of segments for the current ring
		for(unsigned int seg = 0; seg <= numSegments; seg++) 
		{
			Ogre::Real x0 = r0 * cosf(seg * fDeltaSegAngle);
			Ogre::Real z0 = r0 * sinf(seg * fDeltaSegAngle);

			// Add one vertex to the strip which makes up the sphere
			buffer.position( x0, 0.5*height + y0, z0);
			if (enableNormals)
				buffer.normal(Ogre::Vector3(x0, y0, z0).normalisedCopy());
			for (unsigned int tc=0;tc<numTexCoordSet;tc++)
				buffer.textureCoord((Ogre::Real) seg / (Ogre::Real) numSegments * uTile, (Ogre::Real) ring / (Ogre::Real) numRings * vTile * sphereRatio);
			
			// each vertex (except the last) has six indices pointing to it
			buffer.index(offset + numSegments + 1);
			buffer.index(offset + numSegments);
			buffer.index(offset);
			buffer.index(offset + numSegments + 1);
			buffer.index(offset);
			buffer.index(offset + 1);
			
			offset ++;
		} // end for seg
	} // end for ring

	// Cylinder part
	Ogre::Real deltaAngle = (Ogre::Math::TWO_PI / numSegments);
	Ogre::Real deltaHeight = height/(Ogre::Real)numSegHeight;

	for (int i = 1; i < numSegHeight; i++)
		for (int j = 0; j<=numSegments; j++)
		{
			Ogre::Real x0 = radius * cosf(j*deltaAngle);
			Ogre::Real z0 = radius * sinf(j*deltaAngle);
			buffer.position(x0, 0.5*height-i*deltaHeight, z0);
			buffer.normal(Ogre::Vector3(x0,0,z0).normalisedCopy());
			buffer.textureCoord(j/(Ogre::Real)numSegments*uTile, i/(Ogre::Real)numSegHeight*vTile * cylinderRatio + sphereRatio);

			buffer.index(offset + numSegments + 1);
			buffer.index(offset + numSegments);
			buffer.index(offset);
			buffer.index(offset + numSegments + 1);
			buffer.index(offset);
			buffer.index(offset + 1);

			offset ++;
		}

	// Bottom half sphere

	// Generate the group of rings for the sphere
	for(unsigned int ring = 0; ring <= numRings; ring++) 
	{
		Ogre::Real r0 = radius * sinf (Ogre::Math::HALF_PI + ring * fDeltaRingAngle);
		Ogre::Real y0 =  radius * cosf (Ogre::Math::HALF_PI + ring * fDeltaRingAngle);

		// Generate the group of segments for the current ring
		for(unsigned int seg = 0; seg <= numSegments; seg++) 
		{
			Ogre::Real x0 = r0 * cosf(seg * fDeltaSegAngle);
			Ogre::Real z0 = r0 * sinf(seg * fDeltaSegAngle);

			// Add one vertex to the strip which makes up the sphere
			buffer.position( x0, -0.5*height + y0, z0);
			if (enableNormals)
				buffer.normal(Ogre::Vector3(x0, y0, z0).normalisedCopy());
			for (unsigned int tc=0;tc<numTexCoordSet;tc++)
				buffer.textureCoord((Ogre::Real) seg / (Ogre::Real) numSegments * uTile, (Ogre::Real) ring / (Ogre::Real) numRings * vTile*sphereRatio + cylinderRatio + sphereRatio);

			if (ring != numRings) 
			{
				// each vertex (except the last) has six indices pointing to it
				buffer.index(offset + numSegments + 1);
				buffer.index(offset + numSegments);
				buffer.index(offset);
				buffer.index(offset + numSegments + 1);
				buffer.index(offset);
				buffer.index(offset + 1);
			}
			offset ++;
		} // end for seg
	} // end for ring		
}
コード例 #19
0
	//-----------------------------------------------------------------------
	void Extruder::_extrudeBodyImpl(TriangleBuffer& buffer, const Shape* shapeToExtrude) const
	{
		assert(mExtrusionPath && shapeToExtrude && "Shape and Path must not be null!");
		unsigned int numSegPath = mExtrusionPath->getSegCount();
		unsigned int numSegShape = shapeToExtrude->getSegCount();
		assert(numSegPath>0 && numSegShape>0 && "Shape and path must contain at least two points");
				
		Real totalPathLength = mExtrusionPath->getTotalLength();
		Real totalShapeLength = shapeToExtrude->getTotalLength();
		
		// Merge shape and path with tracks
		Ogre::Real lineicPos=0.;
		Path path = *mExtrusionPath;
		if (mRotationTrack)
			path = path.mergeKeysWithTrack(*mRotationTrack);
		if (mScaleTrack)
			path = path.mergeKeysWithTrack(*mScaleTrack);
		if (mPathTextureTrack)
			path = path.mergeKeysWithTrack(*mPathTextureTrack);
		numSegPath = path.getSegCount();
		Shape shape = *shapeToExtrude;
		if (mShapeTextureTrack)
			shape = shape.mergeKeysWithTrack(*mShapeTextureTrack);
		numSegShape = shape.getSegCount();
		
		// Estimate vertex and index count
		buffer.rebaseOffset();
		buffer.estimateIndexCount(numSegShape*numSegPath*6);
		buffer.estimateVertexCount((numSegShape+1)*(numSegPath+1));
				
		Vector3 oldup;
		for (unsigned int i = 0; i <= numSegPath; ++i)
		{
			Vector3 v0 = path.getPoint(i);
			Vector3 direction = path.getAvgDirection(i);

			Quaternion q = Utils::_computeQuaternion(direction);
						
			Radian angle = (q*Vector3::UNIT_Y).angleBetween(oldup);
			if (i>0 && angle>(Radian)Math::HALF_PI/2.)
			{
				q = Utils::_computeQuaternion(direction, oldup);
			}
			oldup = q * Vector3::UNIT_Y;

			Real scale=1.;
					
			if (i>0) lineicPos += (v0-path.getPoint(i-1)).length();
			
			// Get the values of angle and scale
			if (mRotationTrack)
			{
				Real angle;
				angle = mRotationTrack->getValue(lineicPos, lineicPos / totalPathLength, i);

				q = q*Quaternion((Radian)angle, Vector3::UNIT_Z);
			}
			if (mScaleTrack)
			{
				scale = mScaleTrack->getValue(lineicPos, lineicPos / totalPathLength, i);
			}
			Real uTexCoord;
			if (mPathTextureTrack)
				uTexCoord = mPathTextureTrack->getValue(lineicPos, lineicPos / totalPathLength, i);
			else
				uTexCoord = lineicPos / totalPathLength;
			
			Real lineicShapePos = 0.;
			// Insert new points
			for (unsigned int j =0; j <= numSegShape; ++j)
			{				
				Vector2 vp2 = shapeToExtrude->getPoint(j);
				//Vector2 vp2direction = shapeToExtrude->getAvgDirection(j);
				Vector2 vp2normal = shapeToExtrude->getAvgNormal(j);
				Vector3 vp(vp2.x, vp2.y, 0);
				Vector3 normal(vp2normal.x, vp2normal.y, 0);							
				buffer.rebaseOffset();
				Vector3 newPoint = v0+q*(scale*vp);				
				if (j>0)
					lineicShapePos += (vp2 - shape.getPoint(j-1)).length();
				Real vTexCoord;
				if (mShapeTextureTrack)
					vTexCoord = mShapeTextureTrack->getValue(lineicShapePos, lineicShapePos / totalShapeLength, j);
				else
					vTexCoord = lineicShapePos / totalShapeLength;				

				addPoint(buffer, newPoint,
					q*normal, 
					Vector2(uTexCoord, vTexCoord));

				if (j <numSegShape && i <numSegPath)
				{		
					if (shapeToExtrude->getOutSide() == SIDE_LEFT)
					{
						buffer.triangle(numSegShape + 1, numSegShape + 2, 0);
						buffer.triangle(0, numSegShape + 2, 1);
					}
					else 
					{
						buffer.triangle(numSegShape + 2, numSegShape + 1, 0);
						buffer.triangle(numSegShape + 2, 0, 1);
					}
				}			
			}			
		}			
	}
コード例 #20
0
	//-----------------------------------------------------------------------
	void Extruder::_extrudeCapImpl(TriangleBuffer& buffer) const
	{
		std::vector<int> indexBuffer;
		PointList pointList;

		buffer.rebaseOffset();

		Triangulator t;
		if (mShapeToExtrude)
			t.setShapeToTriangulate(mShapeToExtrude);
		else
			t.setMultiShapeToTriangulate(mMultiShapeToExtrude);
		t.triangulate(indexBuffer, pointList);
		buffer.estimateIndexCount(2*indexBuffer.size());
		buffer.estimateVertexCount(2*pointList.size());


		//begin cap
		buffer.rebaseOffset();
		Quaternion qBegin = Utils::_computeQuaternion(mExtrusionPath->getDirectionAfter(0));
		if (mRotationTrack)
		{
			Real angle = mRotationTrack->getFirstValue();
			qBegin = qBegin*Quaternion((Radian)angle, Vector3::UNIT_Z);
		}	
		Real scaleBegin=1.;
		if (mScaleTrack)
			scaleBegin = mScaleTrack->getFirstValue();
		for (size_t j =0;j<pointList.size();j++)
		{
			Vector2 vp2 = pointList[j];
			Vector3 vp(vp2.x, vp2.y, 0);
			Vector3 normal = -Vector3::UNIT_Z;				

			Vector3 newPoint = mExtrusionPath->getPoint(0)+qBegin*(scaleBegin*vp);
			addPoint(buffer, newPoint,
				qBegin*normal,
				vp2);
		}

		for (size_t i=0;i<indexBuffer.size()/3;i++)
		{				
			buffer.index(indexBuffer[i*3]);
			buffer.index(indexBuffer[i*3+2]);
			buffer.index(indexBuffer[i*3+1]);
		}

		// end cap
		buffer.rebaseOffset();
		Quaternion qEnd = Utils::_computeQuaternion(mExtrusionPath->getDirectionBefore(mExtrusionPath->getSegCount()));
		if (mRotationTrack)
		{
			Real angle = mRotationTrack->getLastValue();
			qEnd = qEnd*Quaternion((Radian)angle, Vector3::UNIT_Z);
		}			
		Real scaleEnd=1.;
		if (mScaleTrack)
			scaleEnd = mScaleTrack->getLastValue();

		for (size_t j =0;j<pointList.size();j++)
		{
			Vector2 vp2 = pointList[j];
			Vector3 vp(vp2.x, vp2.y, 0);
			Vector3 normal = Vector3::UNIT_Z;				

			Vector3 newPoint = mExtrusionPath->getPoint(mExtrusionPath->getSegCount())+qEnd*(scaleEnd*vp);
			addPoint(buffer, newPoint,
				qEnd*normal,
				vp2);
		}

		for (size_t i=0;i<indexBuffer.size()/3;i++)
		{				
			buffer.index(indexBuffer[i*3]);
			buffer.index(indexBuffer[i*3+1]);
			buffer.index(indexBuffer[i*3+2]);
		}

	}
コード例 #21
0
            void TubeGenerator::AddToTriangleBuffer(TriangleBuffer& Buffer) const
            {
                Buffer.RebaseOffset();
                Buffer.EstimateVertexCount( ( this->NumSegHeight + 1 ) * ( this->NumSegCircle + 1 ) * 2 + ( this->NumSegCircle + 1 ) * 4 );
                Buffer.EstimateIndexCount( 6 * ( this->NumSegCircle + 1 ) * this->NumSegHeight * 2 + 6 * this->NumSegCircle * 2 );

                Real deltaAngle = ( MathTools::GetTwoPi() / this->NumSegCircle );
                Real deltaHeight = this->TubeHeight / (Real)this->NumSegHeight;
                int Offset = 0;

                for( Whole i = 0 ; i <= this->NumSegHeight ; ++i )
                {
                    for( Whole j = 0 ; j <= this->NumSegCircle ; ++j )
                    {
                        Real x0 = this->TubeOuterRadius * cosf( j * deltaAngle );
                        Real z0 = this->TubeOuterRadius * sinf( j * deltaAngle );
                        this->AddPoint(Buffer, Vector3( x0, i * deltaHeight, z0 ),
                                       Vector3( x0, 0, z0 ).GetNormal(),
                                       Vector2( j / (Real)this->NumSegCircle, i / (Real)this->NumSegHeight ) );

                        if( i != this->NumSegHeight ) {
                            Buffer.AddIndex( Offset + this->NumSegCircle + 1 );
                            Buffer.AddIndex( Offset );
                            Buffer.AddIndex( Offset + this->NumSegCircle );
                            Buffer.AddIndex( Offset + this->NumSegCircle + 1 );
                            Buffer.AddIndex( Offset + 1 );
                            Buffer.AddIndex( Offset );
                        }
                        Offset++;
                    }
                }

                for( Whole i = 0 ; i <= this->NumSegHeight ; ++i )
                {
                    for( Whole j = 0 ; j<= this->NumSegCircle ; ++j )
                    {
                        Real x0 = this->TubeInnerRadius * cosf( j * deltaAngle );
                        Real z0 = this->TubeInnerRadius * sinf( j * deltaAngle );
                        this->AddPoint(Buffer, Vector3( x0, i * deltaHeight, z0 ),
                                       -Vector3( x0, 0, z0 ).GetNormal(),
                                       Vector2( j / (Real)this->NumSegCircle, i / (Real)this->NumSegHeight ) );

                        if( i != this->NumSegHeight ) {
                            Buffer.AddIndex( Offset + this->NumSegCircle + 1 );
                            Buffer.AddIndex( Offset + this->NumSegCircle );
                            Buffer.AddIndex( Offset );
                            Buffer.AddIndex( Offset + this->NumSegCircle + 1 );
                            Buffer.AddIndex( Offset );
                            Buffer.AddIndex( Offset + 1);
                        }
                        Offset++;
                    }
                }

                //low cap
                for( Whole j = 0 ; j <= this->NumSegCircle ; ++j )
                {
                    Real x0 = this->TubeInnerRadius * cosf( j * deltaAngle );
                    Real z0 = this->TubeInnerRadius * sinf( j * deltaAngle );

                    this->AddPoint(Buffer, Vector3( x0, 0.0f, z0 ),
                                   Vector3::Neg_Unit_Y(),
                                   Vector2( j / (Real)this->NumSegCircle, 1. ) );

                    x0 = this->TubeOuterRadius * cosf( j * deltaAngle );
                    z0 = this->TubeOuterRadius * sinf( j * deltaAngle );

                    this->AddPoint(Buffer, Vector3( x0, 0.0f, z0 ),
                                   Vector3::Neg_Unit_Y(),
                                   Vector2( j / (Real)this->NumSegCircle, 0. ) );

                    if( j != this->NumSegCircle ) {
                        Buffer.AddIndex( Offset );
                        Buffer.AddIndex( Offset + 1 );
                        Buffer.AddIndex( Offset + 3 );
                        Buffer.AddIndex( Offset + 2 );
                        Buffer.AddIndex( Offset );
                        Buffer.AddIndex( Offset + 3 );
                    }
                    Offset += 2;
                }


                //high cap
                for( Whole j = 0 ; j <= this->NumSegCircle ; ++j )
                {
                    Real x0 = this->TubeInnerRadius * cosf( j * deltaAngle );
                    Real z0 = this->TubeInnerRadius * sinf( j * deltaAngle );

                    this->AddPoint(Buffer, Vector3( x0, this->TubeHeight, z0 ),
                                   Vector3::Unit_Y(),
                                   Vector2( j / (Real)this->NumSegCircle, 0. ) );

                    x0 = this->TubeOuterRadius * cosf( j * deltaAngle );
                    z0 = this->TubeOuterRadius * sinf( j * deltaAngle );

                    this->AddPoint(Buffer, Vector3( x0, this->TubeHeight, z0 ),
                                   Vector3::Unit_Y(),
                                   Vector2( j / (Real)this->NumSegCircle, 1. ) );

                    if( j != this->NumSegCircle ) {
                        Buffer.AddIndex( Offset + 1 );
                        Buffer.AddIndex( Offset );
                        Buffer.AddIndex( Offset + 3 );
                        Buffer.AddIndex( Offset );
                        Buffer.AddIndex( Offset + 2 );
                        Buffer.AddIndex( Offset + 3 );
                    }
                    Offset += 2;
                }
            }
コード例 #22
0
void PlaneGenerator::addToTriangleBuffer(TriangleBuffer& buffer) const
{
	assert(numSegX>0 && numSegY>0 && "Num seg must be positive");
	assert(!normal.isZeroLength() && "Normal must not be null");
	assert(sizeX>0. && sizeY>0. && "Size must be positive");
	
	buffer.rebaseOffset();
	buffer.estimateVertexCount((numSegX+1)*(numSegY+1));
	buffer.estimateIndexCount(numSegX*numSegY*6);
	int offset = 0;

	Ogre::Vector3 vX = normal.perpendicular();
	Ogre::Vector3 vY = normal.crossProduct(vX);
	Ogre::Vector3 delta1 = sizeX / numSegX * vX;
	Ogre::Vector3 delta2 = sizeY / numSegY * vY;
	// build one corner of the square
	Ogre::Vector3 orig = -0.5*sizeX*vX - 0.5*sizeY*vY;

	for (int i1 = 0; i1<=numSegX; i1++)
		for (int i2 = 0; i2<=numSegY; i2++)
		{
			buffer.position(orig+i1*delta1+i2*delta2+position);
			buffer.textureCoord(i1/(Ogre::Real)numSegX*uTile, i2/(Ogre::Real)numSegY*vTile);
			buffer.normal(normal);
		}

	bool reverse = false;
	if (delta1.crossProduct(delta2).dotProduct(normal)>0)
		reverse= true;
	for (int n1 = 0; n1<numSegX; n1++)
	{
		for (int n2 = 0; n2<numSegY; n2++)
		{
			if (reverse)
			{
				buffer.index(offset+0);
				buffer.index(offset+(numSegY+1));
				buffer.index(offset+1);
				buffer.index(offset+1);
				buffer.index(offset+(numSegY+1));
				buffer.index(offset+(numSegY+1)+1);
			}
			else
			{
				buffer.index(offset+0);
				buffer.index(offset+1);
				buffer.index(offset+(numSegY+1));
				buffer.index(offset+1);
				buffer.index(offset+(numSegY+1)+1);
				buffer.index(offset+(numSegY+1));
			}
			offset++;
		}
		offset++;
	}
}
コード例 #23
0
void TubeGenerator::addToTriangleBuffer(TriangleBuffer& buffer) const
{
	buffer.rebaseOffset();
	buffer.estimateVertexCount((mNumSegHeight+1)*(mNumSegBase+1)*2+(mNumSegBase+1)*4);
	buffer.estimateIndexCount(6*(mNumSegBase+1)*mNumSegHeight*2+6*mNumSegBase*2);

	Real deltaAngle = (Math::TWO_PI / mNumSegBase);
	Real deltaHeight = mHeight/(Real)mNumSegHeight;
	int offset = 0;

	for (unsigned int i = 0; i <=mNumSegHeight; i++)
		for (unsigned int j = 0; j<=mNumSegBase; j++)
		{
			Real x0 = mOuterRadius * cosf(j*deltaAngle);
			Real z0 = mOuterRadius * sinf(j*deltaAngle);
			addPoint(buffer, Vector3(x0, i*deltaHeight, z0),
			         Vector3(x0,0,z0).normalisedCopy(),
			         Vector2(j/(Real)mNumSegBase, i/(Real)mNumSegHeight));

			if (i != mNumSegHeight)
			{
				buffer.index(offset + mNumSegBase + 1);
				buffer.index(offset);
				buffer.index(offset + mNumSegBase);
				buffer.index(offset + mNumSegBase + 1);
				buffer.index(offset + 1);
				buffer.index(offset);
			}
			offset ++;
		}

	for (unsigned int i = 0; i <=mNumSegHeight; i++)
		for (unsigned int j = 0; j<=mNumSegBase; j++)
		{
			Real x0 = mInnerRadius * cosf(j*deltaAngle);
			Real z0 = mInnerRadius * sinf(j*deltaAngle);
			addPoint(buffer, Vector3(x0, i*deltaHeight, z0),
			         -Vector3(x0,0,z0).normalisedCopy(),
			         Vector2(j/(Real)mNumSegBase, i/(Real)mNumSegHeight));

			if (i != mNumSegHeight)
			{
				buffer.index(offset + mNumSegBase + 1);
				buffer.index(offset + mNumSegBase);
				buffer.index(offset);
				buffer.index(offset + mNumSegBase + 1);
				buffer.index(offset);
				buffer.index(offset + 1);
			}
			offset ++;
		}


	//low cap
	for (unsigned int j=0; j<=mNumSegBase; j++)
	{
		Real x0 = mInnerRadius * cosf(j*deltaAngle);
		Real z0 = mInnerRadius * sinf(j*deltaAngle);

		addPoint(buffer, Vector3(x0, 0.0f, z0),
		         Vector3::NEGATIVE_UNIT_Y,
		         Vector2(j/(Real)mNumSegBase,1.));

		x0 = mOuterRadius * cosf(j*deltaAngle);
		z0 = mOuterRadius * sinf(j*deltaAngle);

		addPoint(buffer, Vector3(x0, 0.0f, z0),
		         Vector3::NEGATIVE_UNIT_Y,
		         Vector2(j/(Real)mNumSegBase,0.));

		if (j!=mNumSegBase)
		{
			buffer.index(offset);
			buffer.index(offset+1);
			buffer.index(offset+3);
			buffer.index(offset+2);
			buffer.index(offset);
			buffer.index(offset+3);
		}
		offset+=2;
	}


	//high cap
	for (unsigned int j=0; j<=mNumSegBase; j++)
	{
		Real x0 = mInnerRadius * cosf(j*deltaAngle);
		Real z0 = mInnerRadius * sinf(j*deltaAngle);

		addPoint(buffer, Vector3(x0, mHeight, z0),
		         Vector3::UNIT_Y,
		         Vector2(j/(Real)mNumSegBase,0.));

		x0 = mOuterRadius * cosf(j*deltaAngle);
		z0 = mOuterRadius * sinf(j*deltaAngle);

		addPoint(buffer, Vector3(x0, mHeight, z0),
		         Vector3::UNIT_Y,
		         Vector2(j/(Real)mNumSegBase,1.));

		if (j!=mNumSegBase)
		{
			buffer.index(offset+1);
			buffer.index(offset);
			buffer.index(offset+3);
			buffer.index(offset);
			buffer.index(offset+2);
			buffer.index(offset+3);
		}
		offset+=2;
	}
}
コード例 #24
0
void TubeGenerator::addToTriangleBuffer(TriangleBuffer& buffer) const
{
	assert(height>0. && outerRadius>0. && innerRadius>0. && "Height and radius must be positive");
	assert(innerRadius<outerRadius && "Outer radius must be bigger than inner radius");
	assert(numSegBase>0 && numSegHeight>0 && "Num seg must be positive integers");

	buffer.rebaseOffset();
	buffer.estimateVertexCount((numSegHeight+1)*(numSegBase+1)*2+(numSegBase+1)*4);
	buffer.estimateIndexCount(6*(numSegBase+1)*numSegHeight*2+6*numSegBase*2);
	
	Ogre::Real deltaAngle = (Ogre::Math::TWO_PI / numSegBase);
	Ogre::Real deltaHeight = height/(Ogre::Real)numSegHeight;
	int offset = 0;

	for (int i = 0; i <=numSegHeight; i++)
		for (int j = 0; j<=numSegBase; j++)
		{
			Ogre::Real x0 = outerRadius * cosf(j*deltaAngle);
			Ogre::Real z0 = outerRadius * sinf(j*deltaAngle);
			buffer.position(x0, i*deltaHeight, z0);
			buffer.normal(Ogre::Vector3(x0,0,z0).normalisedCopy());
			buffer.textureCoord(j/(Ogre::Real)numSegBase*uTile, i/(Ogre::Real)numSegHeight*vTile);

			if (i != numSegHeight) 
			{
				buffer.index(offset + numSegBase + 1);
				buffer.index(offset);
				buffer.index(offset + numSegBase);
				buffer.index(offset + numSegBase + 1);
				buffer.index(offset + 1);
				buffer.index(offset);
			}
			offset ++;
		}

	for (int i = 0; i <=numSegHeight; i++)
		for (int j = 0; j<=numSegBase; j++)
		{
			Ogre::Real x0 = innerRadius * cosf(j*deltaAngle);
			Ogre::Real z0 = innerRadius * sinf(j*deltaAngle);
			buffer.position(x0, i*deltaHeight, z0);
			buffer.normal(-Ogre::Vector3(x0,0,z0).normalisedCopy());
			buffer.textureCoord(j/(Ogre::Real)numSegBase*uTile, i/(Ogre::Real)numSegHeight*vTile);

			if (i != numSegHeight) 
			{
				buffer.index(offset + numSegBase + 1);
				buffer.index(offset + numSegBase);
				buffer.index(offset);
				buffer.index(offset + numSegBase + 1);
				buffer.index(offset);
				buffer.index(offset + 1);
			}
			offset ++;
		}


		//low cap
		for (int j=0;j<=numSegBase;j++)
		{
			Ogre::Real x0 = innerRadius * cosf(j*deltaAngle);
			Ogre::Real z0 = innerRadius * sinf(j*deltaAngle);

			buffer.position(x0, 0.0f, z0);
			buffer.normal(Ogre::Vector3::NEGATIVE_UNIT_Y);
			buffer.textureCoord(j/(Ogre::Real)numSegBase*uTile,vTile);

			x0 = outerRadius * cosf(j*deltaAngle);
			z0 = outerRadius * sinf(j*deltaAngle);

			buffer.position(x0, 0.0f, z0);
			buffer.normal(Ogre::Vector3::NEGATIVE_UNIT_Y);
			buffer.textureCoord(j/(Ogre::Real)numSegBase*uTile,0.0);

			if (j!=numSegBase)
			{
				buffer.index(offset);
				buffer.index(offset+1);
				buffer.index(offset+3);
				buffer.index(offset+2);
				buffer.index(offset);
				buffer.index(offset+3);
			}
			offset+=2;
		}


		//high cap
		for (int j=0;j<=numSegBase;j++)
		{
			Ogre::Real x0 = innerRadius * cosf(j*deltaAngle);
			Ogre::Real z0 = innerRadius * sinf(j*deltaAngle);

			buffer.position(x0, height, z0);
			buffer.normal(Ogre::Vector3::UNIT_Y);
			buffer.textureCoord(j/(Ogre::Real)numSegBase*uTile,0.0);

			x0 = outerRadius * cosf(j*deltaAngle);
			z0 = outerRadius * sinf(j*deltaAngle);

			buffer.position(x0, height, z0);
			buffer.normal(Ogre::Vector3::UNIT_Y);
			buffer.textureCoord(j/(Ogre::Real)numSegBase*uTile,vTile);

			if (j!=numSegBase)
			{
				buffer.index(offset+1);
				buffer.index(offset);
				buffer.index(offset+3);
				buffer.index(offset);
				buffer.index(offset+2);
				buffer.index(offset+3);
			}
			offset+=2;
		}
}