⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 roam_naturepatch.cpp

📁 使用stl技术,(还没看,是听说的)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			  static_cast<int>(mBaseVertex[2].x), 
			  static_cast<int>(mBaseVertex[2].z),
	      2, 2);
    
    tesselate(&mBaseRight, static_cast<int>(mBaseVertex[1].x),
			   static_cast<int>(mBaseVertex[1].z),
			   static_cast<int>(mBaseVertex[0].x),
			   static_cast<int>(mBaseVertex[0].z),
			   static_cast<int>(mBaseVertex[3].x),
			   static_cast<int>(mBaseVertex[3].z),
	      3, 2);

#if STITCH_EDGES 
    memset(mEdgeVertices, 0xffff, (PATCH_SIZE+1) * 4 * sizeof(ushort));
#if DRAW_EDGE_SKIRTS
    mUsedSkirts[0] = mUsedSkirts[1] = mUsedSkirts[2] = mUsedSkirts[3] = 0;
#endif
#endif

    // Store base vertices
    memset(mVertexLookup, 0xffff, ((PATCH_SIZE+1)*(PATCH_SIZE+1))
				  * sizeof(ushort));
    mVertexCount = mIndexCount = 0;

    STORE_VERTEX_NEW(static_cast<int>(mBaseVertex[0].x),
		     static_cast<int>(mBaseVertex[0].y),
		     static_cast<int>(mBaseVertex[0].z));

    STORE_VERTEX_NEW(static_cast<int>(mBaseVertex[1].x),
		     static_cast<int>(mBaseVertex[1].y),
		     static_cast<int>(mBaseVertex[1].z));

    STORE_VERTEX_NEW(static_cast<int>(mBaseVertex[2].x),
		     static_cast<int>(mBaseVertex[2].y),
		     static_cast<int>(mBaseVertex[2].z));

    STORE_VERTEX_NEW(static_cast<int>(mBaseVertex[3].x),
		     static_cast<int>(mBaseVertex[3].y),
		     static_cast<int>(mBaseVertex[3].z));

    // Store base texture coordinates
    STORE_TEXCOORD(0, mBaseVertex[0].x, mBaseVertex[0].z);
    STORE_TEXCOORD(3, mBaseVertex[1].x, mBaseVertex[1].z);
    STORE_TEXCOORD(6, mBaseVertex[2].x, mBaseVertex[2].z);
    STORE_TEXCOORD(9, mBaseVertex[3].x, mBaseVertex[3].z);

    // Build the vertexbuffers
    render(&mBaseLeft, static_cast<int>(mBaseVertex[0].x),
		       static_cast<int>(mBaseVertex[0].z),
		       static_cast<int>(mBaseVertex[1].x),
		       static_cast<int>(mBaseVertex[1].z),
		       static_cast<int>(mBaseVertex[2].x),
		       static_cast<int>(mBaseVertex[2].z),
	   0, 3, 6, 2);
    
    render(&mBaseRight, static_cast<int>(mBaseVertex[1].x),
			static_cast<int>(mBaseVertex[1].z),
		        static_cast<int>(mBaseVertex[0].x),
			static_cast<int>(mBaseVertex[0].z),
		        static_cast<int>(mBaseVertex[3].x),
			static_cast<int>(mBaseVertex[3].z),
	   3, 0, 9, 2);

    // Create new buffers
    mVertexCacheSize = (mVertexCount * 3);
    mIndexCacheSize  = mIndexCount;

    if (mVertexCache != 0)	delete[] mVertexCache;
    if (mIndexCache != 0)	delete[] mIndexCache;
    if (mTexCoordCache[0] != 0) delete[] mTexCoordCache[0];
//    if (mTexCoordCache[1] != 0) delete[] mTexCoordCache[1];

    // Allocate buffers
#if STITCH_EDGES & DRAW_EDGE_SKIRTS
    mVertexCache      = new Real[mVertexCacheSize + (MAX_EDGE_SKIRTS*4)*6];
    mIndexCache       = new ushort[mIndexCacheSize + (MAX_EDGE_SKIRTS*4)*9];
    mTexCoordCache[0] = new Real[(mVertexCount + (MAX_EDGE_SKIRTS*4)*2) * 2];
//    mTexCoordCache[1] = new Real[(mVertexCount + (MAX_EDGE_SKIRTS*4)*2) * 2];
#else
    mVertexCache      = new Real[mVertexCacheSize];
    mIndexCache       = new ushort[mIndexCacheSize];	
    mTexCoordCache[0] = new Real[mVertexCount * 2];
//    mTexCoordCache[1] = new Real[mVertexCount * 2];
#endif

    // Copy data to the new buffers for the RenderOperation 
    memcpy(mVertexCache, vertexBuffer, mVertexCacheSize * sizeof(Real));
    memcpy(mIndexCache, indexBuffer, mIndexCacheSize * sizeof(ushort));
    memcpy(mTexCoordCache[0], texCoordBuffer[0], mVertexCount*sizeof(Real)*2);
//    memcpy(mTexCoordCache[1], texCoordBuffer[1], mVertexCount*sizeof(Real)*2);

#if DRAW_EDGE_SKIRTS
    mVertexBuffer      = mVertexCache;
    mIndexBuffer       = mIndexCache;
    mTexCoordBuffer[0] = mTexCoordCache[0];
//    mTexCoordBuffer[1] = mTexCoordCache[1];
#endif
#if STITCH_EDGES
    mNeedsStitching    = 0x0f;
#endif
//    mNeedsRebuild = false;

*/
    // Return number of triangles generated
    return (mIndexCount / 3);
}

//---------------------------------------------------------------------------


#if STITCH_EDGES 
#if DRAW_EDGE_SKIRTS

// Removes the skirts on an edge by removing its indexes from the indexcache
void NaturePatch::clearSkirtEdge(int direction)
{
    if (mUsedSkirts[direction] == 0)
    {
	return;
    }
    
    // Calculate offset to first free index before skirts were added
    int count = mUsedSkirts[0] + mUsedSkirts[1]
	      +	mUsedSkirts[2] + mUsedSkirts[3];
    
    int offset = mIndexCacheSize - (count * 9);

    // Clear the edge
    mUsedSkirts[direction] = 0;

    // Copy the indexes of the remaining skirts
    for (int i = 0; i < 4; i++)
    {
	if (mUsedSkirts[i] != 0)
	{
	    memcpy(&mIndexCache[offset], mSkirtIndexes[i],
		   mUsedSkirts[i] * 9 * sizeof(ushort));

	    offset += mUsedSkirts[i] * 9;
	}
    }

    // Update size of the indexcache
    mIndexCacheSize = offset;
}

#endif

void NaturePatch::stitch(int direction, NaturePatch *neighborPatch)
{
    int neighborDir, lo = 0, ln = 0, i, n;
    ushort *neighborEdge;
    ushort *ourEdge;

    if (!(mNeedsStitching & (1 << direction)))
	return;

    switch (direction)
    {
	case EDGE_NORTH: neighborDir = EDGE_SOUTH; break;
	case EDGE_SOUTH: neighborDir = EDGE_NORTH; break;
	case EDGE_WEST:  neighborDir = EDGE_EAST; break;
	case EDGE_EAST:  neighborDir = EDGE_WEST; break;
	default: return;
    }

/*    printf("STITCHING: %s direction %d with %s direction %d -- ",
	(const char *)mName, direction, (const char *)neighborPatch->getName(),
	neighborDir); */

    ourEdge = &mEdgeVertices[direction * (PATCH_SIZE+1)];
    neighborEdge = &neighborPatch->mEdgeVertices[neighborDir * (PATCH_SIZE+1)];

    // Reset the ypos of each edge vertex where vertex exists on both patches
    for (i = 0; i < PATCH_SIZE+1; i++)
    {
	if (ourEdge[i] != 0xffff && neighborEdge[i] != 0xffff)
	{
	    int x = static_cast<int>(((mVertexCache[ourEdge[i] + 0] - mWorld.x)
				     / mScale.x) + 0.5);
    	    int z = static_cast<int>(((mVertexCache[ourEdge[i] + 2] - mWorld.z) 
				     / mScale.z) + 0.5);

	    Real height = (GET_HEIGHT(x, z) * mScale.y) + mWorld.y;

	    mVertexCache[ourEdge[i] + 1] = height;
    	    neighborPatch->mVertexCache[neighborEdge[i] + 1] = height;
	} 
    }

#if DRAW_EDGE_SKIRTS
    // Clear the skirts on the neighbors edge
    neighborPatch->clearSkirtEdge(neighborDir);
    int idxOff = 0;
#endif

    // Find and fix cracks
    for (i = 0; i < PATCH_SIZE+1; i++)
    {
	if (ourEdge[i] != 0xffff)
	{
	    if (neighborEdge[i] == 0xffff)
	    {
		// our edge has a vertex thats not on the neighbors edge,
		// find the next neighbor vertex
		for (n = i+1; n < (PATCH_SIZE+1); n++)
		{
		    if (neighborEdge[n] != 0xffff)
			break;
		}

		// next vertex found, calculate new heigh of our vertex
		Real diffHeight = neighborPatch->mVertexCache[neighborEdge[n] + 1] - 
				  neighborPatch->mVertexCache[neighborEdge[ln] + 1];
		
		Real newHeight = neighborPatch->mVertexCache[neighborEdge[ln] + 1]
				 + diffHeight * (Real)((i-ln)/(Real)(n-ln));
		// update our vertex to the new height
		mVertexCache[ourEdge[i] + 1] = newHeight;
	    
#if DRAW_EDGE_SKIRTS
		if (mUsedSkirts[direction] < MAX_EDGE_SKIRTS)
		{
		    register int ni = (mVertexCount++) * 3;
		    mVertexCache[ni + 0] = mVertexCache[ourEdge[i] + 0];
		    mVertexCache[ni + 1] = mVertexCache[ourEdge[i] + 1] - 1.0;
		    mVertexCache[ni + 2] = mVertexCache[ourEdge[i] + 2];
		    
		    register int ni2 = (mVertexCount++) * 3;
		    mVertexCache[ni2 + 0] = neighborPatch->
			mVertexCache[neighborEdge[n] + 0];
		    mVertexCache[ni2 + 1] = neighborPatch->
			mVertexCache[neighborEdge[n] + 1];
		    mVertexCache[ni2 + 2] = neighborPatch->
			mVertexCache[neighborEdge[n] + 2];
		    
		    int tx = static_cast<int>((mVertexCache[ni + 0] - 
					      mWorld.x) / mScale.x);
		    int tz = static_cast<int>((mVertexCache[ni + 2] -
					      mWorld.z) / mScale.z);
		    STORE_TEXCOORD(ni, tx, tz);

		    tx = static_cast<int>((mVertexCache[ni2 + 0] - 
					  mWorld.x) / mScale.x);
		    tz = static_cast<int>((mVertexCache[ni2 + 2] -
					  mWorld.z) / mScale.z);
		    STORE_TEXCOORD(ni2, tx, tz);

		    if (direction == EDGE_NORTH || direction == EDGE_EAST)
		    {
			mSkirtIndexes[direction][idxOff++] = ourEdge[i] / 3;
			mSkirtIndexes[direction][idxOff++] = ni / 3;
			mSkirtIndexes[direction][idxOff++] = ourEdge[lo] / 3;
		    
			mSkirtIndexes[direction][idxOff++] = ni2 / 3;
			mSkirtIndexes[direction][idxOff++] = ni / 3;
			mSkirtIndexes[direction][idxOff++] = ourEdge[i] / 3;

			mSkirtIndexes[direction][idxOff++] = ourEdge[lo] / 3;
			mSkirtIndexes[direction][idxOff++] = ni / 3;
			mSkirtIndexes[direction][idxOff++] = ni2 / 3;
		    
			ADD_TRIANGLE(ourEdge[i], ni, ourEdge[lo]);
			ADD_TRIANGLE(ni2, ni, ourEdge[i]);
			ADD_TRIANGLE(ourEdge[lo], ni, ni2);
		    }
		    else
		    {
			mSkirtIndexes[direction][idxOff++] = ourEdge[lo] / 3;
			mSkirtIndexes[direction][idxOff++] = ni / 3;
			mSkirtIndexes[direction][idxOff++] = ourEdge[i] / 3;
		    
			mSkirtIndexes[direction][idxOff++] = ourEdge[i] / 3; 
			mSkirtIndexes[direction][idxOff++] = ni / 3;
			mSkirtIndexes[direction][idxOff++] = ni2 / 3;

			mSkirtIndexes[direction][idxOff++] = ni2 / 3;
			mSkirtIndexes[direction][idxOff++] = ni / 3;
			mSkirtIndexes[direction][idxOff++] = ourEdge[lo] / 3;
		    
			ADD_TRIANGLE(ourEdge[lo], ni, ourEdge[i]);
			ADD_TRIANGLE(ourEdge[i], ni, ni2);
			ADD_TRIANGLE(ni2, ni, ourEdge[lo]);
		    }
		    
		    mUsedSkirts[direction]++;
		}
#endif
	    }
	    lo = i;
	}

	if (neighborEdge[i] != 0xffff)
	{
	    if (ourEdge[i] == 0xffff)
	    {
		// the neighbor edge has a vertex thats not on our edge
		// find our next vertex
		for (n = i+1; n < (PATCH_SIZE+1); n++)
		{
		    if (ourEdge[n] != 0xffff)
			break;
		}

		// next vertex found, calculate new heigh of neighbors vertex
		Real diffHeight = mVertexCache[ourEdge[n] + 1] - 
				  mVertexCache[ourEdge[lo] + 1];
		
		Real newHeight = mVertexCache[ourEdge[lo] + 1] +
				 diffHeight * ((Real)(i-lo)/(Real)(n-lo));

		// update neighbor vertex to the new height
		neighborPatch->mVertexCache[neighborEdge[i] + 1] = newHeight;

#if DRAW_EDGE_SKIRTS
		if (mUsedSkirts[direction] < MAX_EDGE_SKIRTS)
		{
		    register int ni = (mVertexCount++) * 3;
		    mVertexCache[ni + 0] = neighborPatch->
			mVertexCache[neighborEdge[i] + 0];
		    mVertexCache[ni + 1] = neighborPatch->
			mVertexCache[neighborEdge[i] + 1] - 1.0;
		    mVertexCache[ni + 2] = neighborPatch->
			mVertexCache[neighborEdge[i] + 2];
		    
		    register int ni2 = (mVertexCount++) * 3;
		    mVertexCache[ni2 + 0] = mVertexCache[ni + 0];
		    mVertexCache[ni2 + 1] = mVertexCache[ni + 1] + 1.0;
		    mVertexCache[ni2 + 2] = mVertexCache[ni + 2];
		    
		    int tx = static_cast<int>((mVertexCache[ni + 0] - 
					      mWorld.x) / mScale.x);
		    int tz = static_cast<int>((mVertexCache[ni + 2] -
					      mWorld.z) / mScale.z);
		    STORE_TEXCOORD(ni, tx, tz);
		    STORE_TEXCOORD(ni2, tx, tz);

		    if (direction == EDGE_NORTH || direction == EDGE_EAST)
		    {
			mSkirtIndexes[direction][idxOff++] = ourEdge[lo] / 3;
			mSkirtIndexes[direction][idxOff++] = ni / 3;
			mSkirtIndexes[direction][idxOff++] = ni2 / 3;

			mSkirtIndexes[direction][idxOff++] = ni2 / 3;
			mSkirtIndexes[direction][idxOff++] = ni / 3;
			mSkirtIndexes[direction][idxOff++] = ourEdge[n] / 3;

			mSkirtIndexes[direction][idxOff++] = ourEdge[n] / 3;
			mSkirtIndexes[direction][idxOff++] = ni / 3;
			mSkirtIndexes[direction][idxOff++] = ourEdge[lo] / 3;
		    
			ADD_TRIANGLE(ourEdge[lo], ni, ni2);
			ADD_TRIANGLE(ni2, ni, ourEdge[n]);
			ADD_TRIANGLE(ourEdge[n], ni, ourEdge[lo]);
		    }
		    else
		    {
			mSkirtIndexes[direction][idxOff++] = ni2 / 3;
			mSkirtIndexes[direction][idxOff++] = ni / 3;
			mSkirtIndexes[direction][idxOff++] = ourEdge[lo] / 3;

			mSkirtIndexes[direction][idxOff++] = ourEdge[n] / 3;
			mSkirtIndexes[direction][idxOff++] = ni / 3;
			mSkirtIndexes[direction][idxOff++] = ni2 / 3;

			mSkirtIndexes[direction][idxOff++] = ourEdge[lo] / 3;
			mSkirtIndexes[direction][idxOff++] = ni / 3;
			mSkirtIndexes[direction][idxOff++] = ourEdge[n] / 3;
		    
			ADD_TRIANGLE(ni2, ni, ourEdge[lo]);
			ADD_TRIANGLE(ourEdge[n], ni, ni2);
			ADD_TRIANGLE(ourEdge[lo], ni, ourEdge[n]);
		    }

		    mUsedSkirts[direction]++;
		}
#endif
	    }
	    ln = i;
	}
    }

#if DRAW_EDGE_SKIRTS
    mVertexCacheSize = (mVertexCount * 3);
    mIndexCacheSize  = mIndexCount;
#endif

    // Update status flags to make sure that edges only gets stitched once
//    neighborPatch->mNeedsStitching &= ~(1 << neighborDir);
    mNeedsStitching &= ~(1 << direction);

/*    std::cout <<  mUsedSkirts[direction] << " skirts added" << std::endl; */
}

#endif

//----------------------------------------------------------------------------

void NaturePatch::getRenderOperation(RenderOperation& op)
{
    /* TODO
    rend.useIndexes = true;

    rend.vertexOptions = LegacyRenderOperation::VO_TEXTURE_COORDS;
    //rend.vertexOptions |= LegacyRenderOperation::VO_DIFFUSE_COLOURS;
    rend.operationType = LegacyRenderOperation::OT_TRIANGLE_LIST;

    // use colors
    rend.pDiffuseColour = 0;
    rend.diffuseStride  = 0;

    // textures
    rend.numTextureCoordSets = 1;
    rend.numTextureDimensions[0] = 2;
//    rend.numTextureDimensions[1] = 2;
    rend.pTexCoords[0] = mTexCoordCache[0];
//    rend.pTexCoords[1] = mTexCoordCache[1];

    rend.texCoordStride[0] = 0;
//    rend.texCoordStride[1] = 0;

    // vertices & indexes
    rend.vertexStride = 0;
    rend.pVertices    = mVertexCache;
    rend.pIndexes     = mIndexCache;
    rend.numVertices  = mVertexCacheSize/3;
    rend.numIndexes   = mIndexCacheSize;

    // lighting
    rend.pNormals = 0;

    */
    return RenderOperation();
}

//----------------------------------------------------------------------------

void NaturePatch::_notifyCurrentCamera(Camera *cam)
{
    Real quality = 1.0;
    Vector3 diff = mCenter - cam->getPosition();
    Real dist = diff.length();

    if (dist > 400) quality = 0.30;
    else if (dist > 300) quality = 0.60;
    else quality = 1.0;

/*    if (dist > 400) quality = 0.15;
    else if (dist > 300) quality = 0.30;
    else if (dist > 200) quality = 0.60;
    else quality = 1.5;
*/
    quality = quality * mQualityModifier;

    if (mMeshQuality != quality)
    {
	mMeshQuality = quality;
	mNeedsRebuild = true;
    }
}

//----------------------------------------------------------------------------

uint NaturePatch::getMemoryUsage()
{
    unsigned int memUsage = 0;

    // vertexcache
    memUsage += ((mVertexCount*3) + ((MAX_EDGE_SKIRTS*4)*6)) * sizeof(Real);
    // indexcache
    memUsage += (mIndexCount + (MAX_EDGE_SKIRTS*4)*9) * sizeof(Real);
    // texturecoordcache
    memUsage += ((mVertexCount + (MAX_EDGE_SKIRTS*4)*2)*2) * sizeof(ushort);

    memUsage += VARBUF_SIZE * 2;

    return memUsage + sizeof(NaturePatch);
}

} // Ogre namespace

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -