GLint gluProject( GLdouble objx, GLdouble objy, GLdouble objz, const F64 *model, const F64 * proj, const GLint * vp, F64 * winx, F64 * winy, F64 * winz ) { Vector4F v = Vector4F( objx, objy, objz, 1.0f ); MatrixF pmat = MatrixF( false ); for (int i=0; i<16; i++) { ((F32*)pmat)[i] = (float)proj[i]; } MatrixF mmat = MatrixF( false ); for (int i=0; i<16; i++) { ((F32*)mmat)[i] = (float)model[i]; } //Luma: Projection fix mmat.transpose(); pmat.transpose(); (pmat.mul(mmat)).mul(v); //Luma: Projection fix if(v.w == 0.0f) { return GL_FALSE; } F32 invW = 1.0f / v.w; v.x *= invW; v.y *= invW; v.z *= invW; *winx = (GLfloat)vp[0] + (GLfloat)vp[2] * (v.x + 1.0f) * 0.5f; *winy = (GLfloat)vp[1] + (GLfloat)vp[3] * (v.y + 1.0f) * 0.5f; *winz = (v.z + 1.0f) * 0.5f; int glError; glError = TEST_FOR_OPENGL_ERRORS return GL_TRUE; }
void GLSimpleShader::updateTransforms() { MatrixF combined = mProjectionMatrix * mModelViewMatrix; combined.transpose(); glUniformMatrix4fv(mUniforms[kGLSimpleUniformMVPMatrix], 1, GL_FALSE, (F32*)combined); combined = mModelViewMatrix; combined.transpose(); glUniformMatrix4fv(mUniforms[kGLSimpleUniformMVMatrix], 1, GL_FALSE, (F32*)combined); glUniform3fv(mUniforms[kGLSimpleUniformLightColor], 1, mLightColor); glUniform3fv(mUniforms[kGLSimpleUniformLightPos], 1, mLightPos); }
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; }
/** * This method gets the move list for an object, in the case * of the AI, it actually calculates the moves, and then * sends them down the pipe. * * @param movePtr Pointer to move the move list into * @param numMoves Number of moves in the move list */ U32 AIClient::getMoveList( Move **movePtr,U32 *numMoves ) { //initialize the move structure and return pointers mMove = NullMove; *movePtr = &mMove; *numMoves = 1; // Check if we got a player mPlayer = NULL; mPlayer = dynamic_cast<Player *>( getControlObject() ); // We got a something controling us? if( !mPlayer ) return 1; // What is The Matrix? MatrixF moveMatrix; moveMatrix.set( EulerF( 0, 0, 0 ) ); moveMatrix.setColumn( 3, Point3F( 0, 0, 0 ) ); moveMatrix.transpose(); // Position / rotation variables F32 curYaw, curPitch; F32 newYaw, newPitch; F32 xDiff, yDiff; F32 moveSpeed = mMoveSpeed; switch( mMoveMode ) { case ModeStop: return 1; // Stop means no action break; case ModeStuck: // Fall through, so we still try to move case ModeMove: // Get my location MatrixF const& myTransform = mPlayer->getTransform(); myTransform.getColumn( 3, &mLocation ); // Set rotation variables Point3F rotation = mPlayer->getRotation(); Point3F headRotation = mPlayer->getHeadRotation(); curYaw = rotation.z; curPitch = headRotation.x; xDiff = mAimLocation.x - mLocation.x; yDiff = mAimLocation.y - mLocation.y; // first do Yaw if( !mIsZero( xDiff ) || !mIsZero( yDiff ) ) { // use the cur yaw between -Pi and Pi while( curYaw > M_2PI_F ) curYaw -= M_2PI_F; while( curYaw < -M_2PI_F ) curYaw += M_2PI_F; // find the new yaw newYaw = mAtan2( xDiff, yDiff ); // find the yaw diff 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_2PI_F ) yawDiff -= M_2PI_F; else if( yawDiff < -M_2PI_F ) yawDiff += M_2PI_F; mMove.yaw = yawDiff; // set up the movement matrix moveMatrix.set( EulerF( 0.0f, 0.0f, newYaw ) ); } else moveMatrix.set( EulerF( 0.0f, 0.0f, curYaw ) ); // next do pitch F32 horzDist = Point2F( mAimLocation.x, mAimLocation.y ).len(); if( !mIsZero( horzDist ) ) { //we shoot from the gun, not the eye... F32 vertDist = mAimLocation.z; newPitch = mAtan2( horzDist, vertDist ) - ( M_2PI_F / 2.0f ); F32 pitchDiff = newPitch - curPitch; mMove.pitch = pitchDiff; } // finally, mMove towards mMoveDestination xDiff = mMoveDestination.x - mLocation.x; yDiff = mMoveDestination.y - mLocation.y; // Check if we should mMove, or if we are 'close enough' if( ( ( mFabs( xDiff ) > mMoveTolerance ) || ( mFabs( yDiff ) > mMoveTolerance ) ) && ( !mIsZero( mMoveSpeed ) ) ) { if( mIsZero( xDiff ) ) mMove.y = ( mLocation.y > mMoveDestination.y ? -moveSpeed : moveSpeed ); else if( mIsZero( yDiff ) ) mMove.x = ( mLocation.x > mMoveDestination.x ? -moveSpeed : moveSpeed ); else if( mFabs( xDiff ) > mFabs( yDiff ) ) { F32 value = mFabs( yDiff / xDiff ) * mMoveSpeed; mMove.y = ( mLocation.y > mMoveDestination.y ? -value : value ); mMove.x = ( mLocation.x > mMoveDestination.x ? -moveSpeed : moveSpeed ); } else { F32 value = mFabs( xDiff / yDiff ) * mMoveSpeed; mMove.x = ( mLocation.x > mMoveDestination.x ? -value : value ); mMove.y = ( mLocation.y > mMoveDestination.y ? -moveSpeed : moveSpeed ); } //now multiply the mMove vector by the transpose of the object rotation matrix moveMatrix.transpose(); Point3F newMove; moveMatrix.mulP( Point3F( mMove.x, mMove.y, 0.0f ), &newMove ); //and sub the result back in the mMove structure mMove.x = newMove.x; mMove.y = newMove.y; // We should check to see if we are stuck... if( mLocation.x == mLastLocation.x && mLocation.y == mLastLocation.y && mLocation.z == mLastLocation.z ) { // We're stuck...probably setMoveMode( ModeStuck ); } else setMoveMode( ModeMove ); } else { // Ok, we are close enough, lets stop // setMoveMode( ModeStop ); // DON'T use this, it'll throw the wrong callback mMoveMode = ModeStop; throwCallback( "onReachDestination" ); // Callback } break; } // Test for target location in sight RayInfo dummy; Point3F targetLoc = mMoveDestination; // Change this if( mPlayer ) { if( !mPlayer->getContainer()->castRay( mLocation, targetLoc, StaticShapeObjectType | StaticObjectType | TerrainObjectType, &dummy ) ) { if( !mTargetInLOS ) throwCallback( "onTargetEnterLOS" ); } else { if( mTargetInLOS ) throwCallback( "onTargetExitLOS" ); } } // Copy over the trigger status for( int i = 0; i < MaxTriggerKeys; i++ ) { mMove.trigger[i] = mTriggers[i]; mTriggers[i] = false; } return 1; }