📄 camera.cc
字号:
{
bstream->writeFlag(mObservingClientObject);
bstream->writeInt(gIndex, GhostConnection::GhostIdBitSize);
}
if (writeMode == OrbitPointMode)
bstream->writeCompressedPoint(writePos);
}
}
void Camera::readPacketData(GameConnection *connection, BitStream *bstream)
{
Parent::readPacketData(connection, bstream);
Point3F pos,rot;
mathRead(*bstream, &pos);
bstream->setCompressionPoint(pos);
bstream->read(&rot.x);
bstream->read(&rot.z);
GameBase* obj = 0;
mode = bstream->readRangedU32(CameraFirstMode, CameraLastMode);
mObservingClientObject = false;
if (mode == OrbitObjectMode || mode == OrbitPointMode) {
bstream->read(&mMinOrbitDist);
bstream->read(&mMaxOrbitDist);
bstream->read(&mCurOrbitDist);
if(mode == OrbitObjectMode)
{
mObservingClientObject = bstream->readFlag();
S32 gIndex = bstream->readInt(GhostConnection::GhostIdBitSize);
obj = static_cast<GameBase*>(connection->resolveGhost(gIndex));
}
if (mode == OrbitPointMode)
bstream->readCompressedPoint(&mPosition);
}
if (obj != (GameBase*)mOrbitObject) {
if (mOrbitObject) {
clearProcessAfter();
clearNotify(mOrbitObject);
}
mOrbitObject = obj;
if (mOrbitObject) {
processAfter(mOrbitObject);
deleteNotify(mOrbitObject);
}
}
setPosition(pos,rot);
delta.pos = pos;
delta.rot = rot;
delta.rotVec.set(0,0,0);
delta.posVec.set(0,0,0);
}
U32 Camera::packUpdate(NetConnection *con, U32 mask, BitStream *bstream)
{
Parent::packUpdate(con,mask,bstream);
// The rest of the data is part of the control object packet update.
// If we're controlled by this client, we don't need to send it.
if(bstream->writeFlag(getControllingClient() == con && !(mask & InitialUpdateMask)))
return 0;
if (bstream->writeFlag(mask & MoveMask)) {
Point3F pos;
mObjToWorld.getColumn(3,&pos);
bstream->write(pos.x);
bstream->write(pos.y);
bstream->write(pos.z);
bstream->write(mRot.x);
bstream->write(mRot.z);
}
return 0;
}
void Camera::unpackUpdate(NetConnection *con, BitStream *bstream)
{
Parent::unpackUpdate(con,bstream);
// controlled by the client?
if(bstream->readFlag())
return;
if (bstream->readFlag()) {
Point3F pos,rot;
bstream->read(&pos.x);
bstream->read(&pos.y);
bstream->read(&pos.z);
bstream->read(&rot.x);
bstream->read(&rot.z);
setPosition(pos,rot);
// New delta for client side interpolation
delta.pos = pos;
delta.rot = rot;
delta.posVec = delta.rotVec = VectorF(0,0,0);
}
}
//----------------------------------------------------------------------------
void Camera::initPersistFields()
{
Parent::initPersistFields();
}
void Camera::consoleInit()
{
Con::addVariable("Camera::movementSpeed",TypeF32,&mMovementSpeed);
}
Point3F &Camera::getPosition()
{
static Point3F position;
mObjToWorld.getColumn(3, &position);
return position;
}
ConsoleMethod( Camera, getPosition, const char *, 2, 2, "()"
"Get the position of the camera.\n\n"
"@returns A string of form \"x y z\".")
{
static char buffer[100];
Point3F& pos = object->getPosition();
dSprintf(buffer, sizeof(buffer),"%g %g %g",pos.x,pos.y,pos.z);
return buffer;
}
ConsoleMethod( Camera, setOrbitMode, void, 7, 8, "(GameBase orbitObject, transform mat, float minDistance,"
" float maxDistance, float curDistance, bool ownClientObject)"
"Set the camera to orbit around some given object.\n\n"
"@param orbitObject Object we want to orbit.\n"
"@param mat A set of fields: posX posY posZ aaX aaY aaZ aaTheta\n"
"@param minDistance Minimum distance to keep from object.\n"
"@param maxDistance Maximum distance to keep from object.\n"
"@param curDistance Distance to set initially from object.\n"
"@param ownClientObj Are we observing an object owned by us?")
{
Point3F pos;
AngAxisF aa;
F32 minDis, maxDis, curDis;
GameBase *orbitObject = NULL;
if(Sim::findObject(argv[2],orbitObject) == false)
{
Con::warnf("Cannot orbit non-existing object.");
object->setFlyMode();
return;
}
dSscanf(argv[3],"%g %g %g %g %g %g %g",
&pos.x,&pos.y,&pos.z,&aa.axis.x,&aa.axis.y,&aa.axis.z,&aa.angle);
minDis = dAtof(argv[4]);
maxDis = dAtof(argv[5]);
curDis = dAtof(argv[6]);
object->setOrbitMode(orbitObject, pos, aa, minDis, maxDis, curDis, (argc == 8) ? dAtob(argv[7]) : false);
}
ConsoleMethod( Camera, setFlyMode, void, 2, 2, "()"
"Set the camera to be able to fly freely.")
{
object->setFlyMode();
}
//----------------------------------------------------------------------------
void Camera::renderImage(SceneState*, SceneRenderImage*)
{
if(gEditingMission)
{
glPushMatrix();
dglMultMatrix(&mObjToWorld);
glScalef(mObjScale.x,mObjScale.y,mObjScale.z);
wireCube(Point3F(1, 1, 1),Point3F(0,0,0));
glPopMatrix();
}
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// NEW Observer Code
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
void Camera::setFlyMode()
{
mode = FlyMode;
if(bool(mOrbitObject)) {
clearProcessAfter();
clearNotify(mOrbitObject);
}
mOrbitObject = NULL;
}
void Camera::setOrbitMode(GameBase *obj, Point3F &pos, AngAxisF &rot, F32 minDist, F32 maxDist, F32 curDist, bool ownClientObject)
{
mObservingClientObject = ownClientObject;
rot;
if(bool(mOrbitObject)) {
clearProcessAfter();
clearNotify(mOrbitObject);
}
mOrbitObject = obj;
if(bool(mOrbitObject))
{
processAfter(mOrbitObject);
deleteNotify(mOrbitObject);
mOrbitObject->getWorldBox().getCenter(&mPosition);
mode = OrbitObjectMode;
}
else
{
mode = OrbitPointMode;
mPosition = pos;
}
QuatF q(rot);
MatrixF tempMat(true);
q.setMatrix(&tempMat);
Point3F dir;
tempMat.getColumn(1, &dir);
setPosition(mPosition, dir);
mMinOrbitDist = minDist;
mMaxOrbitDist = maxDist;
mCurOrbitDist = curDist;
}
void Camera::validateEyePoint(F32 pos, MatrixF *mat)
{
if (pos != 0)
{
// Use the eye transform to orient the camera
Point3F dir;
mat->getColumn(1, &dir);
pos *= mMaxOrbitDist - mMinOrbitDist;
// Use the camera node's pos.
Point3F startPos = getRenderPosition();
Point3F endPos;
// Make sure we don't extend the camera into anything solid
if(mOrbitObject)
mOrbitObject->disableCollision();
disableCollision();
RayInfo collision;
U32 mask = TerrainObjectType |
InteriorObjectType |
WaterObjectType |
StaticShapeObjectType |
PlayerObjectType |
ItemObjectType |
VehicleObjectType;
Container* pContainer = isServerObject() ? &gServerContainer : &gClientContainer;
if (!pContainer->castRay(startPos, startPos - dir * 2.5 * pos, mask, &collision))
endPos = startPos - dir * pos;
else
{
float dot = mDot(dir, collision.normal);
if(dot > 0.01)
{
float colDist = mDot(startPos - collision.point, dir) - (1 / dot) * CameraRadius;
if(colDist > pos)
colDist = pos;
if(colDist < 0)
colDist = 0;
endPos = startPos - dir * colDist;
}
else
endPos = startPos - dir * pos;
}
mat->setColumn(3,endPos);
enableCollision();
if(mOrbitObject)
mOrbitObject->enableCollision();
}
}
void Camera::setPosition(const Point3F& pos, const Point3F& rot, MatrixF *mat)
{
MatrixF xRot, zRot;
xRot.set(EulerF(rot.x, 0, 0));
zRot.set(EulerF(0, 0, rot.z));
mat->mul(zRot, xRot);
mat->setColumn(3,pos);
mRot = rot;
}
void Camera::setTransform(const MatrixF& mat)
{
// This method should never be called on the client.
// This currently converts all rotation in the mat into
// rotations around the z and x axis.
Point3F pos,vec;
mat.getColumn(1,&vec);
mat.getColumn(3,&pos);
Point3F rot(-mAtan(vec.z, mSqrt(vec.x*vec.x + vec.y*vec.y)),0,-mAtan(-vec.x,vec.y));
setPosition(pos,rot);
}
void Camera::setRenderTransform(const MatrixF& mat)
{
// This method should never be called on the client.
// This currently converts all rotation in the mat into
// rotations around the z and x axis.
Point3F pos,vec;
mat.getColumn(1,&vec);
mat.getColumn(3,&pos);
Point3F rot(-mAtan(vec.z, mSqrt(vec.x*vec.x + vec.y*vec.y)),0,-mAtan(-vec.x,vec.y));
setRenderPosition(pos,rot);
}
F32 Camera::getDamageFlash() const
{
if (mode == OrbitObjectMode && isServerObject() && bool(mOrbitObject))
{
const GameBase *castObj = mOrbitObject;
const ShapeBase* psb = dynamic_cast<const ShapeBase*>(castObj);
if (psb)
return psb->getDamageFlash();
}
return mDamageFlash;
}
F32 Camera::getWhiteOut() const
{
if (mode == OrbitObjectMode && isServerObject() && bool(mOrbitObject))
{
const GameBase *castObj = mOrbitObject;
const ShapeBase* psb = dynamic_cast<const ShapeBase*>(castObj);
if (psb)
return psb->getWhiteOut();
}
return mWhiteOut;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -