📄 fxfoliagereplicator.cc
字号:
//-----------------------------------------------------------------------------
// Torque Game Engine
// Written by Melvyn May, Started on 4th August 2002.
//
// "My code is written for the Torque community, so do your worst with it,
// just don't rip-it-off and call it your own without even thanking me".
//
// - Melv.
//
//-----------------------------------------------------------------------------
#include "dgl/dgl.h"
#include "console/consoleTypes.h"
#include "core/bitStream.h"
#include "math/mRandom.h"
#include "math/mathIO.h"
#include "terrain/terrData.h"
#include "game/gameConnection.h"
#include "console/simBase.h"
#include "sceneGraph/sceneGraph.h"
#include "fxFoliageReplicator.h"
//------------------------------------------------------------------------------
//
// Put the function in /example/common/editor/ObjectBuilderGui.gui [around line 458] ...
//
// function ObjectBuilderGui::buildfxFoliageReplicator(%this)
// {
// %this.className = "fxFoliageReplicator";
// %this.process();
// }
//
//------------------------------------------------------------------------------
//
// Put this in /example/common/editor/EditorGui.cs in [function Creator::init( %this )]
//
// %Environment_Item[8] = "fxFoliageReplicator"; <-- ADD THIS.
//
//------------------------------------------------------------------------------
//
// Put this in /example/common/client/missionDownload.cs in [function clientCmdMissionStartPhase3(%seq,%missionName)] (line 65)
// after codeline 'onPhase2Complete();'.
//
// StartFoliageReplication();
//
//------------------------------------------------------------------------------
//
// Put this in /engine/console/simBase.h (around line 509) in
//
// namespace Sim
// {
// DeclareNamedSet(fxFoliageSet) <-- ADD THIS (Note no semi-colon).
//
//------------------------------------------------------------------------------
//
// Put this in /engine/console/simBase.cc (around line 19) in
//
// ImplementNamedSet(fxFoliageSet) <-- ADD THIS (Note no semi-colon).
//
//------------------------------------------------------------------------------
//
// Put this in /engine/console/simManager.cc [function void init()] (around line 269).
//
// namespace Sim
// {
// InstantiateNamedSet(fxFoliageSet); <-- ADD THIS (Including Semi-colon).
//
//------------------------------------------------------------------------------
extern bool gEditingMission;
//------------------------------------------------------------------------------
IMPLEMENT_CO_NETOBJECT_V1(fxFoliageReplicator);
//------------------------------------------------------------------------------
//
// Trig Table Lookups.
//
//------------------------------------------------------------------------------
static bool mTrigTableInitialised;
static F32 mCosTable[720];
static F32 mSinTable[720];
//------------------------------------------------------------------------------
//
// Class: fxFoliageRenderList
//
//------------------------------------------------------------------------------
void fxFoliageRenderList::SetupClipPlanes(SceneState* state, const F32 FarClipPlane)
{
// Fetch Camera Position.
CameraPosition = state->getCameraPosition();
// Calculate Perspective.
F32 FarOverNear = FarClipPlane / state->getNearPlane();
// Calculate Clip-Planes.
FarPosLeftUp = Point3F( state->getBaseZoneState().frustum[0] * FarOverNear,
FarClipPlane,
state->getBaseZoneState().frustum[3] * FarOverNear);
FarPosLeftDown = Point3F( state->getBaseZoneState().frustum[0] * FarOverNear,
FarClipPlane,
state->getBaseZoneState().frustum[2] * FarOverNear);
FarPosRightUp = Point3F( state->getBaseZoneState().frustum[1] * FarOverNear,
FarClipPlane,
state->getBaseZoneState().frustum[3] * FarOverNear);
FarPosRightDown = Point3F( state->getBaseZoneState().frustum[1] * FarOverNear,
FarClipPlane,
state->getBaseZoneState().frustum[2] * FarOverNear);
// Calculate our World->Object Space Transform.
MatrixF InvXForm = state->mModelview;
InvXForm.inverse();
// Convert to Object-Space.
InvXForm.mulP(FarPosLeftUp);
InvXForm.mulP(FarPosLeftDown);
InvXForm.mulP(FarPosRightUp);
InvXForm.mulP(FarPosRightDown);
// Calculate Bounding Box (including Camera).
mBox.min = CameraPosition;
mBox.min.setMin(FarPosLeftUp);
mBox.min.setMin(FarPosLeftDown);
mBox.min.setMin(FarPosRightUp);
mBox.min.setMin(FarPosRightDown);
mBox.max = CameraPosition;
mBox.max.setMax(FarPosLeftUp);
mBox.max.setMax(FarPosLeftDown);
mBox.max.setMax(FarPosRightUp);
mBox.max.setMax(FarPosRightDown);
// Setup Our Viewplane.
ViewPlanes[0].set(CameraPosition, FarPosLeftUp, FarPosLeftDown);
ViewPlanes[1].set(CameraPosition, FarPosRightUp, FarPosLeftUp);
ViewPlanes[2].set(CameraPosition, FarPosRightDown, FarPosRightUp);
ViewPlanes[3].set(CameraPosition, FarPosLeftDown, FarPosRightDown);
ViewPlanes[4].set(FarPosLeftUp, FarPosRightUp, FarPosRightDown);
}
//------------------------------------------------------------------------------
inline void fxFoliageRenderList::DrawQuadBox(const Box3F& QuadBox, const ColorF Colour)
{
// Define our debug box.
static Point3F BoxPnts[] = {
Point3F(0,0,0),
Point3F(0,0,1),
Point3F(0,1,0),
Point3F(0,1,1),
Point3F(1,0,0),
Point3F(1,0,1),
Point3F(1,1,0),
Point3F(1,1,1)
};
static U32 BoxVerts[][4] = {
{0,2,3,1}, // -x
{7,6,4,5}, // +x
{0,1,5,4}, // -y
{3,2,6,7}, // +y
{0,4,6,2}, // -z
{3,7,5,1} // +z
};
static Point3F BoxNormals[] = {
Point3F(-1, 0, 0),
Point3F( 1, 0, 0),
Point3F( 0,-1, 0),
Point3F( 0, 1, 0),
Point3F( 0, 0,-1),
Point3F( 0, 0, 1)
};
// Select the Box Colour.
glColor4fv(Colour);
// Project our Box Points.
Point3F ProjectionPoints[8];
for(U32 i = 0; i < 8; i++)
{
ProjectionPoints[i].set(BoxPnts[i].x ? QuadBox.max.x : QuadBox.min.x,
BoxPnts[i].y ? QuadBox.max.y : QuadBox.min.y,
BoxPnts[i].z ? (mHeightLerp * QuadBox.max.z) + (1-mHeightLerp) * QuadBox.min.z : QuadBox.min.z);
}
// Draw the Box.
for(U32 x = 0; x < 6; x++)
{
// Draw a line-loop.
glBegin(GL_LINE_LOOP);
for(U32 y = 0; y < 4; y++)
{
// Draw Vertex.
glVertex3f( ProjectionPoints[BoxVerts[x][y]].x,
ProjectionPoints[BoxVerts[x][y]].y,
ProjectionPoints[BoxVerts[x][y]].z);
}
glEnd();
}
}
//------------------------------------------------------------------------------
void fxFoliageRenderList::CompileVisibleSet(const fxFoliageQuadrantNode* pNode, const MatrixF& RenderTransform, const bool UseDebug)
{
// Attempt to trivially reject the Node.
//
// Is any of the quadrant visible?
if (IsQuadrantVisible(pNode->QuadrantBox, RenderTransform))
{
// Draw the Quad Box (Debug Only).
if (UseDebug) DrawQuadBox(pNode->QuadrantBox, ColorF(0,.8,.1,.2));
// Yes, so are we at sub-level 0?
if (pNode->Level == 0)
{
// Yes, so merge visible object set with node render list.
mVisObjectSet.merge(pNode->RenderList);
}
else
{
// No, so compile quadrants.
for (U32 q = 0; q < 4; q++)
if (pNode->QuadrantChildNode[q]) CompileVisibleSet(pNode->QuadrantChildNode[q], RenderTransform, UseDebug);
}
}
else
{
// Draw the Quad Box (Debug Only).
if (UseDebug) DrawQuadBox(pNode->QuadrantBox, ColorF(0,.1,8,.2));
}
return;
}
//------------------------------------------------------------------------------
bool fxFoliageRenderList::IsQuadrantVisible(const Box3F VisBox, const MatrixF& RenderTransform)
{
// Can we trivially accept the visible box?
if (mBox.isOverlapped(VisBox))
{
// Yes, so calculate Object-Space Box.
MatrixF InvXForm = RenderTransform;
InvXForm.inverse();
Box3F OSBox = VisBox;
InvXForm.mulP(OSBox.min);
InvXForm.mulP(OSBox.max);
// Yes, so fetch Box Center.
Point3F Center;
OSBox.getCenter(&Center);
// Scale.
Point3F XRad(OSBox.len_x() * 0.5, 0, 0);
Point3F YRad(0, OSBox.len_y() * 0.5, 0);
Point3F ZRad(0, 0, OSBox.len_z() * 0.5);
// Render Transformation.
RenderTransform.mulP(Center);
RenderTransform.mulV(XRad);
RenderTransform.mulV(YRad);
RenderTransform.mulV(ZRad);
// Check against View-planes.
for (U32 i = 0; i < 5; i++)
{
// Reject if not visible.
if (ViewPlanes[i].whichSideBox(Center, XRad, YRad, ZRad, Point3F(0, 0, 0)) == PlaneF::Back) return false;
}
// Visible.
return true;
}
// Not visible.
return false;
}
//------------------------------------------------------------------------------
//
// Class: fxFoliageCulledList
//
//------------------------------------------------------------------------------
fxFoliageCulledList::fxFoliageCulledList(Box3F SearchBox, fxFoliageCulledList* InVec)
{
// Find the Candidates.
FindCandidates(SearchBox, InVec);
}
//------------------------------------------------------------------------------
void fxFoliageCulledList::FindCandidates(Box3F SearchBox, fxFoliageCulledList* InVec)
{
// Search the Culled List.
for (U32 i = 0; i < InVec->GetListCount(); i++)
{
// Is this Box overlapping our search box?
if (SearchBox.isOverlapped(InVec->GetElement(i)->FoliageBox))
{
// Yes, so add it to our culled list.
mCulledObjectSet.push_back(InVec->GetElement(i));
}
}
}
//------------------------------------------------------------------------------
//
// Class: fxFoliageReplicator
//
//------------------------------------------------------------------------------
fxFoliageReplicator::fxFoliageReplicator()
{
// Setup NetObject.
mTypeMask |= StaticObjectType | StaticTSObjectType | StaticRenderedObjectType;
mAddedToScene = false;
mNetFlags.set(Ghostable | ScopeAlways);
// Reset Client Replication Started.
mClientReplicationStarted = false;
// Reset Foliage Count.
mCurrentFoliageCount = 0;
// Reset Creation Area Angle Animation.
mCreationAreaAngle = 0;
// Reset Last Render Time.
mLastRenderTime = 0;
// Reset Foliage Nodes.
mPotentialFoliageNodes = 0;
// Reset Billboards Acquired.
mBillboardsAcquired = 0;
// Reset Frame Serial ID.
mFrameSerialID = 0;
}
//------------------------------------------------------------------------------
fxFoliageReplicator::~fxFoliageReplicator()
{
}
//------------------------------------------------------------------------------
void fxFoliageReplicator::initPersistFields()
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -