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); }
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 PhysShape::setRotation(const QuatF& rot) { MatrixF tr; rot.setMatrix(&tr); tr.setPosition(getPosition()); setTransform(tr); }
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; }
MatrixF VPathNode::getWorldTransform( void ) const { MatrixF mat; getWorldRotation().setMatrix( &mat ); mat.setPosition( getWorldPosition() ); return mat; }
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 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 convertRotation(const F32 inRotMat[3][3], MatrixF& outRotation) { // Set rotation. We need to convert from sixense coordinates to // Torque coordinates. The conversion is: // // Sixense Torque // a b c a b c a -c b // d e f --> -g -h -i --> -g i -h // g h i d e f d -f e outRotation.setColumn(0, Point4F( inRotMat[0][0], -inRotMat[0][2], inRotMat[0][1], 0.0f)); outRotation.setColumn(1, Point4F(-inRotMat[2][0], inRotMat[2][2], -inRotMat[2][1], 0.0f)); outRotation.setColumn(2, Point4F( inRotMat[1][0], -inRotMat[1][2], inRotMat[1][1], 0.0f)); outRotation.setPosition(Point3F::Zero); }
//---------------------------------------------------------------------------- // Explode //---------------------------------------------------------------------------- void Splash::spawnExplosion() { if( !mDataBlock->explosion ) return; Explosion* pExplosion = new Explosion; pExplosion->onNewDataBlock(mDataBlock->explosion, false); MatrixF trans = getTransform(); trans.setPosition( getPosition() ); pExplosion->setTransform( trans ); pExplosion->setInitialState( trans.getPosition(), VectorF(0,0,1), 1); if (!pExplosion->registerObject()) delete pExplosion; }
void WorldEditorSelection::orient(const MatrixF & rot, const Point3F & center) { // Orient all the selected objects to the given rotation for( iterator iter = begin(); iter != end(); ++ iter ) { SceneObject* object = dynamic_cast< SceneObject* >( *iter ); if( !object ) continue; MatrixF mat = rot; mat.setPosition( object->getPosition() ); object->setTransform(mat); } mCentroidValid = false; }
bool TurretShape::getNodeTransform(S32 node, MatrixF& mat) { if (node == -1) return false; MatrixF nodeTransform = mShapeInstance->mNodeTransforms[node]; const Point3F& scale = getScale(); // The position of the node needs to be scaled. Point3F position = nodeTransform.getPosition(); position.convolve( scale ); nodeTransform.setPosition( position ); mat.mul(mObjToWorld, nodeTransform); return true; }
void convertPointableRotation(const Leap::Pointable& pointable, MatrixF& outRotation) { // We need to convert from Motion coordinates to // Torque coordinates. The conversion is: // // Motion Torque // a b c a b c a -c b // d e f --> -g -h -i --> -g i -h // g h i d e f d -f e Leap::Vector pointableFront = -pointable.direction(); Leap::Vector pointableRight = Leap::Vector::up().cross(pointableFront); Leap::Vector pointableUp = pointableFront.cross(pointableRight); outRotation.setColumn(0, Point4F( pointableRight.x, -pointableRight.z, pointableRight.y, 0.0f)); outRotation.setColumn(1, Point4F( -pointableFront.x, pointableFront.z, -pointableFront.y, 0.0f)); outRotation.setColumn(2, Point4F( pointableUp.x, -pointableUp.z, pointableUp.y, 0.0f)); outRotation.setPosition(Point3F::Zero); }
void convertHandRotation(const Leap::Hand& hand, MatrixF& outRotation) { // We need to convert from Motion coordinates to // Torque coordinates. The conversion is: // // Motion Torque // a b c a b c a -c b // d e f --> -g -h -i --> -g i -h // g h i d e f d -f e const Leap::Vector& handToFingers = hand.direction(); Leap::Vector handFront = -handToFingers; const Leap::Vector& handDown = hand.palmNormal(); Leap::Vector handUp = -handDown; Leap::Vector handRight = handUp.cross(handFront); outRotation.setColumn(0, Point4F( handRight.x, -handRight.z, handRight.y, 0.0f)); outRotation.setColumn(1, Point4F( -handFront.x, handFront.z, -handFront.y, 0.0f)); outRotation.setColumn(2, Point4F( handUp.x, -handUp.z, handUp.y, 0.0f)); outRotation.setPosition(Point3F::Zero); }
void GFXDrawUtil::_drawWireCapsule( const GFXStateBlockDesc &desc, const Point3F ¢er, F32 radius, F32 height, const ColorI &color, const MatrixF *xfm ) { MatrixF mat; if ( xfm ) mat = *xfm; else mat = MatrixF::Identity; mat.scale( Point3F(radius,radius,height*0.5f) ); mat.setPosition(center); mDevice->pushWorldMatrix(); mDevice->multWorld(mat); S32 numPoints = sizeof(circlePoints)/sizeof(Point2F); GFXVertexBufferHandle<GFXVertexPC> verts(mDevice, numPoints, GFXBufferTypeVolatile); verts.lock(); for (S32 i=0; i< numPoints; i++) { S32 idx = i & (~1); // just draw the even ones F32 z = i & 1 ? 1.0f : -1.0f; verts[i].point = Point3F(circlePoints[idx].x,circlePoints[idx].y, z); verts[i].color = color; } verts.unlock(); mDevice->setStateBlockByDesc( desc ); mDevice->setVertexBuffer( verts ); mDevice->setupGenericShaders(); for (S32 i=0; i<numPoints; i += 2) mDevice->drawPrimitive(GFXLineStrip, i, 1); mDevice->popWorldMatrix(); Point3F sphereCenter; sphereCenter.z = center.z + 0.5f * height; drawSphere( desc, radius,sphereCenter,color,true,false); sphereCenter.z = center.z - 0.5f * height; drawSphere( desc, radius,sphereCenter,color,false,true); }
void PxSingleActor::interpolateTick( F32 delta ) { Point3F interpPos; QuatF interpRot; // Interpolate the position based on the delta. interpPos.interpolate( mNextPos, mLastPos, delta ); // Interpolate the rotation based on the delta. interpRot.interpolate( mNextRot, mLastRot, delta ); // Set up the interpolated transform. MatrixF interpMat; // Set the interpolated position and rotation. interpRot.setMatrix( &interpMat ); interpMat.setPosition( interpPos ); // Set the transform to the interpolated transform. Parent::setTransform( interpMat ); }
void TurretShape::getWeaponMountTransform( S32 index, const MatrixF &xfm, MatrixF *outMat ) { // Returns mount point to world space transform if ( index >= 0 && index < SceneObject::NumMountPoints) { S32 ni = mDataBlock->weaponMountNode[index]; 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. outMat->mul(mObjToWorld, mountTransform); return; } } // Then let SceneObject handle it. GrandParent::getMountTransform( index, xfm, outMat ); }
void TSMesh::innerRender( TSMaterialList *materials, const TSRenderState &rdata, TSVertexBufferHandle &vb, GFXPrimitiveBufferHandle &pb ) { PROFILE_SCOPE( TSMesh_InnerRender ); if( vertsPerFrame <= 0 ) return; F32 meshVisibility = rdata.getFadeOverride() * mVisibility; if ( meshVisibility < VISIBILITY_EPSILON ) return; const SceneRenderState *state = rdata.getSceneState(); RenderPassManager *renderPass = state->getRenderPass(); MeshRenderInst *coreRI = renderPass->allocInst<MeshRenderInst>(); coreRI->type = RenderPassManager::RIT_Mesh; const MatrixF &objToWorld = GFX->getWorldMatrix(); // Sort by the center point or the bounds. if ( rdata.useOriginSort() ) coreRI->sortDistSq = ( objToWorld.getPosition() - state->getCameraPosition() ).lenSquared(); else { Box3F rBox = mBounds; objToWorld.mul( rBox ); coreRI->sortDistSq = rBox.getSqDistanceToPoint( state->getCameraPosition() ); } if (getFlags(Billboard)) { Point3F camPos = state->getDiffuseCameraPosition(); Point3F objPos; objToWorld.getColumn(3, &objPos); Point3F targetVector = camPos - objPos; if(getFlags(BillboardZAxis)) targetVector.z = 0.0f; targetVector.normalize(); MatrixF orient = MathUtils::createOrientFromDir(targetVector); orient.setPosition(objPos); orient.scale(objToWorld.getScale()); coreRI->objectToWorld = renderPass->allocUniqueXform( orient ); } else coreRI->objectToWorld = renderPass->allocUniqueXform( objToWorld ); coreRI->worldToCamera = renderPass->allocSharedXform(RenderPassManager::View); coreRI->projection = renderPass->allocSharedXform(RenderPassManager::Projection); AssertFatal( vb.isValid(), "TSMesh::innerRender() - Got invalid vertex buffer!" ); AssertFatal( pb.isValid(), "TSMesh::innerRender() - Got invalid primitive buffer!" ); coreRI->vertBuff = &vb; coreRI->primBuff = &pb; coreRI->defaultKey2 = (U32) coreRI->vertBuff; coreRI->materialHint = rdata.getMaterialHint(); coreRI->visibility = meshVisibility; coreRI->cubemap = rdata.getCubemap(); // NOTICE: SFXBB is removed and refraction is disabled! //coreRI->backBuffTex = GFX->getSfxBackBuffer(); for ( S32 i = 0; i < primitives.size(); i++ ) { const TSDrawPrimitive &draw = primitives[i]; // We need to have a material. if ( draw.matIndex & TSDrawPrimitive::NoMaterial ) continue; #ifdef TORQUE_DEBUG // for inspection if you happen to be running in a debugger and can't do bit // operations in your head. S32 triangles = draw.matIndex & TSDrawPrimitive::Triangles; S32 strip = draw.matIndex & TSDrawPrimitive::Strip; S32 fan = draw.matIndex & TSDrawPrimitive::Fan; S32 indexed = draw.matIndex & TSDrawPrimitive::Indexed; S32 type = draw.matIndex & TSDrawPrimitive::TypeMask; TORQUE_UNUSED(triangles); TORQUE_UNUSED(strip); TORQUE_UNUSED(fan); TORQUE_UNUSED(indexed); TORQUE_UNUSED(type); #endif const U32 matIndex = draw.matIndex & TSDrawPrimitive::MaterialMask; BaseMatInstance *matInst = materials->getMaterialInst( matIndex ); #ifndef TORQUE_OS_MAC // Get the instancing material if this mesh qualifies. if ( meshType != SkinMeshType && pb->mPrimitiveArray[i].numVertices < smMaxInstancingVerts ) matInst = InstancingMaterialHook::getInstancingMat( matInst ); #endif // If we don't have a material instance after the overload then // there is nothing to render... skip this primitive. matInst = state->getOverrideMaterial( matInst ); if ( !matInst || !matInst->isValid()) continue; // If the material needs lights then gather them // here once and set them on the core render inst. if ( matInst->isForwardLit() && !coreRI->lights[0] && rdata.getLightQuery() ) rdata.getLightQuery()->getLights( coreRI->lights, 8 ); MeshRenderInst *ri = renderPass->allocInst<MeshRenderInst>(); *ri = *coreRI; ri->matInst = matInst; ri->defaultKey = matInst->getStateHint(); ri->primBuffIndex = i; // Translucent materials need the translucent type. if ( matInst->getMaterial()->isTranslucent() ) { ri->type = RenderPassManager::RIT_Translucent; ri->translucentSort = true; } renderPass->addInst( ri ); } }
void DualParaboloidLightShadowMap::_render( RenderPassManager* renderPass, const SceneRenderState *diffuseState ) { PROFILE_SCOPE(DualParaboloidLightShadowMap_render); const ShadowMapParams *p = mLight->getExtended<ShadowMapParams>(); const LightMapParams *lmParams = mLight->getExtended<LightMapParams>(); const bool bUseLightmappedGeometry = lmParams ? !lmParams->representedInLightmap || lmParams->includeLightmappedGeometryInShadow : true; const U32 texSize = getBestTexSize( 2 ); if ( mShadowMapTex.isNull() || mTexSize != texSize ) { mTexSize = texSize; mShadowMapTex.set( mTexSize * 2, mTexSize, ShadowMapFormat, &ShadowMapProfile, "DualParaboloidLightShadowMap" ); mShadowMapDepth = _getDepthTarget( mShadowMapTex->getWidth(), mShadowMapTex->getHeight() ); } GFXFrustumSaver frustSaver; GFXTransformSaver saver; // Set and Clear target GFX->pushActiveRenderTarget(); mTarget->attachTexture(GFXTextureTarget::Color0, mShadowMapTex); mTarget->attachTexture( GFXTextureTarget::DepthStencil, mShadowMapDepth ); GFX->setActiveRenderTarget(mTarget); GFX->clear(GFXClearTarget | GFXClearStencil | GFXClearZBuffer, ColorI::WHITE, 1.0f, 0); const bool bUseSinglePassDPM = (p->shadowType == ShadowType_DualParaboloidSinglePass); // Set up matrix and visible distance mWorldToLightProj = mLight->getTransform(); mWorldToLightProj.inverse(); const F32 &lightRadius = mLight->getRange().x; const F32 paraboloidNearPlane = 0.01f; const F32 renderPosOffset = 0.01f; // Alter for creation of scene state if this is a single pass map if(bUseSinglePassDPM) { VectorF camDir; MatrixF temp = mLight->getTransform(); temp.getColumn(1, &camDir); temp.setPosition(mLight->getPosition() - camDir * (lightRadius + renderPosOffset)); temp.inverse(); GFX->setWorldMatrix(temp); GFX->setOrtho(-lightRadius, lightRadius, -lightRadius, lightRadius, paraboloidNearPlane, 2.0f * lightRadius, true); } else { VectorF camDir; MatrixF temp = mLight->getTransform(); temp.getColumn(1, &camDir); temp.setPosition(mLight->getPosition() - camDir * renderPosOffset); temp.inverse(); GFX->setWorldMatrix(temp); GFX->setOrtho(-lightRadius, lightRadius, -lightRadius, lightRadius, paraboloidNearPlane, lightRadius, true); } SceneManager* sceneManager = diffuseState->getSceneManager(); // Front map render { SceneRenderState frontMapRenderState ( sceneManager, SPT_Shadow, SceneCameraState::fromGFXWithViewport( diffuseState->getViewport() ), renderPass ); frontMapRenderState.getMaterialDelegate().bind( this, &LightShadowMap::getShadowMaterial ); frontMapRenderState.renderNonLightmappedMeshes( true ); frontMapRenderState.renderLightmappedMeshes( bUseLightmappedGeometry ); frontMapRenderState.setDiffuseCameraTransform( diffuseState->getCameraTransform() ); frontMapRenderState.setWorldToScreenScale( diffuseState->getWorldToScreenScale() ); if(bUseSinglePassDPM) { GFX->setWorldMatrix(mWorldToLightProj); frontMapRenderState.getRenderPass()->getMatrixSet().setSceneView(mWorldToLightProj); GFX->setOrtho(-lightRadius, lightRadius, -lightRadius, lightRadius, paraboloidNearPlane, lightRadius, true); } GFXDEBUGEVENT_SCOPE( DualParaboloidLightShadowMap_Render_FrontFacingParaboloid, ColorI::RED ); mShadowMapScale.set(0.5f, 1.0f); mShadowMapOffset.set(-0.5f, 0.0f); sceneManager->renderSceneNoLights( &frontMapRenderState, SHADOW_TYPEMASK ); _debugRender( &frontMapRenderState ); } // Back map render if(!bUseSinglePassDPM) { GFXDEBUGEVENT_SCOPE( DualParaboloidLightShadowMap_Render_BackFacingParaboloid, ColorI::RED ); mShadowMapScale.set(0.5f, 1.0f); mShadowMapOffset.set(0.5f, 0.0f); // Invert direction on camera matrix VectorF right, forward; MatrixF temp = mLight->getTransform(); temp.getColumn( 1, &forward ); temp.getColumn( 0, &right ); forward *= -1.0f; right *= -1.0f; temp.setColumn( 1, forward ); temp.setColumn( 0, right ); temp.setPosition(mLight->getPosition() - forward * -renderPosOffset); temp.inverse(); GFX->setWorldMatrix(temp); // Create an inverted scene state for the back-map SceneRenderState backMapRenderState ( sceneManager, SPT_Shadow, SceneCameraState::fromGFXWithViewport( diffuseState->getViewport() ), renderPass ); backMapRenderState.getMaterialDelegate().bind( this, &LightShadowMap::getShadowMaterial ); backMapRenderState.renderNonLightmappedMeshes( true ); backMapRenderState.renderLightmappedMeshes( bUseLightmappedGeometry ); backMapRenderState.setDiffuseCameraTransform( diffuseState->getCameraTransform() ); backMapRenderState.setWorldToScreenScale( diffuseState->getWorldToScreenScale() ); backMapRenderState.getRenderPass()->getMatrixSet().setSceneView(temp); // Draw scene sceneManager->renderSceneNoLights( &backMapRenderState ); _debugRender( &backMapRenderState ); } mTarget->resolve(); GFX->popActiveRenderTarget(); }
void ConvexShape::_renderDebug( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *mat ) { GFXDrawUtil *drawer = GFX->getDrawUtil(); GFX->setTexture( 0, NULL ); // Render world box. if ( false ) { Box3F wbox( mWorldBox ); //if ( getServerObject() ) // Box3F wbox = static_cast<ConvexShape*>( getServerObject() )->mWorldBox; GFXStateBlockDesc desc; desc.setCullMode( GFXCullNone ); desc.setFillModeWireframe(); drawer->drawCube( desc, wbox, ColorI::RED ); } const Vector< Point3F > &pointList = mGeometry.points; const Vector< ConvexShape::Face > &faceList = mGeometry.faces; // Render Edges. if ( false ) { GFXTransformSaver saver; //GFXFrustumSaver fsaver; MatrixF xfm( getRenderTransform() ); xfm.scale( getScale() ); GFX->multWorld( xfm ); GFXStateBlockDesc desc; desc.setZReadWrite( true, false ); desc.setBlend( true ); GFX->setStateBlockByDesc( desc ); //MathUtils::getZBiasProjectionMatrix( 0.01f, state->getFrustum(), ) const Point3F &camFvec = state->getCameraTransform().getForwardVector(); for ( S32 i = 0; i < faceList.size(); i++ ) { const ConvexShape::Face &face = faceList[i]; const Vector< ConvexShape::Edge > &edgeList = face.edges; const Vector< U32 > &facePntList = face.points; PrimBuild::begin( GFXLineList, edgeList.size() * 2 ); PrimBuild::color( ColorI::WHITE * 0.8f ); for ( S32 j = 0; j < edgeList.size(); j++ ) { PrimBuild::vertex3fv( pointList[ facePntList[ edgeList[j].p0 ] ] - camFvec * 0.001f ); PrimBuild::vertex3fv( pointList[ facePntList[ edgeList[j].p1 ] ] - camFvec * 0.001f ); } PrimBuild::end(); } } ColorI faceColorsx[4] = { ColorI( 255, 0, 0 ), ColorI( 0, 255, 0 ), ColorI( 0, 0, 255 ), ColorI( 255, 0, 255 ) }; MatrixF objToWorld( mObjToWorld ); objToWorld.scale( mObjScale ); // Render faces centers/colors. if ( false ) { GFXStateBlockDesc desc; desc.setCullMode( GFXCullNone ); Point3F size( 0.1f ); for ( S32 i = 0; i < faceList.size(); i++ ) { ColorI color = faceColorsx[ i % 4 ]; S32 div = ( i / 4 ) * 4; if ( div > 0 ) color /= div; color.alpha = 255; Point3F pnt; objToWorld.mulP( faceList[i].centroid, &pnt ); drawer->drawCube( desc, size, pnt, color, NULL ); } } // Render winding order. if ( false ) { GFXStateBlockDesc desc; desc.setCullMode( GFXCullNone ); desc.setZReadWrite( true, false ); GFX->setStateBlockByDesc( desc ); U32 pointCount = 0; for ( S32 i = 0; i < faceList.size(); i++ ) pointCount += faceList[i].winding.size(); PrimBuild::begin( GFXLineList, pointCount * 2 ); for ( S32 i = 0; i < faceList.size(); i++ ) { for ( S32 j = 0; j < faceList[i].winding.size(); j++ ) { Point3F p0 = pointList[ faceList[i].points[ faceList[i].winding[j] ] ]; Point3F p1 = p0 + mSurfaces[ faceList[i].id ].getUpVector() * 0.75f * ( Point3F::One / mObjScale ); objToWorld.mulP( p0 ); objToWorld.mulP( p1 ); ColorI color = faceColorsx[ j % 4 ]; S32 div = ( j / 4 ) * 4; if ( div > 0 ) color /= div; color.alpha = 255; PrimBuild::color( color ); PrimBuild::vertex3fv( p0 ); PrimBuild::color( color ); PrimBuild::vertex3fv( p1 ); } } PrimBuild::end(); } // Render Points. if ( false ) { /* GFXTransformSaver saver; MatrixF xfm( getRenderTransform() ); xfm.scale( getScale() ); GFX->multWorld( xfm ); GFXStateBlockDesc desc; Point3F size( 0.05f ); */ } // Render surface transforms. if ( false ) { GFXStateBlockDesc desc; desc.setBlend( false ); desc.setZReadWrite( true, true ); Point3F scale(mNormalLength); for ( S32 i = 0; i < mSurfaces.size(); i++ ) { MatrixF objToWorld( mObjToWorld ); objToWorld.scale( mObjScale ); MatrixF renderMat; renderMat.mul( objToWorld, mSurfaces[i] ); renderMat.setPosition( renderMat.getPosition() + renderMat.getUpVector() * 0.001f ); drawer->drawTransform( desc, renderMat, &scale, NULL ); } } }
void PhysShape::setPosition(const Point3F& pos) { MatrixF tr = getTransform(); tr.setPosition(pos); setTransform(tr); }
void Projectile::emitParticles(const Point3F& from, const Point3F& to, const Point3F& vel, const U32 ms) { if ( mHasExploded ) return; Point3F axis = -vel; if( axis.isZero() ) axis.set( 0.0, 0.0, 1.0 ); else axis.normalize(); bool fromWater = pointInWater(from); bool toWater = pointInWater(to); if (!fromWater && !toWater && bool(mParticleEmitter)) // not in water mParticleEmitter->emitParticles(from, to, axis, vel, ms); else if (fromWater && toWater && bool(mParticleWaterEmitter)) // in water mParticleWaterEmitter->emitParticles(from, to, axis, vel, ms); else if (!fromWater && toWater && mDataBlock->splash) // entering water { // cast the ray to get the surface point of the water RayInfo rInfo; if (gClientContainer.castRay(from, to, WaterObjectType, &rInfo)) { MatrixF trans = getTransform(); trans.setPosition(rInfo.point); Splash *splash = new Splash(); splash->onNewDataBlock(mDataBlock->splash, false); splash->setTransform(trans); splash->setInitialState(trans.getPosition(), Point3F(0.0, 0.0, 1.0)); if (!splash->registerObject()) { delete splash; splash = NULL; } // create an emitter for the particles out of water and the particles in water if (mParticleEmitter) mParticleEmitter->emitParticles(from, rInfo.point, axis, vel, ms); if (mParticleWaterEmitter) mParticleWaterEmitter->emitParticles(rInfo.point, to, axis, vel, ms); } } else if (fromWater && !toWater && mDataBlock->splash) // leaving water { // cast the ray in the opposite direction since that point is out of the water, otherwise // we hit water immediately and wont get the appropriate surface point RayInfo rInfo; if (gClientContainer.castRay(to, from, WaterObjectType, &rInfo)) { MatrixF trans = getTransform(); trans.setPosition(rInfo.point); Splash *splash = new Splash(); splash->onNewDataBlock(mDataBlock->splash,false); splash->setTransform(trans); splash->setInitialState(trans.getPosition(), Point3F(0.0, 0.0, 1.0)); if (!splash->registerObject()) { delete splash; splash = NULL; } // create an emitter for the particles out of water and the particles in water if (mParticleEmitter) mParticleEmitter->emitParticles(rInfo.point, to, axis, vel, ms); if (mParticleWaterEmitter) mParticleWaterEmitter->emitParticles(from, rInfo.point, axis, vel, ms); } } }
//----------------------------------------------------------------------------- // // VActorPhysicsController::postTickUpdate( pDelta ); // // ... // //----------------------------------------------------------------------------- void VActorPhysicsController::postTickUpdate( const F32 &pDelta ) { switch( mControlState ) { case k_PathControlState : { AssertFatal( isPathing(), "VActorPhysicsController::postTickUpdate() - Invalid Path State." ); // Fetch Mount Transform. MatrixF transform; mMountedPath->getMountTransform( mObject->getMountNode(), getTransform(), &transform ); // Fetch Mount Position. const Point3F &mountPosition = transform.getPosition(); // Update X & Y Position. Point3F position = getPosition(); position.x = mountPosition.x; position.y = mountPosition.y; // In Water? bool underWater = false; if ( isInWater() ) { // Fetch Body of Water. WaterObject *waterBody = getWaterObject(); // Fetch Surface Position. const F32 &waterSurfacePosition = waterBody->getSurfaceHeight( Point2F( position.x, position.y ) ); // Fetch Submersion Position. const F32 sumbersionPosition = waterSurfacePosition - ( mObject->getWorldBox().len_z() * mObject->getDataBlock()->getSumbergeCoverage() ); // Choose a Z Value. // Note: This is done so that the Actor will either path under the // water, or it will swim along the water's surface. position.z = getMin( mountPosition.z, sumbersionPosition ); // Under Water? underWater = ( position.z < sumbersionPosition ); } // Under Water? if ( !underWater ) { // Fetch Y Column. VectorF forwardVector; transform.getColumn( 1, &forwardVector ); // Determine Angle. const F32 &angle = -mAtan2( -forwardVector.x, forwardVector.y ); // Reset Transform. transform.set( EulerF( 0.f, 0.f, angle ) ); // In the air? if ( !isOnGround() ) { // Apply z-axis force. position.z += ( getVelocity().z * pDelta ); } } // Update Transform. transform.setPosition( position ); // Apply Update. setTransform( transform ); } break; default : { // Fetch Transform. MatrixF transform = getTransform(); // Determine the Post-Tick Position. Point3F postTickPosition = getPosition() + ( getVelocity() * pDelta ); // Set the Post Tick Position. transform.setPosition( postTickPosition ); // Apply the Transform. setTransform( transform ); } break; } // Push Delta. mInterpController.pushDelta( getTransform() ); }