1082 lines
31 KiB
C++
Executable File
1082 lines
31 KiB
C++
Executable File
//-----------------------------------------------------------------------------
|
|
// 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)
|
|
{
|
|
if (th<0 || th>=threads.size())
|
|
return;
|
|
|
|
shapeInstance->destroyThread(threads[th]);
|
|
threads.erase(th);
|
|
play.erase(th);
|
|
scale.erase(th);
|
|
}
|
|
|
|
void ShowTSShape::setPosition(Point3F p)
|
|
{
|
|
if (stayGrounded && gClientSceneGraph->getCurrentTerrain())
|
|
// won't actually change p.z if on empty square
|
|
gClientSceneGraph->getCurrentTerrain()->getHeight(Point2F(p.x,p.y),&p.z);
|
|
|
|
centerPos = p + shapeInstance->getShape()->center;
|
|
mat.setColumn(3,p);
|
|
setTransform(mat);
|
|
}
|
|
|
|
void ShowTSShape::addGroundTransform(const MatrixF & ground)
|
|
{
|
|
// add some ground transform to our current transform
|
|
MatrixF m;
|
|
m.mul(mat,ground);
|
|
mat = m;
|
|
Point3F p;
|
|
mat.getColumn(3,&p);
|
|
setPosition(p);
|
|
}
|
|
|
|
void ShowTSShape::orbitUs()
|
|
{
|
|
// make us the center of attention
|
|
minOrbitDist = shapeInstance->getShape()->radius;
|
|
setOrbit(¢erPos,false);
|
|
}
|
|
|
|
bool ShowTSShape::handleMovement(F32 leftSpeed, F32 rightSpeed,
|
|
F32 forwardSpeed, F32 backwardSpeed,
|
|
F32 upSpeed, F32 downSpeed,
|
|
F32 delta)
|
|
{
|
|
if (!currentShow)
|
|
return false;
|
|
|
|
Point3F vec,p;
|
|
|
|
// turn shape left/right
|
|
F32 turnLR = (gShowShapeRightSpeed-gShowShapeLeftSpeed) * delta * 0.1f;
|
|
MatrixF turn(EulerF(0,0,turnLR));
|
|
currentShow->addGroundTransform(turn);
|
|
|
|
if (keyboardControlsShape && currentShow)
|
|
{
|
|
currentShow->getFeetPosition(&p);
|
|
|
|
// the following moves shape with camera orthoganol to world
|
|
// depends on camera not having roll
|
|
|
|
cameraMatrix.getColumn(0, &vec);
|
|
vec.z = 0.0f;
|
|
vec.normalize();
|
|
p += vec * (rightSpeed - leftSpeed) * delta;
|
|
if (!orbitPos)
|
|
// move camera with shape
|
|
camPos += vec * (rightSpeed - leftSpeed) * delta;
|
|
|
|
cameraMatrix.getColumn(1, &vec);
|
|
vec.z = 0.0f;
|
|
vec.normalize();
|
|
p += vec * (forwardSpeed - backwardSpeed) * delta;
|
|
if (!orbitPos)
|
|
// move camera with shape
|
|
camPos += vec * (forwardSpeed - backwardSpeed) * delta;
|
|
|
|
vec.set(0,0,1.0f);
|
|
p += vec * (upSpeed - downSpeed) * delta;
|
|
if (!orbitPos)
|
|
// move camera with shape
|
|
camPos += vec * (upSpeed - downSpeed) * delta;
|
|
|
|
currentShow->setPosition(p);
|
|
|
|
// if orbit cam is on, zero out speeds and adjust like normal
|
|
// if not, let normal camera move us with these speeds...
|
|
if (orbitPos)
|
|
leftSpeed = rightSpeed = forwardSpeed = backwardSpeed = upSpeed = downSpeed = 0.0f;
|
|
}
|
|
|
|
if (!orbitPos)
|
|
return false;
|
|
|
|
// forward/backward = closer/farther
|
|
|
|
orbitDist -= (forwardSpeed - backwardSpeed) * delta;
|
|
if (orbitDist<minOrbitDist)
|
|
orbitDist = minOrbitDist;
|
|
F32 invD = orbitDist>0.001f ? 1.0f / orbitDist : 0.0f;
|
|
|
|
// up/down & left/right = rotate
|
|
|
|
F32 xr = (upSpeed-downSpeed) * invD * delta; // convert linear speed to angular
|
|
F32 zr = (leftSpeed-rightSpeed) * invD * delta; // convert linear speed to angular
|
|
|
|
// cap rotation rate (for when you're real close to orbit point)
|
|
if (xr > maxOrbitASin)
|
|
xr = maxOrbitASin;
|
|
else if (xr < -maxOrbitASin)
|
|
xr = -maxOrbitASin;
|
|
if (zr > maxOrbitASin)
|
|
zr = maxOrbitASin;
|
|
else if (zr < -maxOrbitASin)
|
|
zr = -maxOrbitASin;
|
|
|
|
camRot.x += mAsin(xr);
|
|
camRot.z += mAsin(zr);
|
|
|
|
MatrixF xRot, zRot, newCameraRot;
|
|
xRot.set(EulerF(camRot.x, 0, 0));
|
|
zRot.set(EulerF(0, 0, camRot.z));
|
|
newCameraRot.mul(zRot,xRot);
|
|
|
|
// adjust cameraPos so we still face orbitPos (and are still d units away)
|
|
newCameraRot.getColumn(1,&vec);
|
|
vec *= orbitDist;
|
|
camPos = *orbitPos - vec;
|
|
|
|
return true;
|
|
}
|
|
|
|
void ShowTSShape::render()
|
|
{
|
|
bool wasLit = glIsEnabled(GL_LIGHTING);
|
|
bool wasLit0 = glIsEnabled(GL_LIGHT0);
|
|
|
|
glEnable(GL_LIGHTING);
|
|
glEnable(GL_LIGHT0);
|
|
|
|
glLightfv(GL_LIGHT0,GL_POSITION,(float*)&lightDir);
|
|
|
|
GLfloat amb[] = {ambR,ambG,ambB,0.0f};
|
|
GLfloat diff[] = {diffR,diffG,diffB,1.0f};
|
|
GLfloat matProp[] = {1.0f,1.0f,1.0f,1.0f};
|
|
GLfloat zeroColor[] = {0,0,0,0};
|
|
|
|
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,amb);
|
|
glLightfv(GL_LIGHT0,GL_DIFFUSE,diff);
|
|
glLightfv(GL_LIGHT0,GL_AMBIENT,zeroColor);
|
|
glLightfv(GL_LIGHT0,GL_SPECULAR,zeroColor);
|
|
|
|
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,matProp);
|
|
glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,zeroColor);
|
|
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,zeroColor);
|
|
|
|
// glPushMatrix();
|
|
// dglMultMatrix(&mat);
|
|
|
|
shapeInstance->setEnvironmentMapOn(true,emapAlpha);
|
|
|
|
if (Con::getBoolVariable("$showAutoDetail",false))
|
|
{
|
|
shapeInstance->selectCurrentDetail();
|
|
GuiSliderCtrl * slider = static_cast<GuiSliderCtrl*>(Sim::findObject("showDetailSlider"));
|
|
// set slider value to be correct
|
|
if (slider && slider->mAwake)
|
|
{
|
|
char buffer[32];
|
|
dSprintf(buffer,32,"%g",(F32)shapeInstance->getCurrentDetail()+1.0f-shapeInstance->getCurrentIntraDetail());
|
|
slider->setScriptValue(buffer);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
GuiSliderCtrl * slider = static_cast<GuiSliderCtrl*>(Sim::findObject("showDetailSlider"));
|
|
// set current detail level based on slider
|
|
if (slider)
|
|
shapeInstance->setCurrentDetail((S32)slider->getValue(),1.0f-(F32)((F32)slider->getValue()-(S32)slider->getValue()));
|
|
}
|
|
GuiTextCtrl * detailText1 = static_cast<GuiTextCtrl*>(Sim::findObject("showDetailInfoText1"));
|
|
GuiTextCtrl * detailText2 = static_cast<GuiTextCtrl*>(Sim::findObject("showDetailInfoText2"));
|
|
if (detailText1 && detailText2)
|
|
{
|
|
char buffer[128];
|
|
S32 dl = shapeInstance->getCurrentDetail();
|
|
S32 dlSize = (S32) (dl>=0 ? shapeInstance->getShape()->details[dl].size : 0);
|
|
S32 polys = dl>=0 ? shapeInstance->getShape()->details[dl].polyCount : 0;
|
|
Point3F p;
|
|
mObjToWorld.getColumn(3,&p);
|
|
p -= camPos;
|
|
F32 dist = p.len();
|
|
F32 pixelSize = dglProjectRadius(dist,shapeInstance->getShape()->radius) * dglGetPixelScale() * TSShapeInstance::smDetailAdjust;
|
|
dSprintf(buffer,128,"detail level: %i, detail size: %i",dl,dlSize);
|
|
detailText1->setText(buffer);
|
|
dSprintf(buffer,128,"size: %g, polys: %i, dist: %g",pixelSize,polys,dist);
|
|
detailText2->setText(buffer);
|
|
}
|
|
|
|
shapeInstance->animate();
|
|
|
|
shapeInstance->render();
|
|
|
|
// glPopMatrix();
|
|
|
|
if (!wasLit)
|
|
glDisable(GL_LIGHTING);
|
|
if (!wasLit0)
|
|
glDisable(GL_LIGHT0);
|
|
}
|
|
|
|
void ShowTSShape::reset()
|
|
{
|
|
SimSet * set = static_cast<SimSet*>(Sim::findObject("showSet"));
|
|
if (!set)
|
|
return;
|
|
|
|
for (SimSet::iterator itr = set->begin(); itr!=set->end(); itr++)
|
|
static_cast<ShowTSShape*>(*itr)->resetInstance();
|
|
}
|
|
|
|
void ShowTSShape::resetInstance()
|
|
{
|
|
// do nothing for now...
|
|
// eventually, may need to delete shape and then reload it, but seems to work fine now
|
|
}
|
|
|
|
void ShowTSShape::advanceTime(U32 delta)
|
|
{
|
|
// get the show set...
|
|
SimSet * set = static_cast<SimSet*>(Sim::findObject("showSet"));
|
|
|
|
// update the instances...
|
|
if (set)
|
|
for (SimSet::iterator itr = set->begin(); itr!=set->end(); itr++)
|
|
static_cast<ShowTSShape*>(*itr)->advanceTimeInstance(delta);
|
|
|
|
// set thread position slider
|
|
GuiSliderCtrl * slider = static_cast<GuiSliderCtrl*>(Sim::findObject("threadPosition"));
|
|
GuiTextListCtrl * threadList = static_cast<GuiTextListCtrl*>(Sim::findObject("threadList"));
|
|
GuiTextCtrl * transitionSignal = static_cast<GuiTextCtrl*>(Sim::findObject("transitionSignal"));
|
|
bool inTransition = false;
|
|
if (currentShow && threadList && slider && slider->mAwake && threadList->getSelectedCell().y>=0)
|
|
{
|
|
S32 th = threadList->getSelectedCell().y;
|
|
if (currentShow->getPlay(th))
|
|
{
|
|
char buffer[32];
|
|
dSprintf(buffer,32,"%g",currentShow->getPos(th));
|
|
slider->setScriptValue(buffer);
|
|
}
|
|
else
|
|
currentShow->setPos(th,slider->getValue());
|
|
|
|
inTransition = currentShow->isInTransition(th);
|
|
}
|
|
|
|
if (transitionSignal)
|
|
{
|
|
if (inTransition)
|
|
transitionSignal->setText("T");
|
|
else
|
|
transitionSignal->setText(" ");
|
|
}
|
|
|
|
if (!gInitLightingSliders)
|
|
{
|
|
char buffer[32];
|
|
slider = static_cast<GuiSliderCtrl*>(Sim::findObject("emapAlpha"));
|
|
if (slider)
|
|
{
|
|
dSprintf(buffer,32,"%g",emapAlpha);
|
|
slider->setField("value",buffer);
|
|
}
|
|
slider = static_cast<GuiSliderCtrl*>(Sim::findObject("ambR"));
|
|
if (slider)
|
|
{
|
|
dSprintf(buffer,32,"%g",ambR);
|
|
slider->setField("value",buffer);
|
|
}
|
|
slider = static_cast<GuiSliderCtrl*>(Sim::findObject("ambG"));
|
|
if (slider)
|
|
{
|
|
dSprintf(buffer,32,"%g",ambG);
|
|
slider->setField("value",buffer);
|
|
}
|
|
slider = static_cast<GuiSliderCtrl*>(Sim::findObject("ambB"));
|
|
if (slider)
|
|
{
|
|
dSprintf(buffer,32,"%g",ambB);
|
|
slider->setField("value",buffer);
|
|
}
|
|
slider = static_cast<GuiSliderCtrl*>(Sim::findObject("diffR"));
|
|
if (slider)
|
|
{
|
|
dSprintf(buffer,32,"%g",diffR);
|
|
slider->setField("value",buffer);
|
|
}
|
|
slider = static_cast<GuiSliderCtrl*>(Sim::findObject("diffG"));
|
|
if (slider)
|
|
{
|
|
dSprintf(buffer,32,"%g",diffG);
|
|
slider->setField("value",buffer);
|
|
}
|
|
slider = static_cast<GuiSliderCtrl*>(Sim::findObject("diffB"));
|
|
if (slider)
|
|
{
|
|
dSprintf(buffer,32,"%g",diffB);
|
|
slider->setField("value",buffer);
|
|
}
|
|
gInitLightingSliders = true;
|
|
}
|
|
|
|
// handle lighting sliders...
|
|
slider = static_cast<GuiSliderCtrl*>(Sim::findObject("emapAlpha"));
|
|
if (slider)
|
|
emapAlpha = slider->getValue();
|
|
slider = static_cast<GuiSliderCtrl*>(Sim::findObject("ambR"));
|
|
if (slider)
|
|
ambR = slider->getValue();
|
|
slider = static_cast<GuiSliderCtrl*>(Sim::findObject("ambG"));
|
|
if (slider)
|
|
ambG = slider->getValue();
|
|
slider = static_cast<GuiSliderCtrl*>(Sim::findObject("ambB"));
|
|
if (slider)
|
|
ambB = slider->getValue();
|
|
slider = static_cast<GuiSliderCtrl*>(Sim::findObject("diffR"));
|
|
if (slider)
|
|
diffR = slider->getValue();
|
|
slider = static_cast<GuiSliderCtrl*>(Sim::findObject("diffG"));
|
|
if (slider)
|
|
diffG = slider->getValue();
|
|
slider = static_cast<GuiSliderCtrl*>(Sim::findObject("diffB"));
|
|
if (slider)
|
|
diffB = slider->getValue();
|
|
|
|
|
|
// handle movement...a little weird because spliced from early version:
|
|
|
|
F32 leftSpeed = gShowLeftAction;
|
|
F32 rightSpeed = gShowRightAction;
|
|
F32 forwardSpeed = gShowForwardAction;
|
|
F32 backwardSpeed = gShowBackwardAction;
|
|
F32 upSpeed = gShowUpAction;
|
|
F32 downSpeed = gShowDownAction;
|
|
|
|
F32 timeScale = gShowMovementSpeed * 25.0f * ((F32)delta) / F32(1000);
|
|
if (!ShowTSShape::handleMovement(leftSpeed,rightSpeed,forwardSpeed,backwardSpeed,upSpeed,downSpeed,timeScale))
|
|
{
|
|
Point3F vec;
|
|
cameraMatrix.getColumn(0, &vec);
|
|
camPos += vec * (rightSpeed - leftSpeed) * timeScale;
|
|
cameraMatrix.getColumn(1, &vec);
|
|
camPos += vec * (forwardSpeed - backwardSpeed) * timeScale;
|
|
cameraMatrix.getColumn(2, &vec);
|
|
camPos += vec * (upSpeed - downSpeed) * timeScale;
|
|
}
|
|
}
|
|
|
|
void ShowTSShape::advanceTimeInstance(U32 delta)
|
|
{
|
|
float dt = timeScale * 0.001f * (float)delta;
|
|
|
|
for (S32 i=0; i<threads.size(); i++)
|
|
if (play[i])
|
|
shapeInstance->advanceTime(scale[i]*dt,threads[i]);
|
|
|
|
if (addGround)
|
|
{
|
|
shapeInstance->animateGround();
|
|
addGroundTransform(shapeInstance->getGroundTransform());
|
|
}
|
|
|
|
shapeInstance->animate();
|
|
}
|
|
|
|
//------------------------------------------------------------
|
|
// TS Control for show objects
|
|
//------------------------------------------------------------
|
|
|
|
bool ShowProcessCameraQuery(CameraQuery *q)
|
|
{
|
|
MatrixF xRot, zRot;
|
|
xRot.set(EulerF(camRot.x, 0, 0));
|
|
zRot.set(EulerF(0, 0, camRot.z));
|
|
|
|
cameraMatrix.mul(zRot, xRot);
|
|
q->nearPlane = 0.1;
|
|
q->farPlane = 2100.0;
|
|
q->fov = 3.1415 / 2;
|
|
cameraMatrix.setColumn(3, camPos);
|
|
q->cameraMatrix = cameraMatrix;
|
|
return true;
|
|
}
|
|
|
|
void ShowRenderWorld()
|
|
{
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
glDisable(GL_CULL_FACE);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
glDepthFunc(GL_LEQUAL);
|
|
|
|
dglSetCanonicalState();
|
|
gClientSceneGraph->renderScene();
|
|
dglSetCanonicalState();
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
AssertFatal(dglIsInCanonicalState(), "Not in canonical state on exit!");
|
|
}
|
|
|
|
class ShowTSCtrl : public GuiTSCtrl
|
|
{
|
|
typedef GuiTSCtrl Parent;
|
|
public:
|
|
bool processCameraQuery(CameraQuery *query);
|
|
void renderWorld(const RectI &updateRect);
|
|
void onRender(Point2I offset, const RectI &updateRect);
|
|
// void onMouseMove(const GuiEvent &evt);
|
|
|
|
DECLARE_CONOBJECT(ShowTSCtrl);
|
|
};
|
|
|
|
IMPLEMENT_CONOBJECT(ShowTSCtrl);
|
|
|
|
bool ShowTSCtrl::processCameraQuery(CameraQuery * q)
|
|
{
|
|
return ShowProcessCameraQuery(q);
|
|
}
|
|
|
|
void ShowTSCtrl::onRender(Point2I offset, const RectI &updateRect)
|
|
{
|
|
glColor3i(0, 0, 0);
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
glBegin(GL_TRIANGLE_FAN);
|
|
glVertex2i(updateRect.point.x, updateRect.point.y);
|
|
glVertex2i(updateRect.point.x + updateRect.extent.x, updateRect.point.y);
|
|
glVertex2i(updateRect.point.x + updateRect.extent.x, updateRect.point.y + updateRect.extent.y);
|
|
glVertex2i(updateRect.point.x, updateRect.point.y + updateRect.extent.y);
|
|
glEnd();
|
|
|
|
Parent::onRender(offset, updateRect);
|
|
}
|
|
|
|
void ShowTSCtrl::renderWorld(const RectI &updateRect)
|
|
{
|
|
ShowRenderWorld();
|
|
dglSetClipRect(updateRect);
|
|
}
|
|
|
|
//------------------------------------------------------------
|
|
// console functions for show plugin
|
|
//------------------------------------------------------------
|
|
ConsoleFunctionGroupBegin( ShowTool, "Functions for controlling the show tool.");
|
|
|
|
ConsoleFunction( showShapeLoad, void, 2, 3, "(string shapeName, bool faceCamera)")
|
|
{
|
|
argc;
|
|
|
|
Point3F vec,pos;
|
|
cameraMatrix.getColumn(1,&vec);
|
|
cameraMatrix.getColumn(3,&pos);
|
|
vec *= initialShowDistance;
|
|
|
|
ShowTSShape * show = new ShowTSShape(argv[1]);
|
|
|
|
if (show->shapeLoaded())
|
|
{
|
|
show->setPosition(pos+vec);
|
|
show->registerObject();
|
|
Sim::getRootGroup()->addObject(show);
|
|
}
|
|
else
|
|
delete show;
|
|
|
|
showUpdateThreadControl();
|
|
|
|
// make sure detail slider is set correctly
|
|
setDetailSlider();
|
|
}
|
|
|
|
ConsoleFunction( showSequenceLoad, void, 2, 3, "(string sequenceFile, string sequenceName=NULL)")
|
|
{
|
|
ShowTSShape * currentShow = ShowTSShape::currentShow;
|
|
if (!currentShow)
|
|
return;
|
|
|
|
char buffer[512];
|
|
|
|
if (argc==2)
|
|
dSprintf(buffer,512,"new TSShapeConstructor() { baseShape=\"%s\";sequence0=\"%s\"; };",currentShow->getShapeName(),argv[1]);
|
|
else
|
|
dSprintf(buffer,512,"new TSShapeConstructor() { baseShape=\"%s\";sequence0=\"%s %s\"; };",currentShow->getShapeName(),argv[1],argv[2]);
|
|
|
|
Con::evaluate(buffer);
|
|
ShowTSShape::reset();
|
|
}
|
|
|
|
ConsoleFunction( showSelectSequence, void, 1, 1, "")
|
|
{
|
|
ShowTSShape * currentShow = ShowTSShape::currentShow;
|
|
if (!currentShow)
|
|
return;
|
|
|
|
GuiTextListCtrl * threadList = static_cast<GuiTextListCtrl*>(Sim::findObject("threadList"));
|
|
if (!threadList)
|
|
return;
|
|
|
|
GuiTextListCtrl * sequenceList = static_cast<GuiTextListCtrl*>(Sim::findObject("sequenceList"));
|
|
if (!sequenceList)
|
|
return;
|
|
|
|
S32 threadNum = threadList->getSelectedCell().y;
|
|
S32 seq = sequenceList->getSelectedCell().y;
|
|
|
|
if (threadNum>=0 && seq>=0)
|
|
{
|
|
if (Con::getBoolVariable("$showTransition",false) && !currentShow->isBlend(seq))
|
|
{
|
|
F32 pos;
|
|
F32 dur = Con::getFloatVariable("$showTransitionDuration",0.2f);
|
|
GuiSliderCtrl * tpos = static_cast<GuiSliderCtrl*>(Sim::findObject("transitionPosition"));
|
|
if (Con::getBoolVariable("$showTransitionSynched",true) || !tpos)
|
|
pos = currentShow->getPos(threadNum);
|
|
else
|
|
pos = tpos->getValue();
|
|
bool targetPlay = Con::getBoolVariable("$showTransitionTargetPlay",true);
|
|
currentShow->transitionToSequence(threadNum,seq,pos,dur,targetPlay);
|
|
}
|
|
else
|
|
currentShow->setSequence(threadNum,seq);
|
|
|
|
GuiSliderCtrl * slider = static_cast<GuiSliderCtrl*>(Sim::findObject("threadPosition"));
|
|
if (slider && slider->getRoot())
|
|
{
|
|
char buffer[32];
|
|
dSprintf(buffer,32,"%g",currentShow->getPos(threadNum));
|
|
slider->setScriptValue(buffer);
|
|
}
|
|
}
|
|
|
|
showUpdateThreadControl();
|
|
return;
|
|
}
|
|
|
|
ConsoleFunction( showSetDetailSlider, void, 1, 1, "")
|
|
{
|
|
setDetailSlider();
|
|
}
|
|
|
|
ConsoleFunction( showUpdateThreadControl, void, 1, 1, "")
|
|
{
|
|
showUpdateThreadControl();
|
|
}
|
|
|
|
ConsoleFunction( showPlay, void, 1, 2, "(int threadNum = -1)")
|
|
{
|
|
ShowTSShape * currentShow = ShowTSShape::currentShow;
|
|
if (!currentShow)
|
|
return;
|
|
if (argc==1)
|
|
{
|
|
for (S32 i=0; i < currentShow->getThreadCount(); i++)
|
|
currentShow->setPlay(i,1);
|
|
}
|
|
else
|
|
{
|
|
S32 i = dAtoi(argv[1]);
|
|
if (i>=0)
|
|
currentShow->setPlay(i,1);
|
|
}
|
|
}
|
|
|
|
ConsoleFunction( showStop, void, 1, 2, "(int threadNum = -1)")
|
|
{
|
|
ShowTSShape * currentShow = ShowTSShape::currentShow;
|
|
if (!currentShow)
|
|
return;
|
|
if (argc==1)
|
|
{
|
|
for (S32 i=0; i < currentShow->getThreadCount(); i++)
|
|
currentShow->setPlay(i,0);
|
|
}
|
|
else
|
|
{
|
|
S32 i = dAtoi(argv[1]);
|
|
if (i>=0)
|
|
currentShow->setPlay(i,0);
|
|
}
|
|
}
|
|
|
|
ConsoleFunction (showSetScale, void, 3, 3, "(int threadNum, float scale)")
|
|
{
|
|
ShowTSShape * currentShow = ShowTSShape::currentShow;
|
|
if (!currentShow)
|
|
return;
|
|
|
|
S32 idx = dAtoi(argv[1]);
|
|
float s = dAtof(argv[2]);
|
|
if (idx>=0)
|
|
currentShow->setThreadScale(idx,s);
|
|
|
|
showUpdateThreadControl();
|
|
}
|
|
|
|
ConsoleFunction( showSetPos, void, 2, 2, "(int threadNum, float pos)")
|
|
{
|
|
ShowTSShape * currentShow = ShowTSShape::currentShow;
|
|
if (!currentShow)
|
|
return;
|
|
|
|
S32 idx = dAtoi(argv[1]);
|
|
float s = dAtof(argv[2]);
|
|
if (idx>=0)
|
|
currentShow->setPos(idx,s);
|
|
}
|
|
ConsoleFunction( showNewThread, void, 1, 1, "")
|
|
{
|
|
ShowTSShape * currentShow = ShowTSShape::currentShow;
|
|
if (!currentShow)
|
|
return;
|
|
|
|
currentShow->newThread();
|
|
|
|
showUpdateThreadControl();
|
|
}
|
|
|
|
ConsoleFunction( showDeleteThread, void, 2, 2, "(int threadNum)")
|
|
{
|
|
ShowTSShape * currentShow = ShowTSShape::currentShow;
|
|
if (!currentShow)
|
|
return;
|
|
|
|
S32 th = dAtoi(argv[1]);
|
|
if (th>=0)
|
|
currentShow->deleteThread(th);
|
|
|
|
showUpdateThreadControl();
|
|
}
|
|
|
|
|
|
ConsoleFunction( showToggleRoot, void, 1, 1, "")
|
|
{
|
|
ShowTSShape * currentShow = ShowTSShape::currentShow;
|
|
if (!currentShow)
|
|
return;
|
|
|
|
currentShow->setAnimateRoot(!currentShow->getAnimateRoot());
|
|
}
|
|
|
|
|
|
|
|
ConsoleFunction( showToggleStick, void, 1, 1, "")
|
|
{
|
|
ShowTSShape * currentShow = ShowTSShape::currentShow;
|
|
if (!currentShow)
|
|
return;
|
|
|
|
currentShow->setStickToGround(!currentShow->getStickToGround());
|
|
}
|
|
|
|
ConsoleFunction( showSetCamera, void, 2, 2, "(char orbitShape) t or T to orbit, else free-fly.")
|
|
{
|
|
ShowTSShape * currentShow = ShowTSShape::currentShow;
|
|
|
|
if (argv[1][0]=='t' || argv[1][0]=='T' && currentShow)
|
|
// orbit
|
|
currentShow->orbitUs();
|
|
else
|
|
// no orbit -- camera moves freely
|
|
orbitPos = NULL;
|
|
}
|
|
|
|
ConsoleFunction(showSetKeyboard, void, 2, 2, "(char moveShape) Set to t or T.")
|
|
{
|
|
keyboardControlsShape = (argv[1][0]=='t' || argv[1][0]=='T');
|
|
}
|
|
|
|
ConsoleFunction(showTurnLeft, void, 2, 2, "(float amt)")
|
|
{
|
|
gShowShapeLeftSpeed = dAtof(argv[1]);
|
|
}
|
|
|
|
|
|
ConsoleFunction( showTurnRight, void, 2, 2, "(float amt)")
|
|
{
|
|
gShowShapeRightSpeed = dAtof(argv[1]);
|
|
}
|
|
|
|
ConsoleFunction( showSetLightDirection, void, 1, 1, "")
|
|
{
|
|
cameraMatrix.getColumn(1,(Point3F*)&lightDir);
|
|
lightDir.x *= -1.0f;
|
|
lightDir.y *= -1.0f;
|
|
lightDir.z *= -1.0f;
|
|
lightDir.w *= -1.0f;
|
|
}
|
|
|
|
ConsoleFunctionGroupEnd( ShowTool );
|
|
|
|
void ShowInit()
|
|
{
|
|
Con::addVariable("showForwardAction", TypeF32, &gShowForwardAction);
|
|
Con::addVariable("showBackwardAction", TypeF32, &gShowBackwardAction);
|
|
Con::addVariable("showUpAction", TypeF32, &gShowUpAction);
|
|
Con::addVariable("showDownAction", TypeF32, &gShowDownAction);
|
|
Con::addVariable("showLeftAction", TypeF32, &gShowLeftAction);
|
|
Con::addVariable("showRightAction", TypeF32, &gShowRightAction);
|
|
|
|
Con::addVariable("showMovementSpeed", TypeF32, &gShowMovementSpeed);
|
|
|
|
Con::addVariable("showPitch", TypeF32, &camRot.x);
|
|
Con::addVariable("showYaw", TypeF32, &camRot.z);
|
|
|
|
cameraMatrix.identity();
|
|
camRot.set(0,0,0);
|
|
camPos.set(10,10,10);
|
|
cameraMatrix.setColumn(3,camPos);
|
|
}
|