📄 showtsshape.cc
字号:
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -