GameGetCameraTransform() inconsistent when in orbit-cam mode
by Orion Elenzil · in Torque Game Engine · 07/17/2006 (6:22 pm) · 1 replies
Hey all -
i've got a weird one here.
i'm doing some client-side picking to facilitate selecting other players,
based off the usual "object selection in torque" resource.
along the way we make a call to GameGetCameraTransform().
now the weird part is that occasionally, when in Orbit-Cam mode, GameGetCameraTransform() returns values which are slightly off. - the result being that picking another player is highly flaky. we highlight the selected player on mouse-over, so it looks as if the other player is flickering at about oh maybe 6 or 7 Hz.
however, at the same time, the actual camera is rock-steady by the time scene is rendered.
so i'm thinking it's an asynchonousness between user UI events (mouseMove) and incoming packUpdates,
and furthermore that some part of the system is correcting the incoming camera position by the time it actually gets rendered.
the TGE camera system has always befuddled me,
so if anyone has an idea or two that'd be awesome.
this is the stock TGE 1.3 camera, no advanced camera or anything like that.
tia, orion
i've got a weird one here.
i'm doing some client-side picking to facilitate selecting other players,
based off the usual "object selection in torque" resource.
along the way we make a call to GameGetCameraTransform().
now the weird part is that occasionally, when in Orbit-Cam mode, GameGetCameraTransform() returns values which are slightly off. - the result being that picking another player is highly flaky. we highlight the selected player on mouse-over, so it looks as if the other player is flickering at about oh maybe 6 or 7 Hz.
however, at the same time, the actual camera is rock-steady by the time scene is rendered.
so i'm thinking it's an asynchonousness between user UI events (mouseMove) and incoming packUpdates,
and furthermore that some part of the system is correcting the incoming camera position by the time it actually gets rendered.
the TGE camera system has always befuddled me,
so if anyone has an idea or two that'd be awesome.
this is the stock TGE 1.3 camera, no advanced camera or anything like that.
tia, orion
About the author
Associate Orion Elenzil
Real Life Plus
we've got a pretty nice fix for this.
short story:
GuiTSControl already stores the last camera matrix actually used to render the scene, so we just use that.
Mousepicking is potentially lagging one frame behind the camera motion, but really, one is hardly ever picking when the camera is in motion. So it's all good.
long story:
GuiTSControl::mLastCameraQuery.cameraMatrix is the last camera matrix actually used to render, but inverted.
Added mLastCameraQuery.cameraMatrixNonInverted, which gets stored off right before the inversion, and voila.
Also added console method accessors.
here's the code.
guiTSControl.h
additions in bold:
bool unproject(const Point3F &pt, Point3F *dest); // returns world space point for X, Y and Z[b] const MatrixF& getLastCameraMatrixNonInverted() { return mLastCameraQuery.cameraMatrixNonInverted; } const MatrixF& getLastCameraMatrixInverted () { return mLastCameraQuery.cameraMatrix; }[/b] DECLARE_CONOBJECT(GuiTSCtrl);guiTSControl.cc
add these to the bottom or wherever appropriate:
[b] ConsoleMethod( GuiTSCtrl, getLastCameraTransform, const char*, 2, 2, "") { char *returnBuffer = Con::getReturnBuffer(256); const MatrixF& mat = object->getLastCameraMatrixNonInverted(); Point3F pos; mat.getColumn(3,&pos); AngAxisF aa(mat); dSprintf(returnBuffer,256,"%g %g %g %g %g %g %g", pos.x, pos.y, pos.z, aa.axis.x, aa.axis.y, aa.axis.z, aa.angle); return returnBuffer; } ConsoleMethod( GuiTSCtrl, getLastCameraTransformInverted, const char*, 2, 2, "") { char *returnBuffer = Con::getReturnBuffer(256); const MatrixF& mat = object->getLastCameraMatrixInverted(); Point3F pos; mat.getColumn(3,&pos); AngAxisF aa(mat); dSprintf(returnBuffer,256,"%g %g %g %g %g %g %g", pos.x, pos.y, pos.z, aa.axis.x, aa.axis.y, aa.axis.z, aa.angle); return returnBuffer; }[/b]and then this is the mousePick method we've also added to gameTSCtrl.cc, which now uses the new stuff from above.
it's slightly specialized and may have one or two pieces which aren't in stock TGE,
but they're not mysterious or anything.
[b] bool GameTSCtrl::doMouseRayCast(RayInfo* rayInfo, Point2I& pt) { Player* localPlayer = GameConnection::getServerConnection()->getPlayerObject(); if(gSnapLine) return false; MatrixF mat; Point3F vel; if ( GameGetCameraTransform(&mat, &vel) ) { mat = getLastCameraMatrixNonInverted(); Point3F pos; Point3F trg; mat.getColumn(3,&pos); Point3F screenPoint(pt.x, pt.y, -1); Point3F worldPoint; if (unproject(screenPoint, &worldPoint)) { Point3F vec = worldPoint - pos; lineTestStart = pos; vec.normalizeSafe(); lineTestEnd = pos + vec * 1000; mMouse3DVec = vec; mMouse3DPos = pos; //don't highlight the local player GameBase* pExempt; pExempt = localPlayer; if (pExempt) pExempt->disableCollision(); trg = pos + vec * smObjSelRange; bool gotObject = gClientContainer.castRay(pos, trg, smObjSelTypeMasks, rayInfo); if (pExempt) pExempt->enableCollision(); return gotObject; } return false; } return false; }[/b]