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

📄 fxfoliagereplicator.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 5 页
字号:
		// Reset Frame Serial.
		pFoliageItem->LastFrameSerialID = 0;

		// Reset Transform.
		pFoliageItem->Transform.identity();

		// Set Position.
		pFoliageItem->Transform.setColumn(3, FoliagePosition);
	
		// Are we fixing size @ max?
		if (mFieldData.mFixSizeToMax)
		{
			// Yes, so set height maximum height.
			pFoliageItem->Height = mFieldData.mMaxHeight;
			// Is the Aspect Ratio Fixed?
			if (mFieldData.mFixAspectRatio)
				// Yes, so lock to height.
				pFoliageItem->Width = pFoliageItem->Height;
			else
				// No, so set width to maximum width.
				pFoliageItem->Width = mFieldData.mMaxWidth;
		}
		else
		{
			// No, so choose a new Scale.
			pFoliageItem->Height = RandomGen.randF(mFieldData.mMinHeight, mFieldData.mMaxHeight);
			// Is the Aspect Ratio Fixed?
			if (mFieldData.mFixAspectRatio)
				// Yes, so lock to height.
				pFoliageItem->Width = pFoliageItem->Height;
			else
				// No, so choose a random width.
				pFoliageItem->Width = RandomGen.randF(mFieldData.mMinWidth, mFieldData.mMaxWidth);
		}

		// Are we randomly flipping horizontally?
		if (mFieldData.mRandomFlip)
			// Yes, so choose a random flip for this object.
			pFoliageItem->Flipped = (RandomGen.randF(0, 1000) < 500.0f) ? false : true;
		else
			// No, so turn-off flipping.
			pFoliageItem->Flipped = false;


		// Calculate Foliage Item World Box.
		// NOTE:-	We generate a psuedo-volume here.  It's basically the volume to which the
		//			plane can move and this includes swaying!
		//
		// Is Sway On?
		if (mFieldData.mSwayOn)
		{
			// Yes, so take swaying into account...
			pFoliageItem->FoliageBox.min =	FoliagePosition +
											Point3F(-pFoliageItem->Width / 2.0f - mFieldData.mSwayMagnitudeSide,
													-0.5f - mFieldData.mSwayMagnitudeFront,
													pFoliageItem->Height );

			pFoliageItem->FoliageBox.max =	FoliagePosition +
											Point3F(+pFoliageItem->Width / 2.0f + mFieldData.mSwayMagnitudeSide,
													+0.5f + mFieldData.mSwayMagnitudeFront,
													pFoliageItem->Height );
		}
		else
		{
			// No, so give it a minimum volume...
			pFoliageItem->FoliageBox.min =	FoliagePosition +
											Point3F(-pFoliageItem->Width / 2.0f,
													-0.5f,
													pFoliageItem->Height );

			pFoliageItem->FoliageBox.max =	FoliagePosition +
											Point3F(+pFoliageItem->Width / 2.0f,
													+0.5f,
													pFoliageItem->Height );
		}

		// Monitor the total volume.
		MinPoint.setMin( pFoliageItem->FoliageBox.min - getRenderPosition() );
		MaxPoint.setMax( pFoliageItem->FoliageBox.max - getRenderPosition() );

		// Store Shape in Replicated Shapes Vector.
		mReplicatedFoliage.push_back(pFoliageItem);

		// Increase Foliage Count.
		mCurrentFoliageCount++;
	}

	// Is Lighting On?
	if (mFieldData.mLightOn)
	{
		// Yes, so step through Foliage.
		for (U32 idx = 0; idx < mCurrentFoliageCount; idx++)
		{
			fxFoliageItem*	pFoliageItem;

			// Fetch the Foliage Item.
			pFoliageItem = mReplicatedFoliage[idx];

			// Do we have an item?
			if (pFoliageItem)
			{
				// Yes, so are lights syncronised?
				if (mFieldData.mLightSync)
				{
					// Yes, so reset Global Light phase.
					mGlobalLightPhase = 0.0f;
					// Set Global Light Time Ratio.
					mGlobalLightTimeRatio = 719.0f / mFieldData.mLightTime;
				}
				else
				{
					// No, so choose a random Light phase.
					pFoliageItem->LightPhase = RandomGen.randF(0, 719.0f);
					// Set Light Time Ratio.
					pFoliageItem->LightTimeRatio = 719.0f / mFieldData.mLightTime;
				}
			}
		}

	}

	// Is Swaying Enabled?
	if (mFieldData.mSwayOn)
	{
		// Yes, so step through Foliage.
		for (U32 idx = 0; idx < mCurrentFoliageCount; idx++)
		{
			fxFoliageItem*	pFoliageItem;

			// Fetch the Foliage Item.
			pFoliageItem = mReplicatedFoliage[idx];

			// Do we have an item?
			if (pFoliageItem)
			{
				// Are we using Sway Sync?
				if (mFieldData.mSwaySync)
				{
					// Yes, so reset Global Sway phase.
					mGlobalSwayPhase = 0.0f;
					// Set Global Sway Time Ratio.
					mGlobalSwayTimeRatio = 719.0f / RandomGen.randF(mFieldData.mMinSwayTime, mFieldData.mMaxSwayTime);
				}
				else
				{
					// No, so choose a random Sway phase.
					pFoliageItem->SwayPhase = RandomGen.randF(0, 719.0f);
					// Set to random Sway Time.
					pFoliageItem->SwayTimeRatio = 719.0f / RandomGen.randF(mFieldData.mMinSwayTime, mFieldData.mMaxSwayTime);
				}
			}
		}
	}

	// Update our Object Volume.
	mObjBox.min.set(MinPoint);
	mObjBox.max.set(MaxPoint);
	setTransform(mObjToWorld);

	// ----------------------------------------------------------------------------------------------------------------------
	// Step 3.
	// ----------------------------------------------------------------------------------------------------------------------

	// Reset Next Allocated Node to Stack base.
	mNextAllocatedNodeIdx = 0;

	// Allocate a new Node.
	fxFoliageQuadrantNode* pNewNode = new fxFoliageQuadrantNode;

	// Store it in the Quad-tree.
	mFoliageQuadTree.push_back(pNewNode);

	// Populate Initial Node.
	//
	// Set Start Level.
	pNewNode->Level = mQuadTreeLevels;
	// Calculate Total Foliage Area.
	pNewNode->QuadrantBox = getWorldBox();
	// Reset Quadrant child nodes.
	pNewNode->QuadrantChildNode[0] =
	pNewNode->QuadrantChildNode[1] =
	pNewNode->QuadrantChildNode[2] =
	pNewNode->QuadrantChildNode[3] = NULL;

	// Create our initial cull list with *all* billboards into.
	fxFoliageCulledList CullList;
	CullList.mCulledObjectSet = mReplicatedFoliage;

	// Move to next node Index.
	mNextAllocatedNodeIdx++;

	// Let's start this thing going by recursing it's children.
	ProcessNodeChildren(pNewNode, &CullList);

	// Calculate Elapsed Time and take new Timestamp.
	F32 ElapsedTime = (Platform::getRealMilliseconds() - mStartCreationTime) * 0.001f;

	// Console Output.
	Con::printf("fxFoliageReplicator - Lev: %d  PotNodes: %d  Used: %d  Objs: %d  Time: %0.4fs.",
				mQuadTreeLevels,
				mPotentialFoliageNodes,
				mNextAllocatedNodeIdx-1,
				mBillboardsAcquired,
				ElapsedTime);

	// Dump (*very*) approximate allocated memory.
	F32 MemoryAllocated = (mNextAllocatedNodeIdx-1) * sizeof(fxFoliageQuadrantNode);
	MemoryAllocated		+=	mCurrentFoliageCount * sizeof(fxFoliageItem);
	MemoryAllocated		+=	mCurrentFoliageCount * sizeof(fxFoliageItem*);
	Con::printf("fxFoliageReplicator - Approx. %0.2fMb allocated.", MemoryAllocated / 1048576.0f);

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

	// Take first Timestamp.
	mLastRenderTime = Platform::getVirtualMilliseconds();
}

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

Box3F fxFoliageReplicator::FetchQuadrant(Box3F Box, U32 Quadrant)
{
	Box3F QuadrantBox;

	// Select Quadrant.
	switch(Quadrant)
	{
		// UL.
		case 0:
			QuadrantBox.min = Box.min + Point3F(0, Box.len_y()/2, 0);
			QuadrantBox.max = QuadrantBox.min + Point3F(Box.len_x()/2, Box.len_y()/2, Box.len_z());
			break;

		// UR.
		case 1:
			QuadrantBox.min = Box.min + Point3F(Box.len_x()/2, Box.len_y()/2, 0);
			QuadrantBox.max = QuadrantBox.min + Point3F(Box.len_x()/2, Box.len_y()/2, Box.len_z());
			break;

		// LL.
		case 2:
			QuadrantBox.min = Box.min;
			QuadrantBox.max = QuadrantBox.min + Point3F(Box.len_x()/2, Box.len_y()/2, Box.len_z());
			break;

		// LR.
		case 3:
			QuadrantBox.min = Box.min + Point3F(Box.len_x()/2, 0, 0);
			QuadrantBox.max = QuadrantBox.min + Point3F(Box.len_x()/2, Box.len_y()/2, Box.len_z());
			break;

		default:
			return Box;
	}

	return QuadrantBox;
}

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

void fxFoliageReplicator::ProcessNodeChildren(fxFoliageQuadrantNode* pParentNode, fxFoliageCulledList* pCullList)
{
	// ---------------------------------------------------------------
	// Split Node into Quadrants and Process each.
	// ---------------------------------------------------------------

	// Process All Quadrants (UL/UR/LL/LR).
	for (U32 q = 0; q < 4; q++)
		ProcessQuadrant(pParentNode, pCullList, q);
}

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

void fxFoliageReplicator::ProcessQuadrant(fxFoliageQuadrantNode* pParentNode, fxFoliageCulledList* pCullList, U32 Quadrant)
{
	// Fetch Quadrant Box.
	const Box3F QuadrantBox = FetchQuadrant(pParentNode->QuadrantBox, Quadrant);

	// Create our new Cull List.
	fxFoliageCulledList CullList(QuadrantBox, pCullList);

	// Did we get any objects?
	if (CullList.GetListCount() > 0)
	{
		// Yes, so allocate a new Node.
		fxFoliageQuadrantNode* pNewNode = new fxFoliageQuadrantNode;

		// Store it in the Quad-tree.
		mFoliageQuadTree.push_back(pNewNode);

		// Move to next node Index.
		mNextAllocatedNodeIdx++;

		// Populate Quadrant Node.
		//
		// Next Sub-level.
		pNewNode->Level = pParentNode->Level - 1;
		// Calculate Quadrant Box.
		pNewNode->QuadrantBox = QuadrantBox;
		// Reset Child Nodes.
		pNewNode->QuadrantChildNode[0] =
		pNewNode->QuadrantChildNode[1] =
		pNewNode->QuadrantChildNode[2] =
		pNewNode->QuadrantChildNode[3] = NULL;
		
		// Put a reference in parent.
		pParentNode->QuadrantChildNode[Quadrant] = pNewNode;

		// If we're not at sub-level 0 then process this nodes children.
		if (pNewNode->Level != 0) ProcessNodeChildren(pNewNode, &CullList);
		// If we've reached sub-level 0 then store Cull List (for rendering).
		if (pNewNode->Level == 0)
		{
			// Store the render list from our culled object set.
			pNewNode->RenderList = CullList.mCulledObjectSet;
			// Keep track of the total billboard acquired.
			mBillboardsAcquired += CullList.GetListCount();
		}
	}
}

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

void fxFoliageReplicator::SyncFoliageReplicators(void)
{
	// Check Host.
	AssertFatal(isServerObject(), "We *MUST* be on server when Synchronising Foliage!")

	// Find the Replicator Set.
	SimSet *fxFoliageSet = dynamic_cast<SimSet*>(Sim::findObject("fxFoliageSet"));

	// Return if Error.
	if (!fxFoliageSet)
	{
		// Console Warning.
		Con::warnf("fxFoliageReplicator - Cannot locate the 'fxFoliageSet', this is bad!");
		// Return here.
		return;
	}

	// Parse Replication Object(s).
	for (SimSetIterator itr(fxFoliageSet); *itr; ++itr)
	{
		// Fetch the Replicator Object.
		fxFoliageReplicator* Replicator = static_cast<fxFoliageReplicator*>(*itr);
		// Set Foliage Replication Mask.
		if (Replicator->isServerObject())
		{
			Con::printf("fxFoliageReplicator - Restarting fxFoliageReplicator Object...");
			Replicator->setMaskBits(FoliageReplicationMask);
		}
	}

	// Info ...
	Con::printf("fxFoliageReplicator - Client Foliage Sync has completed.");
}


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

void fxFoliageReplicator::DestroyFoliage(void)

⌨️ 快捷键说明

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