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++; } }
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 }
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; } }