📄 worldwall.cc
字号:
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#include "game/WorldWall.h"
#include "game/gameConnection.h"
#include "dgl/dgl.h"
#include "sceneGraph/sceneGraph.h"
#include "sceneGraph/sceneState.h"
#include "core/bitStream.h"
#include "console/consoleTypes.h"
#include "terrain/terrData.h"
#include "console/simBase.h"
#include "core/frameAllocator.h"
IMPLEMENT_CONOBJECT(WorldWall);
//bool WorldWall::ms_bWorldWallOn = true;
WorldWall* g_pWorldWall = 0;
void WorldWall::create()
{
// return;
if(g_pWorldWall)
return;
g_pWorldWall = new WorldWall();
g_pWorldWall->registerObject("WorldWall");
Sim::getRootGroup()->addObject(g_pWorldWall);
gClientContainer.addObject(g_pWorldWall);
gClientSceneGraph->addObjectToScene(g_pWorldWall);
}
void WorldWall::destroy()
{
// return;
if(g_pWorldWall==0)
return;
gClientSceneGraph->removeObjectFromScene(g_pWorldWall);
gClientContainer.removeObject(g_pWorldWall);
g_pWorldWall = 0;
}
WorldWall::WorldWall()
{
mTypeMask |= StaticObjectType;
//mNetFlags.set(Ghostable);//ScopeAlways
//mNetFlags.set(Ghostable|ScopeAlways);
//mNetFlags.set(IsGhost);
mGridAmount = 30;
mRenderWall = true;
mWallFillColor.set(0,0xe0,0,0x90);
mWallFrameColor.set(0,0xe0,0,0xff);
/// TGE_Debug
//#ifdef TORQUE_DEBUG
// mRenderGridLine = true;
// mRenderGridPlane = true;
// mGridFillColor.set(0x40,0x40,0xa0,0x50);
// mGridLineColor.set(0x90,0x40,0x40,0x50);
//#else
mRenderGridLine = false;
mRenderGridPlane = false;
mGridFillColor.set(0x40,0x40,0xa0,0x50);
mGridLineColor.set(0xa0,0xa0,0xa0,0x30);
//#endif
mGridSize.set(1.f,1.f,0.1f);
//mTypeMask |= DecalManagerObjectType;
mObjBox.min.set(-1e7, -1e7, -1e7);
mObjBox.max.set( 1e7, 1e7, 1e7);
mWorldBox.min.set(-1e7, -1e7, -1e7);
mWorldBox.max.set( 1e7, 1e7, 1e7);
}
WorldWall::~WorldWall()
{
}
void WorldWall::consoleInit()
{
//Con::addVariable("$pref::worldWallOn", TypeBool, &ms_bWorldWallOn);
}
void WorldWall::initPersistFields()
{
addField("renderWall", TypeBool, Offset(mRenderWall, WorldWall));
addField("wallFillColor", TypeColorI, Offset(mWallFillColor, WorldWall));
addField("wallFrameColor", TypeColorI, Offset(mWallFrameColor, WorldWall));
addField("renderGridLine", TypeBool, Offset(mRenderGridLine, WorldWall));
addField("gridAmount", TypeBool, Offset(mGridAmount, WorldWall));
addField("renderGridPlane", TypeBool, Offset(mRenderGridPlane, WorldWall));
addField("gridLineColor", TypeColorI, Offset(mGridLineColor, WorldWall));
addField("gridFillColor", TypeColorI, Offset(mGridFillColor, WorldWall));
addField("gridSize", TypePoint3F, Offset(mGridSize, WorldWall));
}
//--------------------------------------------------------------------------
//U32 WorldWall::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
//{
// U32 retMask = Parent::packUpdate(con, mask, stream);
//
// stream->write(mWallFillColor);
// stream->write(mWallFrameColor);
//
// return retMask;
//}
//
//
//
//void WorldWall::unpackUpdate(NetConnection* con, BitStream* stream)
//{
// Parent::unpackUpdate(con, stream);
//
// stream->read(&mWallFrameColor);
// stream->read(&mWallFillColor);
//
//}
/// Enable scoping so we can see this thing on the client.
void WorldWall::onEditorEnable()
{
setRenderGridLine(true);
//mNetFlags.set(Ghostable);
//setScopeAlways();
//addToScene();
//gClientContainer.addObject(g_pWorldWall);
//gClientSceneGraph->addObjectToScene(g_pWorldWall);
}
/// Disable scoping so we can see this thing on the client
void WorldWall::onEditorDisable()
{
setRenderGridLine(false);
//removeFromScene();
//mNetFlags.clear(Ghostable);
//clearScopeAlways();
}
bool WorldWall::prepRenderImage(SceneState* state, const U32 stateKey,
const U32 /*startZone*/, const bool /*modifyBaseState*/)
{
if (!mWallFrameColor && !mRenderGridPlane && !mRenderGridLine) return false;
// This should be sufficient for most objects that don't manage zones, and
// don't need to return a specialized RenderImage...
SceneRenderImage* image = new SceneRenderImage;
image->obj = this;
image->isTranslucent = true;
image->sortType = SceneRenderImage::BeginSort;
state->insertRenderImage(image);
return true;
}
void WorldWall::renderObject(SceneState* state, SceneRenderImage*)
{
if (!mWallFrameColor && !mRenderGridPlane && !mRenderGridLine) return;
AssertFatal(dglIsInCanonicalState(), "Error, GL not in canonical state on entry");
RectI viewport;
glMatrixMode(GL_PROJECTION);
glPushMatrix();
dglGetViewport(&viewport);
state->setupBaseProjection();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glDisable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
renderWorldWall();
glDisable(GL_BLEND);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
dglSetViewport(viewport);
AssertFatal(dglIsInCanonicalState(), "Error, GL not in canonical state on exit");
}
void WorldWall::renderWorldWall()
{
TerrainBlock * terrain = dynamic_cast<TerrainBlock*>(Sim::findObject("Terrain"));
if(!terrain)
return;
const MatrixF & terrMat = terrain->getTransform();
Point3F terrPos;
terrMat.getColumn(3, &terrPos);
F32 terrDim = F32(terrain->getSquareSize() * TerrainBlock::BlockSize );
RectF area(terrPos.x,terrPos.y, terrDim, terrDim);
GridSquare * gs = terrain->findSquare(TerrainBlock::BlockShift, Point2I(0,0));
F32 height = F32(gs->maxHeight) * 0.03125f + 20.f;
renderCuboidFrame(area, height,mWallFillColor,mWallFrameColor);
//尝试以人物为中心,渲染宽高为mGridAmount的平面
GameConnection * connection = GameConnection::getConnectionToServer();
ShapeBase * obj = 0;
if(connection)
obj = connection->getControlObject();
if(obj)
{
Point3F pos = obj->getPosition();
area.point.set(mFloor(pos.x)-mGridAmount,mFloor(pos.y)-mGridAmount);
area.extent.set(mGridAmount<<1,mGridAmount<<1);
mGridSize.z = pos.z;
}
renderTerrainGrid(area);//, mGridFillColor,mGridLineColor,mRenderGridPlane,mRenderGridLine);
//renderGrid(area, mGridSize,mGridFillColor,mGridLineColor,mRenderGridPlane,mRenderGridLine);
}
void WorldWall::renderCuboidFrame(const RectF &area, F32 height, ColorI & a,ColorI & b)
{
Point2F min(area.point.x, area.point.y);
Point2F max(area.point.x + area.extent.x, area.point.y + area.extent.y);
for(U32 i = 0; i < 2; i++)
{
//
if(i){glColor4ub(a.red,a.green,a.blue,a.alpha);glBegin(GL_QUADS);} else {glColor4f(b.red,b.green,b.blue,b.alpha); glBegin(GL_LINE_LOOP);}
glVertex3f(min.x, min.y, 0);
glVertex3f(max.x, min.y, 0);
glVertex3f(max.x, min.y, height);
glVertex3f(min.x, min.y, height);
glEnd();
//
if(i){glColor4ub(a.red,a.green,a.blue,a.alpha);glBegin(GL_QUADS);} else {glColor4f(b.red,b.green,b.blue,b.alpha); glBegin(GL_LINE_LOOP);}
glVertex3f(min.x, max.y, 0);
glVertex3f(max.x, max.y, 0);
glVertex3f(max.x, max.y, height);
glVertex3f(min.x, max.y, height);
glEnd();
//
if(i){glColor4ub(a.red,a.green,a.blue,a.alpha);glBegin(GL_QUADS);} else {glColor4f(b.red,b.green,b.blue,b.alpha); glBegin(GL_LINE_LOOP);}
glVertex3f(min.x, min.y, 0);
glVertex3f(min.x, max.y, 0);
glVertex3f(min.x, max.y, height);
glVertex3f(min.x, min.y, height);
glEnd();
//
if(i){glColor4ub(a.red,a.green,a.blue,a.alpha);glBegin(GL_QUADS);} else {glColor4f(b.red,b.green,b.blue,b.alpha); glBegin(GL_LINE_LOOP);}
glVertex3f(max.x, min.y, 0);
glVertex3f(max.x, max.y, 0);
glVertex3f(max.x, max.y, height);
glVertex3f(max.x, min.y, height);
glEnd();
}
}
void WorldWall::renderGrid(const RectF &area, Point3F& grid, ColorI & a,ColorI & b,bool bRenderPlane,bool bRenderLine)
{
const Point2F &start = area.point;
const Point2F &extent = area.extent;
F32 height = grid.z;
//绘画地平面
// draw the plane
if(bRenderPlane)
{
glColor4ub(a.red, a.green, a.blue, a.alpha);
glBegin(GL_QUADS);
glVertex3f(start.x, start.y, height);
glVertex3f(start.x, start.y + extent.y, height);
glVertex3f(start.x + extent.x, start.y + extent.y, height);
glVertex3f(start.x + extent.x, start.y, height);
glEnd();
}
//绘画网格线
if(bRenderLine)
{
glColor4ub(b.red, b.green, b.blue, b.alpha);
if(grid.x > 0)
{
U32 xSteps = (U32)(extent.x / grid.x);
F32 hashStart = mCeil(start.x / grid.x) * grid.x;
for(U32 i = 0; i < xSteps; i++)
{
glBegin(GL_LINE_LOOP);
glVertex3f(hashStart + grid.x * i, start.y, height + 0.001f);
glVertex3f(hashStart + grid.x * i, start.y + extent.y, height + 0.001f);
glEnd();
}
}
if(grid.y > 0)
{
U32 ySteps = (U32)(extent.y / grid.y);
F32 hashStart = mCeil(start.y / grid.y) * grid.y;
for(U32 i = 0; i < ySteps; i++)
{
glBegin(GL_LINE_LOOP);
glVertex3f(start.x, hashStart + grid.y * i, height + 0.001f);
glVertex3f(start.x + extent.x, hashStart + grid.y * i, height + 0.001f);
glEnd();
}
}
}
}
void WorldWall::renderTerrainGridSquare(S32 xPos,S32 yPos)//, ColorI & a, ColorI & b)
{
if(g_pTerrainBlock == 0)
return;
// 1.先生成插值高度数组
S32 squareSize = g_pTerrainBlock->getSquareSize();
U32 uWaterMark = FrameAllocator::getWaterMark();
F32* pHeights = (F32*)FrameAllocator::alloc((squareSize+1)*(squareSize+1)*sizeof(F32));
g_pTerrainBlock->getHeights(Point2F((float)xPos,(float)yPos),pHeights);
for(U32 row=0; row < squareSize; row++)
{
F32 y = (float)(yPos + (S32)row);
if(y < 0)
continue;
F32* pRows = pHeights + row * (squareSize+1);
for(U32 col=0; col < squareSize; col++)
{
F32 x = (float)(xPos + (S32)col);
if(x < 0)
continue;
if(mRenderGridLine)
{
/////////////////////////////////
/// 绘画线框
glBegin(GL_LINES);
/// 边界线用补色绘画,绘画 左线(0,0--1,0 )、下线(0,0--0,1)
/// 绘画 左线(0,0--1,0 )
if(row == 0)
glColor4ub(~mGridLineColor.red, ~mGridLineColor.green, ~mGridLineColor.blue, 0xff);
else
glColor4ub(mGridLineColor.red, mGridLineColor.green, mGridLineColor.blue, mGridLineColor.alpha);
glVertex3f(x, y, pRows[col] );
glVertex3f(x + 1, y, pRows[col + 1] );
/// 绘画 下线(0,0--0,1)
if(col == 0)
glColor4ub(~mGridLineColor.red, ~mGridLineColor.green, ~mGridLineColor.blue, 0xff);
else if(row == 0)
glColor4ub(mGridLineColor.red, mGridLineColor.green, mGridLineColor.blue, mGridLineColor.alpha);
glVertex3f(x, y, pRows[col] );
glVertex3f(x, y+1, pRows[squareSize+1 + col] );
glEnd();
}
/////////////////////////////////
/// 绘画步行障碍标志面
if(mRenderGridPlane && g_pTerrainBlock->isBlockAt(x,y) )
{
glBegin(GL_QUADS);
glColor4ub(mGridFillColor.red, mGridFillColor.green, mGridFillColor.blue, mGridFillColor.alpha);
glVertex3f(x, y, pRows[col] );
glVertex3f(x + 1, y, pRows[col + 1] );
glVertex3f(x + 1, y+1, pRows[squareSize+1 + col + 1] );
glVertex3f(x, y+1, pRows[squareSize+1 + col] );
glEnd();
}
}//for
}//for
FrameAllocator::setWaterMark(uWaterMark);
}
void WorldWall::renderTerrainGrid(const RectF &area)//, ColorI & a,ColorI & b,bool bRenderPlane,bool bRenderLine)
{
if(g_pTerrainBlock == 0 || (mRenderGridPlane == false && mRenderGridLine == false) )
return;
S32 squareSize = g_pTerrainBlock->getSquareSize();
float invSquareSize = 1.0f / (float)squareSize;
S32 xStart = mFloor(area.point.x * invSquareSize) * squareSize;
S32 yStart = mFloor(area.point.y * invSquareSize) * squareSize;
S32 xEnd = xStart + mFloor(area.extent.x * invSquareSize) * squareSize;
S32 yEnd = yStart + mFloor(area.extent.y * invSquareSize) * squareSize;
for(S32 y = yStart; y < yEnd; y+=squareSize)
{
for(S32 x = xStart; x < xEnd; x+=squareSize)
{
renderTerrainGridSquare(x,y);
}//for
}//for
}
//------------------------------------------------------------------------------
ConsoleFunction(setRenderGridLine,void,2,2,"setRenderGridLine(bool bSet)")
{
argc;
if(g_pWorldWall)
{
g_pWorldWall->setRenderGridLine(dAtob(argv[1]));
}
}
ConsoleFunction(setRenderWall,void,2,2,"setRenderWall(bool bSet)")
{
argc;
if(g_pWorldWall)
{
g_pWorldWall->setRenderWall(dAtob(argv[1]));
}
}
ConsoleFunction(setRenderGridPlane,void,2,2,"setRenderGridPlane(bool bSet)")
{
argc;
if(g_pWorldWall)
{
g_pWorldWall->setRenderGridPlane(dAtob(argv[1]));
}
}
ConsoleFunction(isRenderGridLine,bool,1,1,"isRenderGridLine()")
{
argc;
if(g_pWorldWall)
return g_pWorldWall->isRenderGridLine();
return false;
}
ConsoleFunction(isRenderWall,bool,1,1,"isRenderWall()")
{
argc;
if(g_pWorldWall)
return g_pWorldWall->isRenderWall();
return false;
}
ConsoleFunction(isRenderGridPlane,bool,1,1,"isRenderGridPlane()")
{
argc;
if(g_pWorldWall)
return g_pWorldWall->isRenderGridPlane();
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -