📄 showtsshape.cc
字号:
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#include "game/showTSShape.h"
//#include "gui/core/guiControl.h"
//#include "gui/core/guiTSControl.h"
#include "gui/controls/guiTextCtrl.h"
#include "gui/controls/guiTextListCtrl.h"
#include "gui/controls/guiSliderCtrl.h"
#include "gui/controls/guiTextEditCtrl.h"
#include "gui/core/guiCanvas.h"
#include "sceneGraph/sceneGraph.h"
#include "sceneGraph/sceneState.h"
#include "console/consoleTypes.h"
#include "terrain/terrData.h"
#include "terrain/terrRender.h"
ShowTSShape * ShowTSShape::currentShow = NULL;
Vector<char *> ShowTSShape::loadQueue(__FILE__, __LINE__);
const char * emapName[] = { "emap.bmp" };
MaterialList emapList(1,emapName);
F32 emapAlpha = 0.0f;
F32 ambR = 0.7f;
F32 ambB = 0.7f;
F32 ambG = 0.7f;
F32 diffR = 0.9f;
F32 diffB = 0.9f;
F32 diffG = 0.9f;
Point4F lightDir(0.57f,0.57f,-0.57f,0.0f);
bool gInitLightingSliders = false;
//------------------------------------------------------------
// simple camera methods and variables
//------------------------------------------------------------
Point3F camPos;
MatrixF cameraMatrix;
EulerF camRot;
F32 gShowForwardAction = 0.0f;
F32 gShowBackwardAction = 0.0f;
F32 gShowUpAction = 0.0f;
F32 gShowDownAction = 0.0f;
F32 gShowLeftAction = 0.0f;
F32 gShowRightAction = 0.0f;
F32 gShowMovementSpeed = 1.0f;
float initialShowDistance = 20.0f;
Point3F * orbitPos = NULL;
float orbitDist = 10.0f;
float minOrbitDist = 1.0f;
float maxOrbitASin = 0.2f;
bool keyboardControlsShape = false;
float gShowShapeLeftSpeed = 0.0f;
float gShowShapeRightSpeed = 0.0f;
void setOrbit(Point3F * orb, bool useCurrentDist)
{
orbitPos = orb;
if (!useCurrentDist)
{
Point3F vec;
cameraMatrix.getColumn(1, &vec);
orbitDist = mDot(vec,*orbitPos-camPos);
}
if (orbitDist<minOrbitDist)
orbitDist = minOrbitDist;
}
void setOrbit(Point3F * orb, float newOrbitDist)
{
orbitPos = orb;
orbitDist = newOrbitDist;
if (orbitDist<minOrbitDist)
orbitDist = minOrbitDist;
}
void setDetailSlider()
{
ShowTSShape * currentShow = ShowTSShape::currentShow;
if (!currentShow)
return;
GuiSliderCtrl * slider = static_cast<GuiSliderCtrl*>(Sim::findObject("showDetailSlider"));
if (!slider)
return;
// find current detail level and number of detail levels of currentShow
S32 dl = currentShow->getCurrentDetail();
S32 numDL = currentShow->getNumDetails();
// set slider range to be correct
slider->setField("range",avar("0 %g",-0.01f + (F32)numDL));
// set slider ticks to be correct
slider->setField("ticks",avar("%i",numDL));
// set slider value to be correct
slider->setField("value",avar("%i",dl));
}
//------------------------------------------------------------
// show gui related methods
//------------------------------------------------------------
void showUpdateThreadControl()
{
char buffer[32];
// update dialogs
GuiTextListCtrl * threadList = dynamic_cast<GuiTextListCtrl*>(Sim::findObject("threadList"));
GuiTextListCtrl * sequenceList = dynamic_cast<GuiTextListCtrl*>(Sim::findObject("sequenceList"));
if (!threadList || !sequenceList)
{
// just for debugging, look up w/o dynamic cast...
threadList = threadList ? NULL : static_cast<GuiTextListCtrl*>(Sim::findObject("threadList"));
sequenceList = sequenceList ? NULL : static_cast<GuiTextListCtrl*>(Sim::findObject("sequenceList"));
AssertFatal(!threadList && !sequenceList,"showUpdateThreadControl: threadList or sequenceList of wrong gui type");
// something wrong, just exit
return;
}
ShowTSShape * currentShow = ShowTSShape::currentShow;
if (!currentShow)
{
// no current show...zero out lists
threadList->clear();
sequenceList->clear();
return;
}
// the thread list:
threadList->setCellSize(Point2I(threadList->mBounds.extent.x,16));
U32 count = currentShow->getThreadCount();
if(count != threadList->getNumEntries())
{
threadList->clear();
for(U32 i = 0; i < count; i++)
{
dSprintf(buffer, sizeof(buffer), "%i", i);
threadList->addEntry(i, buffer);
}
}
S32 selectedThread = threadList->getSelectedCell().y;
if (threadList->getNumEntries()==0 && selectedThread>=0)
// no threads, select nothing...
threadList->deselectCells();
else if (threadList->getNumEntries()>0 && selectedThread<0)
// we have threads but nothing selected...
threadList->setSelectedCell(Point2I(0,0));
selectedThread = threadList->getSelectedCell().y;
// the sequence list:
sequenceList->setCellSize(Point2I(sequenceList->mBounds.extent.x,16));
// only change the text if it needs changing ... this avoids infinite loops since
// changing text can result in this routine getting called again
S32 i;
for (i=0; i<currentShow->getSequenceCount() && i<sequenceList->getNumEntries(); i++)
if (dStrcmp(currentShow->getSequenceName(i),sequenceList->mList[i].text))
break;
while (i<sequenceList->getNumEntries())
sequenceList->removeEntryByIndex(i);
for (; i<currentShow->getSequenceCount(); i++)
sequenceList->addEntry(i, currentShow->getSequenceName(i));
if (selectedThread==-1)
{
if (sequenceList->getSelectedCell().y >= 0)
sequenceList->deselectCells();
}
else if (sequenceList->getSelectedCell().y != currentShow->getSequenceNum(selectedThread))
sequenceList->setSelectedCell(Point2I(0,currentShow->getSequenceNum(selectedThread)));
// update displayed scale value
GuiTextCtrl * text = dynamic_cast<GuiTextCtrl*>(Sim::findObject("showScaleValue"));
if (text && selectedThread>=0)
{
dSprintf(buffer,32,"scale = %2.2f",currentShow->getThreadScale(selectedThread));
text->setText(buffer);
}
}
//------------------------------------------------------------
// basic class for displaying a tsshape
//------------------------------------------------------------
ShowTSShape::ShowTSShape(const char * shapeName)
{
mTypeMask = StaticObjectType;
shapeInstance = NULL;
dStrcpy(shapeNameBuffer,shapeName);
timeScale = 1.0f;
addGround = false;
stayGrounded = true;
char fileBuffer[512];
dStrcpy(fileBuffer,shapeName);
// before loading shape, execute associated script
char *ext = dStrstr( static_cast<char*>( fileBuffer ), const_cast<char*>( ".dts" ) );
if (ext)
{
ext[1]='c';
ext[2]='s';
ext[3]='\0';
Con::executef(2,"exec",fileBuffer);
ext[1]='d';
ext[2]='t';
ext[3]='s';
}
Resource<TSShape> hShape;
hShape = ResourceManager->load(fileBuffer);
if (!bool(hShape))
return;
shapeInstance = new TSShapeInstance(hShape, true);
emapList.load(MeshTexture,0,true);
shapeInstance->setEnvironmentMap(emapList.getMaterial(0));
newThread(); // does nothing if shape has no sequences
// // TODO: fix this in exporter at some point...
Point3F & center = const_cast<Point3F&>(shapeInstance->getShape()->center);
center = shapeInstance->getShape()->bounds.min + shapeInstance->getShape()->bounds.max;
center *= 0.5f;
mat.identity();
setPosition(camPos);
}
//--------------------------------------------------------------------------
bool ShowTSShape::prepRenderImage(SceneState* state, const U32 stateKey,
const U32 /*startZone*/, const bool /*modifyBaseState*/)
{
if (isLastState(state, stateKey))
return false;
setLastState(state, stateKey);
SceneRenderImage* image = new SceneRenderImage;
image->obj = this;
image->isTranslucent = true;
image->sortType = SceneRenderImage::EndSort;
state->insertRenderImage(image);
return false;
}
void ShowTSShape::renderObject(SceneState* state, SceneRenderImage*)
{
AssertFatal(dglIsInCanonicalState(), "Error, GL not in canonical state on entry");
RectI viewport;
glMatrixMode(GL_PROJECTION);
glPushMatrix();
dglGetViewport(&viewport);
state->setupObjectProjection(this);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
dglMultMatrix(&mObjToWorld);
glScalef(mObjScale.x, mObjScale.y, mObjScale.z);
render();
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
dglSetViewport(viewport);
AssertFatal(dglIsInCanonicalState(), "Error, GL not in canonical state on exit");
}
//--------------------------------------
bool ShowTSShape::onAdd()
{
mWorldToObj = mObjToWorld;
mWorldToObj.affineInverse();
resetWorldBox();
if (!Parent::onAdd() || !shapeInstance)
// shape instantiation failed
return false;
// make us the center of attention
orbitUs();
// We're always a client object...
gClientContainer.addObject(this);
gClientSceneGraph->addObjectToScene(this);
mObjBox = shapeInstance->getShape()->bounds;
resetWorldBox();
SimSet * showSet = static_cast<SimSet*>(Sim::findObject("showSet"));
if (!showSet)
{
showSet = new SimSet;
showSet->registerObject("showSet");
Sim::getRootGroup()->addObject(showSet);
}
showSet->addObject(this);
currentShow = this;
return true;
}
void ShowTSShape::onRemove()
{
gClientSceneGraph->removeObjectFromScene(this);
gClientContainer.removeObject(this);
if (this == currentShow)
{
currentShow = NULL;
showUpdateThreadControl();
}
Parent::onRemove();
}
ShowTSShape::~ShowTSShape()
{
delete shapeInstance;
if (orbitPos == ¢erPos)
orbitPos = NULL;
}
void ShowTSShape::newThread()
{
if (shapeInstance->getShape()->sequences.empty())
return;
threads.increment();
threads.last() = shapeInstance->addThread();
play.push_back(true);
scale.push_back(1.0f);
}
void ShowTSShape::deleteThread(S32 th)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -