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