// This is called whenever there is a change in the camera. bool GuiMaterialPreview::processCameraQuery(CameraQuery* query) { MatrixF xRot, zRot; Point3F vecf, vecu, vecr;; xRot.set(EulerF(mCameraRot.x, 0.0f, 0.0f)); zRot.set(EulerF(0.0f, 0.0f, mCameraRot.z)); if(mMouseState != Panning) { // Adjust the camera so that we are still facing the model: Point3F vec; mCameraMatrix.mul(zRot, xRot); mCameraMatrix.getColumn(1, &vec); vec *= mOrbitDist; mCameraPos = mOrbitPos - vec; query->farPlane = 2100.0f; query->nearPlane = query->farPlane / 5000.0f; query->fov = 45.0f; mCameraMatrix.setColumn(3, mCameraPos); query->cameraMatrix = mCameraMatrix; } else { mCameraMatrix.mul( zRot, xRot ); mCameraMatrix.getColumn( 1, &vecf ); // Forward vector mCameraMatrix.getColumn( 2, &vecu ); // Up vector mCameraMatrix.getColumn( 0, &vecr ); // Right vector Point3F flatVecf(vecf.x, vecf.y, 0.0f); Point3F modvecf = flatVecf * mOrbitRelPos.y; Point3F modvecu = vecu * mOrbitRelPos.z; Point3F modvecr = vecr * mOrbitRelPos.x; // Change the orbit position mOrbitPos += modvecu - modvecr + modvecf; F32 vecfmul = mOrbitDist; Point3F virtualVecF = vecf * mOrbitDist; vecf *= vecfmul; mCameraPos = mOrbitPos - virtualVecF; // Update the camera's position mCameraMatrix.setColumn( 3, (mOrbitPos - vecf) ); query->farPlane = 2100.0f; query->nearPlane = query->farPlane / 5000.0f; query->fov = 45.0f; query->cameraMatrix = mCameraMatrix; // Reset the relative position mOrbitRelPos = Point3F(0,0,0); } return true; }
bool FlyingCamera::onSimFrameEndNotifyEvent(const SimFrameEndNotifyEvent *) { float x = rotation.x; float d = rDistance; // get the move info float speed = atof( CMDConsole::getLocked()->getVariable( "MoveSpeed" ) ); float rot = atof( CMDConsole::getLocked()->getVariable( "PosRotation" ) ) * M_PI * 5; maxLinearSpeed.set( speed, speed, speed ); maxAngularSpeed.set( rot, rot, rot ); // Sample inputs and get new throttles throttle.x = input.linear.x.getInput() * maxLinearSpeed.x; throttle.y = input.linear.y.getInput() * maxLinearSpeed.y; throttle.z = input.linear.z.getInput() * maxLinearSpeed.z; rotation.x += input.angular.x.getInput() * maxAngularSpeed.x; rotation.y += input.angular.y.getInput() * maxAngularSpeed.y; rotation.z += input.angular.z.getInput() * maxAngularSpeed.z; // If we're following we need to keep track of our relative position // and rotation if (objFollow) { if (throttle.y) { rDistance += throttle.y < 0 ? MAX_ATTACHED_SPEED : -MAX_ATTACHED_SPEED; if (rDistance >= MAX_ATTACHED_DISTANCE || rDistance < MIN_ATTACHED_DISTANCE) { rDistance = d; } } if (rotation.x >= MAX_ATTACHED_ROTATION || rotation.x <= MIN_ATTACHED_ROTATION) { rotation.x = x; } } // We only set our own position if we're not following else { Point3F tmp; m_mul(throttle, RMat3F(EulerF(rotation.x, rotation.y, rotation.z)), &tmp); position += tmp; setPosition(TMat3F(EulerF(rotation.x, rotation.y, rotation.z), position), true); } return (true); }
void Etherform::setRenderPosition(const Point3F& pos, const Point3F& rot, F32 dt) { MatrixF xRot, zRot; xRot.set(EulerF(rot.x, 0, 0)); zRot.set(EulerF(0, 0, rot.z)); MatrixF temp; temp.mul(zRot, xRot); temp.setColumn(3, pos); Parent::setRenderTransform(temp); }
MatrixF PlaneReflector::getFrustumClipProj( MatrixF &modelview ) { static MatrixF rotMat(EulerF( static_cast<F32>(M_PI / 2.f), 0.0, 0.0)); static MatrixF invRotMat(EulerF( -static_cast<F32>(M_PI / 2.f), 0.0, 0.0)); MatrixF revModelview = modelview; revModelview = rotMat * revModelview; // add rotation to modelview because it needs to be removed from projection // rotate clip plane into modelview space Point4F clipPlane; Point3F pnt = refplane * -(refplane.d + 0.0 ); Point3F norm = refplane; revModelview.mulP( pnt ); revModelview.mulV( norm ); norm.normalize(); clipPlane.set( norm.x, norm.y, norm.z, -mDot( pnt, norm ) ); // Manipulate projection matrix //------------------------------------------------------------------------ MatrixF proj = GFX->getProjectionMatrix(); proj.mul( invRotMat ); // reverse rotation imposed by Torque proj.transpose(); // switch to row-major order // Calculate the clip-space corner point opposite the clipping plane // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and // transform it into camera space by multiplying it // by the inverse of the projection matrix Vector4F q; q.x = sgn(clipPlane.x) / proj(0,0); q.y = sgn(clipPlane.y) / proj(1,1); q.z = -1.0F; q.w = ( 1.0F - proj(2,2) ) / proj(3,2); F32 a = 1.0 / (clipPlane.x * q.x + clipPlane.y * q.y + clipPlane.z * q.z + clipPlane.w * q.w); Vector4F c = clipPlane * a; // CodeReview [ags 1/23/08] Come up with a better way to deal with this. if(GFX->getAdapterType() == OpenGL) c.z += 1.0f; // Replace the third column of the projection matrix proj.setColumn( 2, c ); proj.transpose(); // convert back to column major order proj.mul( rotMat ); // restore Torque rotation return proj; }
bool FlyingCamera::onSimCameraQuery(SimCameraQuery *query) { SimObjectTransformQuery tquery; query->cameraInfo.fov = g_rDefaultFOV; query->cameraInfo.nearPlane = DEFAULT_NEAR_PLANE; query->cameraInfo.farPlane = getFarPlane(); if (objFollow && objFollow->processQuery(&tquery)) { Point3F objPos = tquery.tmat.p; Vector3F x, y, z; RMat3F rmat(EulerF(rotation.x - M_PI / 2, rotation.y, -rotation.z)); tquery.tmat.p += m_mul(Vector3F(0.0f, rDistance, 0.0f), rmat, &y); tquery.tmat.p.z += 2.0f; y.neg(); y.normalize(); m_cross(y, Vector3F(0.0f, 0.0f, 1.0f), &x); x.normalize(); m_cross(x, y, &z); tquery.tmat.setRow(0, x); tquery.tmat.setRow(1, y); tquery.tmat.setRow(2, z); // Set our position findLOSPosition(tquery.tmat, objPos); } query->cameraInfo.tmat = getTransform(); return (true); }
void Item::setTransform(const MatrixF& mat) { Point3F pos; mat.getColumn(3,&pos); MatrixF tmat; if (!mRotate) { // Forces all rotation to be around the z axis VectorF vec; mat.getColumn(1,&vec); tmat.set(EulerF(0,0,-mAtan2(-vec.x,vec.y))); } else tmat.identity(); tmat.setColumn(3,pos); Parent::setTransform(tmat); if (!mStatic) { mAtRest = false; mAtRestCounter = 0; } if ( mPhysicsRep ) mPhysicsRep->setTransform( getTransform() ); setMaskBits(RotationMask | PositionMask | NoWarpMask); }
bool SimInterior::processArguments(int argc, const char **argv) { CMDConsole *console = CMDConsole::getLocked(); if(argc < 1) { console->printf("SimInterior: filename.dis [posX posY posZ] [rotX rotY rotZ]"); return false; } if(!loadShape(argv[0])) { console->printf("SimInterior: unable to load interior shape %s", argv[0]); return false; } if (argc > 1) { float f[6]; memset(f,0,sizeof(f)); for (int i = 1; i < argc; i++) sscanf(argv[i], "%f", &f[i - 1]); const float p = float(M_PI/180.0); set(EulerF(p*f[3],p*f[4],p*f[5]),Point3F(f[0],f[1],f[2])); } return true; }
void GFXDrawUtil::draw2DSquare( const Point2F &screenPoint, F32 width, F32 spinAngle ) { width *= 0.5; Point3F offset( screenPoint.x, screenPoint.y, 0.0 ); GFXVertexBufferHandle<GFXVertexPC> verts( mDevice, 4, GFXBufferTypeVolatile ); verts.lock(); verts[0].point.set( -width, -width, 0.0f ); verts[1].point.set( -width, width, 0.0f ); verts[2].point.set( width, -width, 0.0f ); verts[3].point.set( width, width, 0.0f ); verts[0].color = verts[1].color = verts[2].color = verts[3].color = mBitmapModulation; if(spinAngle != 0.f) { MatrixF rotMatrix( EulerF( 0.0, 0.0, spinAngle ) ); for( S32 i = 0; i < 4; i++ ) { rotMatrix.mulP( verts[i].point ); verts[i].point += offset; } } verts.unlock(); mDevice->setVertexBuffer( verts ); mDevice->setStateBlock(mRectFillSB); mDevice->setupGenericShaders(); mDevice->drawPrimitive( GFXTriangleStrip, 0, 2 ); }
void EditTSCtrl::calcOrthoCamOffset(F32 mousex, F32 mousey, U8 modifier) { F32 camScale = 0.01f; switch(mDisplayType) { case DisplayTypeTop: mOrthoCamTrans.x -= mousex * mOrthoFOV * camScale; mOrthoCamTrans.y += mousey * mOrthoFOV * camScale; break; case DisplayTypeBottom: mOrthoCamTrans.x -= mousex * mOrthoFOV * camScale; mOrthoCamTrans.y -= mousey * mOrthoFOV * camScale; break; case DisplayTypeFront: mOrthoCamTrans.x += mousex * mOrthoFOV * camScale; mOrthoCamTrans.z += mousey * mOrthoFOV * camScale; break; case DisplayTypeBack: mOrthoCamTrans.x -= mousex * mOrthoFOV * camScale; mOrthoCamTrans.z += mousey * mOrthoFOV * camScale; break; case DisplayTypeLeft: mOrthoCamTrans.y += mousex * mOrthoFOV * camScale; mOrthoCamTrans.z += mousey * mOrthoFOV * camScale; break; case DisplayTypeRight: mOrthoCamTrans.y -= mousex * mOrthoFOV * camScale; mOrthoCamTrans.z += mousey * mOrthoFOV * camScale; break; case DisplayTypeIsometric: if(modifier & SI_PRIMARY_CTRL) { // NOTE: Maybe move the center of rotation code to right mouse down to avoid compound errors? F32 rot = mDegToRad(mousex); Point3F campos = (mRawCamPos + mOrthoCamTrans) - mIsoCamRotCenter; MatrixF mat(EulerF(0, 0, rot)); mat.mulP(campos); mOrthoCamTrans = (campos + mIsoCamRotCenter) - mRawCamPos; mIsoCamRot.z += rot; } else { mOrthoCamTrans.x -= mousex * mOrthoFOV * camScale * mCos(mIsoCamRot.z) - mousey * mOrthoFOV * camScale * mSin(mIsoCamRot.z); mOrthoCamTrans.y += mousex * mOrthoFOV * camScale * mSin(mIsoCamRot.z) + mousey * mOrthoFOV * camScale * mCos(mIsoCamRot.z); } break; } }
float Player::coverage (Point3F eye) { float total = 0; Point3F foot = getLinearPosition () + collisionImage.sphere.center / 2; Point3F head = foot + collisionImage.sphere.center; Point3F temp; Point3F lshoulder; Point3F rshoulder; temp = getRot (); RMat3F rot (EulerF(temp.x, temp.y, temp.z)); temp.set (collisionImage.bbox.fMin.x / 2, 0, 0); m_mul (temp, rot, &lshoulder); lshoulder += getLinearPosition (); lshoulder.z += collisionImage.sphere.center.z; lshoulder.z += collisionImage.sphere.center.z / 4; temp.set (collisionImage.bbox.fMax.x / 2, 0, 0); m_mul (temp, rot, &rshoulder); rshoulder += getLinearPosition (); rshoulder.z += collisionImage.sphere.center.z; rshoulder.z += collisionImage.sphere.center.z / 4; SimContainerQuery cq; cq.id = getId(); cq.type = -1; cq.mask = SimTerrainObjectType | SimInteriorObjectType | SimPlayerObjectType | StaticObjectType; cq.box.fMin = eye; cq.box.fMax = foot; SimCollisionInfo info; SimContainer* root = findObject(manager,SimRootContainerId,(SimContainer*)0); bool obstructed = root->findLOS (cq, &info); if (!obstructed) total += 0.25; cq.box.fMax = head; obstructed = root->findLOS (cq, &info); if (!obstructed) total += 0.25; cq.box.fMax = lshoulder; obstructed = root->findLOS (cq, &info); if (!obstructed) total += 0.25; cq.box.fMax = rshoulder; obstructed = root->findLOS (cq, &info); if (!obstructed) total += 0.25; return total; }
bool GuiObjectView::processCameraQuery( CameraQuery* query ) { // Adjust the camera so that we are still facing the model. Point3F vec; MatrixF xRot, zRot; xRot.set( EulerF( mCameraRot.x, 0.0f, 0.0f ) ); zRot.set( EulerF( 0.0f, 0.0f, mCameraRot.z ) ); mCameraMatrix.mul( zRot, xRot ); mCameraMatrix.getColumn( 1, &vec ); vec *= mOrbitDist; mCameraPos = mOrbitPos - vec; query->farPlane = 2100.0f; query->nearPlane = query->farPlane / 5000.0f; query->fov = 45.0f; mCameraMatrix.setColumn( 3, mCameraPos ); query->cameraMatrix = mCameraMatrix; return true; }
void Player::getThrowVector(Point3F* pos,Point3F* vec) { RMat3F view,mat; // Add a small upward component to the pitch to // throw the item up a little. float offset = 0.5 * cos(viewPitch); view.set(EulerF(viewPitch + offset,0.0f,0.0f)); m_mul(view,(RMat3F&)getTransform(),&mat); Point3F vv(0,1,0); m_mul(vv,mat,vec); *pos = getBoxCenter(); }
EditTSCtrl::EditTSCtrl() { mGizmoProfile = NULL; mGizmo = NULL; mRenderMissionArea = true; mMissionAreaFillColor.set(255,0,0,20); mMissionAreaFrameColor.set(255,0,0,128); mMissionAreaHeightAdjust = 5.0f; mConsoleFrameColor.set(255,0,0,255); mConsoleFillColor.set(255,0,0,120); mConsoleSphereLevel = 1; mConsoleCircleSegments = 32; mConsoleLineWidth = 1; mRightMousePassThru = true; mMiddleMousePassThru = true; mConsoleRendering = false; mDisplayType = DisplayTypePerspective; mOrthoFOV = 50.0f; mOrthoCamTrans.set(0.0f, 0.0f, 0.0f); mIsoCamAngle = mDegToRad(45.0f); mIsoCamRot = EulerF(0, 0, 0); mRenderGridPlane = true; mGridPlaneOriginColor = ColorI(255, 255, 255, 100); mGridPlaneColor = ColorI(102, 102, 102, 100); mGridPlaneMinorTickColor = ColorI(51, 51, 51, 100); mGridPlaneMinorTicks = 9; mGridPlaneSize = 1.0f; mGridPlaneSizePixelBias = 10.0f; mLastMousePos.set(0, 0); mAllowBorderMove = false; mMouseMoveBorder = 20; mMouseMoveSpeed = 0.1f; mLastBorderMoveTime = 0; mLeftMouseDown = false; mRightMouseDown = false; mMiddleMouseDown = false; mMiddleMouseTriggered = false; mMouseLeft = false; mBlendSB = NULL; }
void AdvancedLightBinManager::setupSGData( SceneData &data, const SceneRenderState* state, LightInfo *light ) { PROFILE_SCOPE( AdvancedLightBinManager_setupSGData ); data.lights[0] = light; data.ambientLightColor = state->getAmbientLightColor(); data.objTrans = &MatrixF::Identity; if ( light ) { if ( light->getType() == LightInfo::Point ) { // The point light volume gets some flat spots along // the perimiter mostly visible in the constant and // quadradic falloff modes. // // To account for them slightly increase the scale // instead of greatly increasing the polycount. mLightMat = light->getTransform(); mLightMat.scale( light->getRange() * 1.01f ); data.objTrans = &mLightMat; } else if ( light->getType() == LightInfo::Spot ) { mLightMat = light->getTransform(); // Rotate it to face down the -y axis. MatrixF scaleRotateTranslate( EulerF( M_PI_F / -2.0f, 0.0f, 0.0f ) ); // Calculate the radius based on the range and angle. F32 range = light->getRange().x; F32 radius = range * mSin( mDegToRad( light->getOuterConeAngle() ) * 0.5f ); // NOTE: This fudge makes the cone a little bigger // to remove the facet egde of the cone geometry. radius *= 1.1f; // Use the scale to distort the cone to // match our radius and range. scaleRotateTranslate.scale( Point3F( radius, radius, range ) ); // Apply the transform and set the position. mLightMat *= scaleRotateTranslate; mLightMat.setPosition( light->getPosition() ); data.objTrans = &mLightMat; } } }
void SimFire::finishAddToManager() { if (onObj) deleteNotify(onObj); // don't know shape size yet, fake it for now bbox.fMin.set(-1,-1,-1); bbox.fMax.set(1,1,1); if (!faceCam && !followCam) image.transform.identity(); Point3F & p = image.transform.p; image.transform.flags |= TMat3F::Matrix_HasTranslation; // will keep this flag setting getPosition(p); updateBBox(p); updateBox = false; fireHeight = 0; // set fire start and end time prevAnimTime = manager->getCurrentTime(); fireOut += prevAnimTime; // set next smoke time if (producesSmoke) nextSmokeTime = smokeToSmoke*.5f + prevAnimTime; // add to timer set addToSet(SimTimerSetId); // add to container db so we get render query SimContainer *root = NULL; root = findObject(manager, SimRootContainerId,root); root->addObject(this); // start sound if there is one if (soundID != -1) hSound = Sfx::Manager::PlayAt( manager, soundID, TMat3F(EulerF(0, 0, 0), p), Point3F(0, 0, 0)); // prepare the light if (lightRange > 0.0f && SimFire::DynamicLighting) { glow.setType(TS::Light::LightPoint); glow.setIntensity(lightColor); glow.setRange(lightRange); glow.setPosition(p); addToSet(SimLightSetId); } }
const TMat3F &Turret::getEyeTransform (void) { static TMat3F ret; TMat3F temp; int node = cameraNode; if (node != -1) { const TMat3F& nmat = image.shape->getTransform(node); temp.set(EulerF(turretElevation, 0, turretRotation), nmat.p); } else temp.identity(); m_mul(temp, getTransform(), &ret); return ret; }
SimInterior::SimInterior(): m_pFilename(NULL), m_currentState(0) { type = SimInteriorObjectType; renderImage.pSimInterior = this; renderImage.instance = NULL; renderImage.itype = SimRenderImage::Normal; collisionImage.instance = NULL; set(EulerF (0, 0, 0), Point3F (0, 0, 0)); netFlags.set(ScopeAlways); netFlags.set(Ghostable); }
bool Turret::getMuzzleTransform(int, TMat3F *transform) { if(!image.shape) return false; image.shape->animate(); int node = gunNode; if(node != -1) { const TMat3F &nodeTrans = image.shape->getTransform(node); TMat3F mat1(EulerF(turretElevation, 0, turretRotation), nodeTrans.p); m_mul(mat1, getTransform(), transform); } else *transform = getTransform(); return true; }
void Turret::getCameraTransform(float camDist, TMat3F *transform) { if(!image.shape) return; image.shape->animate(); int node = cameraNode; if(node != -1) { const TMat3F &nodeTrans = image.shape->getTransform(node); TMat3F mat1(EulerF(turretElevation, 0, turretRotation), nodeTrans.p); m_mul(mat1, getTransform(), transform); validateEyePoint (transform, camDist * 1.3); } else *transform = getTransform(); }
const TMat3F &Player::getEyeTransform() { static TMat3F ret; TMat3F temp; int node = eyeNode; if (node != -1) { const TMat3F& nmat = image.shape->getTransform(node); temp.set(EulerF(viewPitch, 0, 0), nmat.p); } else temp.identity(); m_mul(temp, getTransform(), &ret); return ret; }
void SimInterior::inspectRead(Inspect* sd) { Parent::inspectRead(sd); // Filename edit char newFilename[Inspect::MAX_STRING_LEN + 1]; sd->read(IDITG_FILENAME, newFilename); loadShape(newFilename); Point3F pos; Point3F rot; sd->read(IDITG_POSITION, pos); sd->read(IDITG_ROTATION, rot); set(EulerF(rot.x, rot.y, rot.z), pos); }
void SimExplosionCloud::makeSound() { if (soundId != EXP_nosound) { Point3F p; if (form==Box) { center = box.fMin; center += box.fMax; center *= 0.5f; } if (hasTransform) m_mul(center,transform,&p); else p = center; Sfx::Manager::PlayAt( manager, soundId, TMat3F(EulerF(0, 0, 0), p), Point3F(0, 0, 0)); } }
//-------------------------------------------------------------------------- // Update //-------------------------------------------------------------------------- void CameraShake::update( F32 dt ) { Parent::update( dt ); fadeAmplitude(); VectorF camOffset; camOffset.x = mAmp.x * sin( M_2PI * (mTimeOffset.x + mElapsedTime) * mFreq.x ); camOffset.y = mAmp.y * sin( M_2PI * (mTimeOffset.y + mElapsedTime) * mFreq.y ); camOffset.z = mAmp.z * sin( M_2PI * (mTimeOffset.z + mElapsedTime) * mFreq.z ); VectorF rotAngles; rotAngles.x = camOffset.x * 10.0 * M_PI/180.0; rotAngles.y = camOffset.y * 10.0 * M_PI/180.0; rotAngles.z = camOffset.z * 10.0 * M_PI/180.0; MatrixF rotMatrix( EulerF( rotAngles.x, rotAngles.y, rotAngles.z ) ); mCamFXTrans = rotMatrix; mCamFXTrans.setPosition( camOffset ); }
// assumes dirY is normalized void fxRenderImage::faceDirection(Point3F & dirY) { // if we rotate about an axis, use a different routine... if (useRotationAxis) { faceDirection(dirY,rotationAxis); return; } Point3F dirX,dirZ; if (fabs(dirY.z) < 0.95) { // dirY is not near vector (0,0,1), so we can // use it as the pivot vector m_cross(dirY, Point3F(0,0,1), &dirX); dirX.normalize(); m_cross(dirX, dirY, &dirZ); } else { // dirY is near vector (0,0,1), so use // pivot Point3F(1,0,0) instead m_cross(Point3F(1,0,0), dirY, &dirZ); dirZ.normalize(); m_cross(dirY, dirZ, &dirX); } transform.setRow(0,dirX); transform.setRow(1,dirY); transform.setRow(2,dirZ); transform.flags |= TMat3F::Matrix_HasRotation; transform.flags &= ~TMat3F::Matrix_HasScale; if (useAxisSpin == true) { RMat3F tempRot(EulerF(0, axisSpin, 0)); TMat3F tempOutput; m_mul(tempRot, transform, &tempOutput); transform = tempOutput; } }
void Player::setMountObject (GameBase *object, int in_mountPoint) { if(mount) clearNotify(mount); setMaskBits(MountMask); mount = object; mountPoint = in_mountPoint; if(mount) { deleteNotify(mount); TMat3F tmat; mount->getObjectMountTransform(mountPoint, &tmat); if (!mountPoint) { Point3F rot = getRot (); tmat.set (EulerF (rot.x, rot.y, rot.z), tmat.p); } setTransform(tmat); EulerF angles; tmat.angles(&angles); if (mountPoint < 1) setRot (Point3F (0, 0, angles.z)); else if (mountPoint == 1) setRot (Point3F (0, 0, 0)); else { Point3F rot = getRot (); rot.z -= angles.z; setRot (rot); } setImageTriggerUp(0); setLinearVelocity (Point3F (0, 0, 0)); } }
void Player::getCameraTransform(float camDist, TMat3F *transform) { #define MinCamDist 0.01 if(camDist < MinCamDist) { *transform = getEyeTransform(); transform->p.z += m_sin (bounce * 2) / 120; } else { int node = chaseNode; TMat3F nmat = image.shape->getTransform(node); nmat.set(EulerF(viewPitch, 0, 0), nmat.p); nmat.p.x = nmat.p.y = 0; m_mul(nmat, getTransform(), transform); transform->p.z += m_sin (bounce * 2) / 120; // Point3F dir; // transform->getRow(1, &dir); // float oldDist = dir.lenf(); validateEyePoint (transform, camDist); // if (newDist > oldDist) // cg.psc->setCamDist(newDist); } }
/// Apply the MAYA texture transform to the given UV coordinates void ColladaExtension_effect::applyTextureTransform(Point2F& uv, F32 time) { // This function will be called for every tvert, every frame. So cache the // texture transform parameters to avoid interpolating them every call (since // they are constant for all tverts for a given 't') if (time != lastAnimTime) { // Update texture transform textureTransform.set(EulerF(0, 0, rotateUV.getValue(time))); textureTransform.setPosition(Point3F( offsetU.getValue(time) + noiseU.getValue(time)*gRandGen.randF(), offsetV.getValue(time) + noiseV.getValue(time)*gRandGen.randF(), 0)); textureTransform.scale(Point3F(repeatU.getValue(time), repeatV.getValue(time), 1.0f)); lastAnimTime = time; } // Apply texture transform Point3F result; textureTransform.mulP(Point3F(uv.x, uv.y, 0), &result); uv.x = result.x; uv.y = result.y; }
void WorldEditorSelection::rotate(const EulerF & rot, const Point3F & center) { // single selections will rotate around own axis, multiple about world if(size() == 1) { SceneObject* object = dynamic_cast< SceneObject* >( at( 0 ) ); if( object ) { MatrixF mat = object->getTransform(); Point3F pos; mat.getColumn(3, &pos); // get offset in obj space Point3F offset = pos - center; MatrixF wMat = object->getWorldTransform(); wMat.mulV(offset); // MatrixF transform(EulerF(0,0,0), -offset); transform.mul(MatrixF(rot)); transform.mul(MatrixF(EulerF(0,0,0), offset)); mat.mul(transform); object->setTransform(mat); } } else { for( iterator iter = begin(); iter != end(); ++ iter ) { SceneObject* object = dynamic_cast< SceneObject* >( *iter ); if( !object ) continue; MatrixF mat = object->getTransform(); Point3F pos; mat.getColumn(3, &pos); // get offset in obj space Point3F offset = pos - center; MatrixF transform(rot); Point3F wOffset; transform.mulV(offset, &wOffset); MatrixF wMat = object->getWorldTransform(); wMat.mulV(offset); // transform.set(EulerF(0,0,0), -offset); mat.setColumn(3, Point3F(0,0,0)); wMat.setColumn(3, Point3F(0,0,0)); transform.mul(wMat); transform.mul(MatrixF(rot)); transform.mul(mat); mat.mul(transform); mat.normalize(); mat.setColumn(3, wOffset + center); object->setTransform(mat); } } mCentroidValid = false; }
void FontRenderBatcher::render( F32 rot, const Point2F &offset ) { if( mLength == 0 ) return; GFX->setStateBlock(mFontSB); for(U32 i = 0; i < GFX->getNumSamplers(); i++) GFX->setTexture(i, NULL); MatrixF rotMatrix; bool doRotation = rot != 0.f; if(doRotation) rotMatrix.set( EulerF( 0.0, 0.0, mDegToRad( rot ) ) ); // Write verts out. U32 currentPt = 0; GFXVertexBufferHandle<GFXVertexPCT> verts(GFX, mLength * 6, GFXBufferTypeVolatile); verts.lock(); for( S32 i = 0; i < mSheets.size(); i++ ) { // Do some early outs... if(!mSheets[i]) continue; if(!mSheets[i]->numChars) continue; mSheets[i]->startVertex = currentPt; const GFXTextureObject *tex = mFont->getTextureHandle(i); for( S32 j = 0; j < mSheets[i]->numChars; j++ ) { // Get some general info to proceed with... const CharMarker &m = mSheets[i]->charIndex[j]; const PlatformFont::CharInfo &ci = mFont->getCharInfo( m.c ); // Where are we drawing it? F32 drawY = offset.y + mFont->getBaseline() - ci.yOrigin * TEXT_MAG; F32 drawX = offset.x + m.x + ci.xOrigin; // Figure some values. const F32 texWidth = (F32)tex->getWidth(); const F32 texHeight = (F32)tex->getHeight(); const F32 texLeft = (F32)(ci.xOffset) / texWidth; const F32 texRight = (F32)(ci.xOffset + ci.width) / texWidth; const F32 texTop = (F32)(ci.yOffset) / texHeight; const F32 texBottom = (F32)(ci.yOffset + ci.height) / texHeight; const F32 fillConventionOffset = GFX->getFillConventionOffset(); const F32 screenLeft = drawX - fillConventionOffset; const F32 screenRight = drawX - fillConventionOffset + ci.width * TEXT_MAG; const F32 screenTop = drawY - fillConventionOffset; const F32 screenBottom = drawY - fillConventionOffset + ci.height * TEXT_MAG; // Build our vertices. We NEVER read back from the buffer, that's // incredibly slow, so for rotation do it into tmp. This code is // ugly as sin. Point3F tmp; tmp.set( screenLeft, screenTop, 0.f ); if(doRotation) rotMatrix.mulP( tmp, &verts[currentPt].point); else verts[currentPt].point = tmp; verts[currentPt].color = m.color; verts[currentPt].texCoord.set( texLeft, texTop ); currentPt++; tmp.set( screenLeft, screenBottom, 0.f ); if(doRotation) rotMatrix.mulP( tmp, &verts[currentPt].point); else verts[currentPt].point = tmp; verts[currentPt].color = m.color; verts[currentPt].texCoord.set( texLeft, texBottom ); currentPt++; tmp.set( screenRight, screenBottom, 0.f ); if(doRotation) rotMatrix.mulP( tmp, &verts[currentPt].point); else verts[currentPt].point = tmp; verts[currentPt].color = m.color; verts[currentPt].texCoord.set( texRight, texBottom ); currentPt++; tmp.set( screenRight, screenBottom, 0.f ); if(doRotation) rotMatrix.mulP( tmp, &verts[currentPt].point); else verts[currentPt].point = tmp; verts[currentPt].color = m.color; verts[currentPt].texCoord.set( texRight, texBottom ); currentPt++; tmp.set( screenRight, screenTop, 0.f ); if(doRotation) rotMatrix.mulP( tmp, &verts[currentPt].point); else verts[currentPt].point = tmp; verts[currentPt].color = m.color; verts[currentPt].texCoord.set( texRight, texTop ); currentPt++; tmp.set( screenLeft, screenTop, 0.f ); if(doRotation) rotMatrix.mulP( tmp, &verts[currentPt].point); else verts[currentPt].point = tmp; verts[currentPt].color = m.color; verts[currentPt].texCoord.set( texLeft, texTop ); currentPt++; } } verts->unlock(); AssertFatal(currentPt <= mLength * 6, "FontRenderBatcher::render - too many verts for length of string!"); GFX->setVertexBuffer(verts); GFX->setupGenericShaders( GFXDevice::GSAddColorTexture ); // Now do an optimal render! for( S32 i = 0; i < mSheets.size(); i++ ) { if(!mSheets[i]) continue; if(!mSheets[i]->numChars ) continue; GFX->setTexture( 0, mFont->getTextureHandle(i) ); GFX->drawPrimitive(GFXTriangleList, mSheets[i]->startVertex, mSheets[i]->numChars * 2); } }
/** * This method calculates the moves for the AI player * * @param movePtr Pointer to move the move list into */ bool AIPlayer::getAIMove(Move *movePtr) { *movePtr = NullMove; // Use the eye as the current position. MatrixF eye; getEyeTransform(&eye); Point3F location = eye.getPosition(); Point3F rotation = getRotation(); // Orient towards the aim point, aim object, or towards // our destination. if (mAimObject || mAimLocationSet || mMoveState != ModeStop) { // Update the aim position if we're aiming for an object if (mAimObject) mAimLocation = mAimObject->getPosition() + mAimOffset; else if (!mAimLocationSet) mAimLocation = mMoveDestination; F32 xDiff = mAimLocation.x - location.x; F32 yDiff = mAimLocation.y - location.y; if (!mIsZero(xDiff) || !mIsZero(yDiff)) { // First do Yaw // use the cur yaw between -Pi and Pi F32 curYaw = rotation.z; while (curYaw > M_2PI_F) curYaw -= M_2PI_F; while (curYaw < -M_2PI_F) curYaw += M_2PI_F; // find the yaw offset F32 newYaw = mAtan2( xDiff, yDiff ); F32 yawDiff = newYaw - curYaw; // make it between 0 and 2PI if( yawDiff < 0.0f ) yawDiff += M_2PI_F; else if( yawDiff >= M_2PI_F ) yawDiff -= M_2PI_F; // now make sure we take the short way around the circle if( yawDiff > M_PI_F ) yawDiff -= M_2PI_F; else if( yawDiff < -M_PI_F ) yawDiff += M_2PI_F; movePtr->yaw = yawDiff; // Next do pitch. if (!mAimObject && !mAimLocationSet) { // Level out if were just looking at our next way point. Point3F headRotation = getHeadRotation(); movePtr->pitch = -headRotation.x; } else { // This should be adjusted to run from the // eye point to the object's center position. Though this // works well enough for now. F32 vertDist = mAimLocation.z - location.z; F32 horzDist = mSqrt(xDiff * xDiff + yDiff * yDiff); F32 newPitch = mAtan2( horzDist, vertDist ) - ( M_PI_F / 2.0f ); if (mFabs(newPitch) > 0.01f) { Point3F headRotation = getHeadRotation(); movePtr->pitch = newPitch - headRotation.x; } } } } else { // Level out if we're not doing anything else Point3F headRotation = getHeadRotation(); movePtr->pitch = -headRotation.x; } // Move towards the destination if (mMoveState != ModeStop) { F32 xDiff = mMoveDestination.x - location.x; F32 yDiff = mMoveDestination.y - location.y; // Check if we should mMove, or if we are 'close enough' if (mFabs(xDiff) < mMoveTolerance && mFabs(yDiff) < mMoveTolerance) { mMoveState = ModeStop; throwCallback("onReachDestination"); } else { // Build move direction in world space if (mIsZero(xDiff)) movePtr->y = (location.y > mMoveDestination.y) ? -1.0f : 1.0f; else if (mIsZero(yDiff)) movePtr->x = (location.x > mMoveDestination.x) ? -1.0f : 1.0f; else if (mFabs(xDiff) > mFabs(yDiff)) { F32 value = mFabs(yDiff / xDiff); movePtr->y = (location.y > mMoveDestination.y) ? -value : value; movePtr->x = (location.x > mMoveDestination.x) ? -1.0f : 1.0f; } else { F32 value = mFabs(xDiff / yDiff); movePtr->x = (location.x > mMoveDestination.x) ? -value : value; movePtr->y = (location.y > mMoveDestination.y) ? -1.0f : 1.0f; } // Rotate the move into object space (this really only needs // a 2D matrix) Point3F newMove; MatrixF moveMatrix; moveMatrix.set(EulerF(0.0f, 0.0f, -(rotation.z + movePtr->yaw))); moveMatrix.mulV( Point3F( movePtr->x, movePtr->y, 0.0f ), &newMove ); movePtr->x = newMove.x; movePtr->y = newMove.y; // Set movement speed. We'll slow down once we get close // to try and stop on the spot... if (mMoveSlowdown) { F32 speed = mMoveSpeed; F32 dist = mSqrt(xDiff*xDiff + yDiff*yDiff); F32 maxDist = 5.0f; if (dist < maxDist) speed *= dist / maxDist; movePtr->x *= speed; movePtr->y *= speed; mMoveState = ModeSlowing; } else { movePtr->x *= mMoveSpeed; movePtr->y *= mMoveSpeed; mMoveState = ModeMove; } if (mMoveStuckTestCountdown > 0) --mMoveStuckTestCountdown; else { // We should check to see if we are stuck... F32 locationDelta = (location - mLastLocation).len(); if (locationDelta < mMoveStuckTolerance && mDamageState == Enabled) { // If we are slowing down, then it's likely that our location delta will be less than // our move stuck tolerance. Because we can be both slowing and stuck // we should TRY to check if we've moved. This could use better detection. if ( mMoveState != ModeSlowing || locationDelta == 0 ) { mMoveState = ModeStuck; throwCallback("onMoveStuck"); } } } } } // Test for target location in sight if it's an object. The LOS is // run from the eye position to the center of the object's bounding, // which is not very accurate. if (mAimObject) { MatrixF eyeMat; getEyeTransform(&eyeMat); eyeMat.getColumn(3,&location); Point3F targetLoc = mAimObject->getBoxCenter(); // This ray ignores non-static shapes. Cast Ray returns true // if it hit something. RayInfo dummy; if (getContainer()->castRay( location, targetLoc, StaticShapeObjectType | StaticObjectType | TerrainObjectType, &dummy)) { if (mTargetInLOS) { throwCallback( "onTargetExitLOS" ); mTargetInLOS = false; } } else if (!mTargetInLOS) { throwCallback( "onTargetEnterLOS" ); mTargetInLOS = true; } } // Replicate the trigger state into the move so that // triggers can be controlled from scripts. for( int i = 0; i < MaxTriggerKeys; i++ ) movePtr->trigger[i] = getImageTriggerState(i); mLastLocation = location; return true; }