void HoverVehicle::updateEmitter(bool active,F32 dt,ParticleEmitterData *emitter,S32 idx,S32 count) { if (!emitter) return; for (S32 j = idx; j < idx + count; j++) if (active) { if (mDataBlock->jetNode[j] != -1) { if (!bool(mJetEmitter[j])) { mJetEmitter[j] = new ParticleEmitter; mJetEmitter[j]->onNewDataBlock( emitter, false ); mJetEmitter[j]->registerObject(); } MatrixF mat; Point3F pos,axis; mat.mul(getRenderTransform(), mShapeInstance->mNodeTransforms[mDataBlock->jetNode[j]]); mat.getColumn(1,&axis); mat.getColumn(3,&pos); mJetEmitter[j]->emitParticles(pos,true,axis,getVelocity(),(U32)(dt * 1000.0f)); } } else { for (S32 j = idx; j < idx + count; j++) if (bool(mJetEmitter[j])) { mJetEmitter[j]->deleteWhenEmpty(); mJetEmitter[j] = 0; } } }
void TurretShape::getRenderWeaponMountTransform( F32 delta, S32 mountPoint, const MatrixF &xfm, MatrixF *outMat ) { // Returns mount point to world space transform if ( mountPoint >= 0 && mountPoint < SceneObject::NumMountPoints) { S32 ni = mDataBlock->weaponMountNode[mountPoint]; if (ni != -1) { MatrixF mountTransform = mShapeInstance->mNodeTransforms[ni]; mountTransform.mul( xfm ); const Point3F& scale = getScale(); // The position of the mount point needs to be scaled. Point3F position = mountTransform.getPosition(); position.convolve( scale ); mountTransform.setPosition( position ); // Also we would like the object to be scaled to the model. mountTransform.scale( scale ); outMat->mul(getRenderTransform(), mountTransform); return; } } // Then let SceneObject handle it. GrandParent::getRenderMountTransform( delta, mountPoint, xfm, outMat ); }
void WorldEditorSelection::offset( const Point3F& offset, F32 gridSnap ) { for( iterator iter = begin(); iter != end(); ++ iter ) { SceneObject* obj = dynamic_cast<SceneObject*>( *iter ); if( !obj ) continue; MatrixF mat = obj->getTransform(); Point3F wPos; mat.getColumn(3, &wPos); // adjust wPos += offset; if( gridSnap != 0.f ) { wPos.x -= mFmod( wPos.x, gridSnap ); wPos.y -= mFmod( wPos.y, gridSnap ); wPos.z -= mFmod( wPos.z, gridSnap ); } mat.setColumn(3, wPos); obj->setTransform(mat); } mCentroidValid = false; }
void RigidBody::setRenderPosition(const Point3F& pos, const QuatF& rot) { MatrixF mat; rot.setMatrix(&mat); mat.setColumn(3,pos); setRenderTransform(mat); }
bool ConvexShape::protectedSetSurface( void *object, const char *index, const char *data ) { ConvexShape *shape = static_cast< ConvexShape* >( object ); QuatF quat; Point3F pos; //MatrixF mat; /* dSscanf( data, "%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g", &mat[0], &mat[1], &mat[2], &mat[3], &mat[4], &mat[5], &mat[6], &mat[7], &mat[8], &mat[9], &mat[10], &mat[11], &mat[12], &mat[13], &mat[14], &mat[15] ); */ dSscanf( data, "%g %g %g %g %g %g %g", &quat.x, &quat.y, &quat.z, &quat.w, &pos.x, &pos.y, &pos.z ); MatrixF surface; quat.setMatrix( &surface ); surface.setPosition( pos ); shape->mSurfaces.push_back( surface ); return false; }
void PhysShape::setRotation(const QuatF& rot) { MatrixF tr; rot.setMatrix(&tr); tr.setPosition(getPosition()); setTransform(tr); }
// This "rounds" the projection matrix to remove subtexel movement during shadow map // rasterization. This is here to reduce shadow shimmering. void PSSMLightShadowMap::_roundProjection(const MatrixF& lightMat, const MatrixF& cropMatrix, Point3F &offset, U32 splitNum) { // Round to the nearest shadowmap texel, this helps reduce shimmering MatrixF currentProj = GFX->getProjectionMatrix(); currentProj = cropMatrix * currentProj * lightMat; // Project origin to screen. Point4F originShadow4F(0,0,0,1); currentProj.mul(originShadow4F); Point2F originShadow(originShadow4F.x / originShadow4F.w, originShadow4F.y / originShadow4F.w); // Convert to texture space (0..shadowMapSize) F32 t = mNumSplits < 4 ? mShadowMapTex->getWidth() / mNumSplits : mShadowMapTex->getWidth() / 2; Point2F texelsToTexture(t / 2.0f, mShadowMapTex->getHeight() / 2.0f); if (mNumSplits >= 4) texelsToTexture.y *= 0.5f; originShadow.convolve(texelsToTexture); // Clamp to texel boundary Point2F originRounded; originRounded.x = mFloor(originShadow.x + 0.5f); originRounded.y = mFloor(originShadow.y + 0.5f); // Subtract origin to get an offset to recenter everything on texel boundaries originRounded -= originShadow; // Convert back to texels (0..1) and offset originRounded.convolveInverse(texelsToTexture); offset.x += originRounded.x; offset.y += originRounded.y; }
void Projectile::prepBatchRender( SceneRenderState *state ) { if ( !mProjectileShape ) return; GFXTransformSaver saver; // Set up our TS render state. TSRenderState rdata; rdata.setSceneState( state ); // We might have some forward lit materials // so pass down a query to gather lights. LightQuery query; query.init( getWorldSphere() ); rdata.setLightQuery( &query ); MatrixF mat = getRenderTransform(); mat.scale( mObjScale ); mat.scale( mDataBlock->scale ); GFX->setWorldMatrix( mat ); mProjectileShape->setDetailFromPosAndScale( state, mat.getPosition(), mObjScale ); mProjectileShape->animate(); mProjectileShape->render( rdata ); }
/// Get the world transform of the node at the specified time MatrixF ColladaAppNode::getNodeTransform(F32 time) { // Avoid re-computing the default transform if possible if (defaultTransformValid && time == TSShapeLoader::DefaultTime) { return defaultNodeTransform; } else { MatrixF nodeTransform = getTransform(time); // Check for inverted node coordinate spaces => can happen when modelers // use the 'mirror' tool in their 3d app. Shows up as negative <scale> // transforms in the collada model. if (m_matF_determinant(nodeTransform) < 0.0f) { // Mark this node as inverted so we can mirror mesh geometry, then // de-invert the transform matrix invertMeshes = true; nodeTransform.scale(Point3F(1, 1, -1)); } // Cache the default transform if (time == TSShapeLoader::DefaultTime) { defaultTransformValid = true; defaultNodeTransform = nodeTransform; } return nodeTransform; } }
void Trigger::renderObject( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ) { if(overrideMat) return; GFXStateBlockDesc desc; desc.setZReadWrite( true, false ); desc.setBlend( true ); // Trigger polyhedrons are set up with outward facing normals and CCW ordering // so can't enable backface culling. desc.setCullMode( GFXCullNone ); GFXTransformSaver saver; MatrixF mat = getRenderTransform(); mat.scale( getScale() ); GFX->multWorld( mat ); GFXDrawUtil *drawer = GFX->getDrawUtil(); drawer->drawPolyhedron( desc, mTriggerPolyhedron, ColorI( 255, 192, 0, 45 ) ); // Render wireframe. desc.setFillModeWireframe(); drawer->drawPolyhedron( desc, mTriggerPolyhedron, ColorI::BLACK ); }
void NavPath::resize() { if(!mPoints.size()) { mObjBox.set(Point3F(-0.5f, -0.5f, -0.5f), Point3F( 0.5f, 0.5f, 0.5f)); resetWorldBox(); setTransform(MatrixF(true)); return; } Point3F max(mPoints[0]), min(mPoints[0]), pos(0.0f); for(U32 i = 1; i < mPoints.size(); i++) { Point3F p = mPoints[i]; max.x = getMax(max.x, p.x); max.y = getMax(max.y, p.y); max.z = getMax(max.z, p.z); min.x = getMin(min.x, p.x); min.y = getMin(min.y, p.y); min.z = getMin(min.z, p.z); pos += p; } pos /= mPoints.size(); min -= Point3F(0.5f, 0.5f, 0.5f); max += Point3F(0.5f, 0.5f, 0.5f); mObjBox.set(min - pos, max - pos); MatrixF mat = Parent::getTransform(); mat.setPosition(pos); Parent::setTransform(mat); }
MatrixF VPathNode::getWorldTransform( void ) const { MatrixF mat; getWorldRotation().setMatrix( &mat ); mat.setPosition( getWorldPosition() ); return mat; }
void TSShapeLoader::zapScale(MatrixF& mat) { Point3F invScale = mat.getScale(); invScale.x = invScale.x ? (1.0f / invScale.x) : 0; invScale.y = invScale.y ? (1.0f / invScale.y) : 0; invScale.z = invScale.z ? (1.0f / invScale.z) : 0; mat.scale(invScale); }
void SceneObject::setPosition(const Point3F &pos) { AssertFatal( !mIsNaN( pos ), "SceneObject::setPosition() - The position is NaN!" ); MatrixF xform = mObjToWorld; xform.setColumn(3, pos); setTransform(xform); }
void GjkCollisionState::reset(const MatrixF& a2w, const MatrixF& b2w) { VectorF zero(0,0,0),sa,sb; a2w.mulP(a->support(zero),&sa); b2w.mulP(b->support(zero),&sb); v = sa - sb; dist = v.len(); }
void Sun::_renderCorona( ObjectRenderInst *ri, SceneState *state, BaseMatInstance *overrideMat ) { Point3F sunlightPosition = state->getCameraPosition() - mLight->getDirection() * state->getFarPlane() * 0.9f; // Calculate Billboard Radius (in world units) to be constant, independent of distance. // Takes into account distance, viewport size, and specified size in editor F32 BBRadius = (((sunlightPosition - state->getCameraPosition()).len()) / (GFX->getViewport().extent.x / 640.0)) / 2; BBRadius *= mCoronaScale; GFXTransformSaver saver; if ( state->isReflectPass() ) GFX->setProjectionMatrix( gClientSceneGraph->getNonClipProjection() ); GFX->setStateBlock(mCoronaSB); // Initialize points with basic info Point3F points[4]; points[0] = Point3F(-BBRadius, 0.0, -BBRadius); points[1] = Point3F( BBRadius, 0.0, -BBRadius); points[2] = Point3F( BBRadius, 0.0, BBRadius); points[3] = Point3F(-BBRadius, 0.0, BBRadius); // Get info we need to adjust points MatrixF camView = GFX->getWorldMatrix(); camView.inverse(); // Finalize points for(int i = 0; i < 4; i++) { // align with camera camView.mulV(points[i]); // offset points[i] += sunlightPosition; } // Draw it if ( mCoronaUseLightColor ) PrimBuild::color(mLightColor); else PrimBuild::color(mCoronaTint); GFX->setTexture(0, mCoronaTexture); PrimBuild::begin( GFXTriangleFan, 4 ); PrimBuild::texCoord2f(0, 0); PrimBuild::vertex3fv(points[0]); PrimBuild::texCoord2f(1, 0); PrimBuild::vertex3fv(points[1]); PrimBuild::texCoord2f(1, 1); PrimBuild::vertex3fv(points[2]); PrimBuild::texCoord2f(0, 1); PrimBuild::vertex3fv(points[3]); PrimBuild::end(); }
void GFXDrawUtil::drawSphere( const GFXStateBlockDesc &desc, F32 radius, const Point3F &pos, const ColorI &color, bool drawTop, bool drawBottom, const MatrixF *xfm ) { MatrixF mat; if ( xfm ) mat = *xfm; else mat = MatrixF::Identity; mat.scale(Point3F(radius,radius,radius)); mat.setPosition(pos); GFX->pushWorldMatrix(); GFX->multWorld(mat); const SphereMesh::TriangleMesh * sphereMesh = gSphere.getMesh(2); S32 numPoly = sphereMesh->numPoly; S32 totalPoly = 0; GFXVertexBufferHandle<GFXVertexPC> verts(mDevice, numPoly*3, GFXBufferTypeVolatile); verts.lock(); S32 vertexIndex = 0; for (S32 i=0; i<numPoly; i++) { if (!drawBottom) { if (sphereMesh->poly[i].pnt[0].z < -0.01f || sphereMesh->poly[i].pnt[1].z < -0.01f || sphereMesh->poly[i].pnt[2].z < -0.01f) continue; } if (!drawTop) { if (sphereMesh->poly[i].pnt[0].z > 0.01f || sphereMesh->poly[i].pnt[1].z > 0.01f || sphereMesh->poly[i].pnt[2].z > 0.01f) continue; } totalPoly++; verts[vertexIndex].point = sphereMesh->poly[i].pnt[0]; verts[vertexIndex].color = color; vertexIndex++; verts[vertexIndex].point = sphereMesh->poly[i].pnt[1]; verts[vertexIndex].color = color; vertexIndex++; verts[vertexIndex].point = sphereMesh->poly[i].pnt[2]; verts[vertexIndex].color = color; vertexIndex++; } verts.unlock(); mDevice->setStateBlockByDesc( desc ); mDevice->setVertexBuffer( verts ); mDevice->setupGenericShaders(); mDevice->drawPrimitive( GFXTriangleList, 0, totalPoly ); GFX->popWorldMatrix(); }
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); }
bool TurretShape::getWorldNodeTransform(S32 node, MatrixF& mat) { MatrixF nodeMat; if (!getNodeTransform(node, nodeMat)) return false; nodeMat.affineInverse(); mat = nodeMat; return true; }
void ForestConvex::getFeatures( const MatrixF &mat, const VectorF &n, ConvexFeature *cf ) { cf->material = 0; cf->object = mObject; TSShapeInstance *si = mData->getShapeInstance(); TSShape::ConvexHullAccelerator* pAccel = si->getShape()->getAccelerator(mData->getCollisionDetails()[hullId]); AssertFatal(pAccel != NULL, "Error, no accel!"); F32 currMaxDP = mDot(pAccel->vertexList[0], n); U32 index = 0; U32 i; for (i = 1; i < pAccel->numVerts; i++) { F32 dp = mDot(pAccel->vertexList[i], n); if (dp > currMaxDP) { currMaxDP = dp; index = i; } } const U8* emitString = pAccel->emitStrings[index]; U32 currPos = 0; U32 numVerts = emitString[currPos++]; for (i = 0; i < numVerts; i++) { cf->mVertexList.increment(); U32 index = emitString[currPos++]; mat.mulP(pAccel->vertexList[index], &cf->mVertexList.last()); } U32 numEdges = emitString[currPos++]; for (i = 0; i < numEdges; i++) { U32 ev0 = emitString[currPos++]; U32 ev1 = emitString[currPos++]; cf->mEdgeList.increment(); cf->mEdgeList.last().vertex[0] = ev0; cf->mEdgeList.last().vertex[1] = ev1; } U32 numFaces = emitString[currPos++]; for (i = 0; i < numFaces; i++) { cf->mFaceList.increment(); U32 plane = emitString[currPos++]; mat.mulV(pAccel->normalList[plane], &cf->mFaceList.last().normal); for (U32 j = 0; j < 3; j++) cf->mFaceList.last().vertex[j] = emitString[currPos++]; } }
Box3F T3DSceneComponent::getWorldBox() { if (DirtyWorldBox && !LockWorldBox) _UpdateWorldBox(); MatrixF mat = getTransform3D()->getWorldMatrix(); Box3F box = getObjectBox(); mat.mul(box); return box; }
void Item::interpolateTick(F32 dt) { Parent::interpolateTick(dt); // Client side interpolation Point3F pos = delta.pos + delta.posVec * dt; MatrixF mat = mRenderObjToWorld; mat.setColumn(3,pos); setRenderTransform(mat); delta.dt = dt; }
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); }
bool AIPlayer::onAdd() { if (!Parent::onAdd()) return false; // Use the eye as the current position (see getAIMove) MatrixF eye; getEyeTransform(&eye); mLastLocation = eye.getPosition(); return true; }
void OrientedBox3F::set( const MatrixF& transform, const Point3F& extents ) { mCenter = transform.getPosition(); mAxes[ RightVector ] = transform.getRightVector(); mAxes[ ForwardVector ] = transform.getForwardVector(); mAxes[ UpVector ] = transform.getUpVector(); mHalfExtents = extents * 0.5f; _initPoints(); }
void SkyBox::_renderObject( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *mi ) { GFXDEBUGEVENT_SCOPE( SkyBox_RenderObject, ColorF::WHITE ); GFXTransformSaver saver; GFX->setVertexBuffer( mVB ); MatrixF worldMat = MatrixF::Identity; worldMat.setPosition( state->getCameraPosition() ); SceneData sgData; sgData.init( state ); sgData.objTrans = &worldMat; mMatrixSet->restoreSceneViewProjection(); mMatrixSet->setWorld( worldMat ); if ( state->isReflectPass() ) mMatrixSet->setProjection( state->getSceneManager()->getNonClipProjection() ); while ( mMatInstance->setupPass( state, sgData ) ) { mMatInstance->setTransforms( *mMatrixSet, state ); mMatInstance->setSceneInfo( state, sgData ); GFX->drawPrimitive( GFXTriangleList, 0, mPrimCount ); } // Draw render band. if ( mFogBandHeight > 0 && mFogBandMatInst ) { const FogData &fog = state->getSceneManager()->getFogData(); if ( mLastFogColor != fog.color ) { mLastFogColor = fog.color; _initRender(); } // Just need it to follow the camera... no rotation. MatrixF camPosMat( MatrixF::Identity ); camPosMat.setPosition( worldMat.getPosition() ); sgData.objTrans = &camPosMat; mMatrixSet->setWorld( *sgData.objTrans ); while ( mFogBandMatInst->setupPass( state, sgData ) ) { mFogBandMatInst->setTransforms( *mMatrixSet, state ); mFogBandMatInst->setSceneInfo( state, sgData ); GFX->setVertexBuffer( mFogBandVB ); GFX->drawPrimitive( GFXTriangleList, 0, 16 ); } } }
void SFXXAudioVoice::setTransform( const MatrixF& transform ) { transform.getColumn( 3, (Point3F*)&mEmitter.Position ); transform.getColumn( 1, (Point3F*)&mEmitter.OrientFront ); transform.getColumn( 2, (Point3F*)&mEmitter.OrientTop ); // XAudio and Torque use opposite handedness, so // flip the z coord to account for that. mEmitter.Position.z *= -1.0f; mEmitter.OrientFront.z *= -1.0f; mEmitter.OrientTop.z *= -1.0f; }
void GFXGLDevice::setClipRect( const RectI &inRect ) { AssertFatal(mCurrentRT.isValid(), "GFXGLDevice::setClipRect - must have a render target set to do any rendering operations!"); // Clip the rect against the renderable size. Point2I size = mCurrentRT->getSize(); RectI maxRect(Point2I(0,0), size); mClip = inRect; mClip.intersect(maxRect); // Create projection matrix. See http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/ortho.html const F32 left = mClip.point.x; const F32 right = mClip.point.x + mClip.extent.x; const F32 bottom = mClip.extent.y; const F32 top = 0.0f; const F32 nearPlane = 0.0f; const F32 farPlane = 1.0f; const F32 tx = -(right + left)/(right - left); const F32 ty = -(top + bottom)/(top - bottom); const F32 tz = -(farPlane + nearPlane)/(farPlane - nearPlane); static Point4F pt; pt.set(2.0f / (right - left), 0.0f, 0.0f, 0.0f); mProjectionMatrix.setColumn(0, pt); pt.set(0.0f, 2.0f/(top - bottom), 0.0f, 0.0f); mProjectionMatrix.setColumn(1, pt); pt.set(0.0f, 0.0f, -2.0f/(farPlane - nearPlane), 0.0f); mProjectionMatrix.setColumn(2, pt); pt.set(tx, ty, tz, 1.0f); mProjectionMatrix.setColumn(3, pt); // Translate projection matrix. static MatrixF translate(true); pt.set(0.0f, -mClip.point.y, 0.0f, 1.0f); translate.setColumn(3, pt); mProjectionMatrix *= translate; setMatrix(GFXMatrixProjection, mProjectionMatrix); MatrixF mTempMatrix(true); setViewMatrix( mTempMatrix ); setWorldMatrix( mTempMatrix ); // Set the viewport to the clip rect RectI viewport(mClip.point.x, mClip.point.y, mClip.extent.x, mClip.extent.y); setViewport(viewport); }
void BoxConvex::emitEdge(S32 v1,S32 v2,const MatrixF& mat,ConvexFeature* cf) { S32 vc = cf->mVertexList.size(); cf->mVertexList.increment(2); Point3F *vp = cf->mVertexList.begin(); mat.mulP(getVertex(v1),&vp[vc]); mat.mulP(getVertex(v2),&vp[vc + 1]); cf->mEdgeList.increment(); ConvexFeature::Edge& edge = cf->mEdgeList.last(); edge.vertex[0] = vc; edge.vertex[1] = vc + 1; }
void TSStatic::_renderNormals( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ) { PROFILE_SCOPE( TSStatic_RenderNormals ); GFXTransformSaver saver; MatrixF mat = getRenderTransform(); mat.scale( mObjScale ); GFX->multWorld( mat ); S32 dl = mShapeInstance->getCurrentDetail(); mShapeInstance->renderDebugNormals( mRenderNormalScalar, dl ); }