void DynoTree::makeBranch(glm::vec3 pos, glm::vec3 dir, float len, float width, int lastRingIndex,bool swapTex) { // Construct the two basis vectors for construction of points glm::vec3 basisA = glm::normalize(glm::cross(dir,glm::vec3(1,0,1))); glm::vec3 basisB = glm::normalize(glm::cross(dir,basisA)); // If we need to make a bottom ring, do so if (lastRingIndex==-1) lastRingIndex = makeRing(pos,basisA,basisB,width,true); // Otherwise, and in addition, create the top ring int topRingIndex = makeRing(pos+dir*len,basisA,basisB,width*0.66f,swapTex); // Add in all the triangles makeTriangles(lastRingIndex,topRingIndex); // If the branch is thick enough, we can branch into two others if (width>0.05) { // Get a random direction glm::vec3 d = glm::sphericalRand(1.f); // Add it to this direction glm::vec3 newDirection = dir + d/1.8f; // Make a sub branch in that direction makeBranch(pos+dir*len,glm::normalize(newDirection),len/1.2f,width*2.f/5.f,-1,false); // Do it again d = glm::sphericalRand(1.f); newDirection = dir + d/2.8f; // Continue this branch makeBranch(pos+dir*len,glm::normalize(newDirection),len/1.2f,width*3.f/5.f,topRingIndex,!swapTex); } // If we are small enough, we can put leaves here if (width<0.3f) makeLeaves(pos,dir,len); }
//----------------------------------------------------------------------- void PatchSurface::setSubdivisionFactor(Real factor) { assert(factor >= 0.0f && factor <= 1.0f); mSubdivisionFactor = factor; mULevel = static_cast<size_t>(factor * mMaxULevel); mVLevel = static_cast<size_t>(factor * mMaxVLevel); makeTriangles(); }
//----------------------------------------------------------------------- void PatchSurface::build(HardwareVertexBufferSharedPtr destVertexBuffer, size_t vertexStart, HardwareIndexBufferSharedPtr destIndexBuffer, size_t indexStart) { if (mVecCtlPoints.empty()) return; mVertexBuffer = destVertexBuffer; mVertexOffset = vertexStart; mIndexBuffer = destIndexBuffer; mIndexOffset = indexStart; // Lock just the region we are interested in void* lockedBuffer = mVertexBuffer->lock( mVertexOffset * mDeclaration->getVertexSize(0), mRequiredVertexCount * mDeclaration->getVertexSize(0), HardwareBuffer::HBL_NO_OVERWRITE); distributeControlPoints(lockedBuffer); // Subdivide the curve to the MAX :) // Do u direction first, so need to step over v levels not done yet size_t vStep = 1 << mMaxVLevel; size_t uStep = 1 << mMaxULevel; size_t v, u; for (v = 0; v < mMeshHeight; v += vStep) { // subdivide this row in u subdivideCurve(lockedBuffer, v*mMeshWidth, uStep, mMeshWidth / uStep, mULevel); } // Now subdivide in v direction, this time all the u direction points are there so no step for (u = 0; u < mMeshWidth; ++u) { subdivideCurve(lockedBuffer, u, vStep*mMeshWidth, mMeshHeight / vStep, mVLevel); } mVertexBuffer->unlock(); // Make triangles from mesh at this current level of detail makeTriangles(); }