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 ); }
bool Convex::getCollisionInfo(const MatrixF& mat, const Point3F& scale, CollisionList* cList,F32 tol) { PROFILE_SCOPE( Convex_GetCollisionInfo ); // Making these static prevents needless Vector resizing that occurs // in the ConvexFeature constructor. static ConvexFeature fa; static ConvexFeature fb; for ( CollisionStateList* itr = mList.mNext; itr != &mList; itr = itr->mNext) { CollisionState* state = itr->mState; if (state->mLista != itr) state->swap(); if (state->dist <= tol) { fa.reset(); fb.reset(); VectorF v; // The idea is that we need to scale the matrix, so we need to // make a copy of it, before we can pass it in to getFeatures. // This is used to scale us for comparison against the other // convex, which is correctly scaled. MatrixF omat = mat; omat.scale(scale); MatrixF imat = omat; imat.inverse(); imat.mulV(-state->v,&v); getFeatures(omat,v,&fa); imat = state->b->getTransform(); imat.scale(state->b->getScale()); MatrixF bxform = imat; imat.inverse(); imat.mulV(state->v,&v); state->b->getFeatures(bxform,v,&fb); fa.collide(fb,cList,tol); } } return (cList->getCount() != 0); }
/// 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 SceneSpace::_renderObject( ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat ) { if( overrideMat ) return; if( !mEditorRenderMaterial ) { // We have no material for rendering so just render // a plain box. GFXTransformSaver saver; MatrixF mat = getRenderTransform(); mat.scale( getScale() ); GFX->multWorld( mat ); GFXStateBlockDesc desc; desc.setZReadWrite( true, false ); desc.setBlend( true ); desc.setCullMode( GFXCullNone ); GFXDrawUtil *drawer = GFX->getDrawUtil(); drawer->drawCube( desc, mObjBox, _getDefaultEditorSolidColor() ); // Render black wireframe. desc.setFillModeWireframe(); drawer->drawCube( desc, mObjBox, _getDefaultEditorWireframeColor() ); } else { //RDTODO } }
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 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 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); }
CollisionState* Convex::findClosestState(const MatrixF& mat, const Point3F& scale, const F32 dontCareDist) { PROFILE_SCOPE( Convex_FindClosestState ); updateStateList(mat, scale); F32 dist = +1E30f; CollisionState *st = 0; // Prepare scaled version of transform MatrixF axform = mat; axform.scale(scale); MatrixF axforminv(true); MatrixF temp(mat); axforminv.scale(Point3F(1.0f/scale.x, 1.0f/scale.y, 1.0f/scale.z)); temp.affineInverse(); axforminv.mul(temp); for (CollisionStateList* itr = mList.mNext; itr != &mList; itr = itr->mNext) { CollisionState* state = itr->mState; if (state->mLista != itr) state->swap(); // Prepare scaled version of transform MatrixF bxform = state->b->getTransform(); temp = bxform; Point3F bscale = state->b->getScale(); bxform.scale(bscale); MatrixF bxforminv(true); bxforminv.scale(Point3F(1.0f/bscale.x, 1.0f/bscale.y, 1.0f/bscale.z)); temp.affineInverse(); bxforminv.mul(temp); // F32 dd = state->distance(axform, bxform, dontCareDist, &axforminv, &bxforminv); if (dd < dist) { dist = dd; st = state; } } if (dist < dontCareDist) return st; else return NULL; }
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 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 ); }
void Projectile::prepBatchRender( SceneState *state ) { GFXTransformSaver saver; // Set up our TS render state. TSRenderState rdata; rdata.setSceneState( state ); MatrixF mat = getRenderTransform(); mat.scale( mObjScale ); mat.scale( mDataBlock->scale ); GFX->setWorldMatrix( mat ); if(mProjectileShape) { AssertFatal(mProjectileShape != NULL, "Projectile::renderObject: Error, projectile shape should always be present in renderObject"); mProjectileShape->setDetailFromPosAndScale( state, mat.getPosition(), mObjScale ); mProjectileShape->animate(); mProjectileShape->render( rdata ); } }
void MetaShapeRenderer::render( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ) { if ( overrideMat ) return; PROFILE_SCOPE(MetaShapeRenderer_Render); mPolyList.render(); if ( mVertexBuffer.isNull() ) return; // Set up a GFX debug event (this helps with debugging rendering events in external tools) GFXDEBUGEVENT_SCOPE( MetaShapeRenderer_Render, ColorI::RED ); // GFXTransformSaver is a handy helper class that restores // the current GFX matrices to their original values when // it goes out of scope at the end of the function GFXTransformSaver saver; // Calculate our object to world transform matrix MatrixF objectToWorld = getRenderTransform(); objectToWorld.scale( getScale() ); // Apply our object transform GFX->multWorld( objectToWorld ); // Deal with reflect pass otherwise // set the normal StateBlock if ( state->isReflectPass() ) GFX->setStateBlock( mReflectSB ); else GFX->setStateBlock( mNormalSB ); // Set up the "generic" shaders // These handle rendering on GFX layers that don't support // fixed function. Otherwise they disable shaders. GFX->setupGenericShaders( GFXDevice::GSModColorTexture ); // Set the vertex buffer GFX->setVertexBuffer( mVertexBuffer ); // Draw our triangles GFX->drawPrimitive( GFXTriangleList, 0, 12 ); }
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); }
//---------------------------------------------------------------------------- AwTextureTarget *AwShape::processAwesomiumHit (const Point3F &start, const Point3F &end) { if (!mTextureTarget) { return NULL; } Point3F localStart, localEnd; MatrixF mat = getTransform(); mat.scale (Point3F (getScale ())); mat.inverse (); mat.mulP (start, &localStart); mat.mulP (end, &localEnd); RayInfo info; info.generateTexCoord = true; if (!mShapeInstance || !mShapeInstance->castRayOpcode (0, localStart, localEnd, &info)) { return NULL; } if (info.texCoord.x != -1 && info.texCoord.y != -1 && info.material == mMatInstance) { Point2I pnt (info.texCoord.x * mTextureTarget->getResolution ().x, info.texCoord.y * mTextureTarget->getResolution ().y); AwManager::sCursor->setPosition (pnt); if (mIsMouseDown) { mTextureTarget->injectMouseDown (); } else { mTextureTarget->injectMouseUp (); } return mTextureTarget; } return NULL; }
void PxSingleActor::renderObject(SceneState* state) { GFXTransformSaver saver; // Set up our TS render state here. TSRenderState rdata; rdata.setSceneState( state ); //rdata.setObjScale( &getScale() ); LightManager *lm = gClientSceneGraph->getLightManager(); if ( !state->isShadowPass() ) lm->setupLights( this, getWorldSphere() ); MatrixF mat = getTransform(); mat.scale( getScale() ); GFX->setWorldMatrix( mat ); mShapeInstance->animate(); mShapeInstance->render( rdata ); lm->resetLights(); }
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 TSStatic::prepRenderImage( SceneRenderState* state ) { if( !mShapeInstance ) return; Point3F cameraOffset; getRenderTransform().getColumn(3,&cameraOffset); cameraOffset -= state->getDiffuseCameraPosition(); F32 dist = cameraOffset.len(); if (dist < 0.01f) dist = 0.01f; F32 invScale = (1.0f/getMax(getMax(mObjScale.x,mObjScale.y),mObjScale.z)); if ( mForceDetail == -1 ) mShapeInstance->setDetailFromDistance( state, dist * invScale ); else mShapeInstance->setCurrentDetail( mForceDetail ); if ( mShapeInstance->getCurrentDetail() < 0 ) return; GFXTransformSaver saver; // Set up our TS render state. TSRenderState rdata; rdata.setSceneState( state ); rdata.setFadeOverride( 1.0f ); rdata.setOriginSort( mUseOriginSort ); // If we have submesh culling enabled then prepare // the object space frustum to pass to the shape. Frustum culler; if ( mMeshCulling ) { culler = state->getCullingFrustum(); MatrixF xfm( true ); xfm.scale( Point3F::One / getScale() ); xfm.mul( getRenderWorldTransform() ); xfm.mul( culler.getTransform() ); culler.setTransform( xfm ); rdata.setCuller( &culler ); } // 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 ); GFX->setWorldMatrix( mat ); mShapeInstance->animate(); mShapeInstance->render( rdata ); if ( mRenderNormalScalar > 0 ) { ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>(); ri->renderDelegate.bind( this, &TSStatic::_renderNormals ); ri->type = RenderPassManager::RIT_Editor; state->getRenderPass()->addInst( ri ); } }
void RenderMeshExample::prepRenderImage( SceneRenderState *state ) { // Do a little prep work if needed if ( mVertexBuffer.isNull() ) createGeometry(); // If we have no material then skip out. if ( !mMaterialInst ) return; // If we don't have a material instance after the override then // we can skip rendering all together. BaseMatInstance *matInst = state->getOverrideMaterial( mMaterialInst ); if ( !matInst ) return; // Get a handy pointer to our RenderPassmanager RenderPassManager *renderPass = state->getRenderPass(); // Allocate an MeshRenderInst so that we can submit it to the RenderPassManager MeshRenderInst *ri = renderPass->allocInst<MeshRenderInst>(); // Set our RenderInst as a standard mesh render ri->type = RenderPassManager::RIT_Mesh; // Calculate our sorting point if ( state ) { // Calculate our sort point manually. const Box3F& rBox = getRenderWorldBox(); ri->sortDistSq = rBox.getSqDistanceToPoint( state->getCameraPosition() ); } else ri->sortDistSq = 0.0f; // Set up our transforms MatrixF objectToWorld = getRenderTransform(); objectToWorld.scale( getScale() ); ri->objectToWorld = renderPass->allocUniqueXform( objectToWorld ); ri->worldToCamera = renderPass->allocSharedXform(RenderPassManager::View); ri->projection = renderPass->allocSharedXform(RenderPassManager::Projection); // If our material needs lights then fill the RIs // light vector with the best lights. if ( matInst->isForwardLit() ) { LightQuery query; query.init( getWorldSphere() ); query.getLights( ri->lights, 8 ); } // Make sure we have an up-to-date backbuffer in case // our Material would like to make use of it // NOTICE: SFXBB is removed and refraction is disabled! //ri->backBuffTex = GFX->getSfxBackBuffer(); // Set our Material ri->matInst = matInst; // Set up our vertex buffer and primitive buffer ri->vertBuff = &mVertexBuffer; ri->primBuff = &mPrimitiveBuffer; ri->prim = renderPass->allocPrim(); ri->prim->type = GFXTriangleList; ri->prim->minIndex = 0; ri->prim->startIndex = 0; ri->prim->numPrimitives = 12; ri->prim->startVertex = 0; ri->prim->numVertices = 36; // We sort by the material then vertex buffer ri->defaultKey = matInst->getStateHint(); ri->defaultKey2 = (U32)ri->vertBuff; // Not 64bit safe! // Submit our RenderInst to the RenderPassManager state->getRenderPass()->addInst( ri ); }
void TSStatic::prepRenderImage( SceneRenderState* state ) { if( !mShapeInstance ) return; //WLE - Vince //Lod preloading GameConnection* connection = GameConnection::getConnectionToServer(); if (connection && !connection->didFirstRender) { TSRenderState rdata; rdata.setSceneState( state ); rdata.setFadeOverride( 1.0f ); rdata.setOriginSort( mUseOriginSort ); for (S32 i = mShapeInstance->getSmallestVisibleDL(); i >= 0; i-- ) { mShapeInstance->setCurrentDetail( i ); mShapeInstance->render( rdata ); } } Point3F cameraOffset; getRenderTransform().getColumn(3,&cameraOffset); cameraOffset -= state->getDiffuseCameraPosition(); F32 dist = cameraOffset.len(); if (dist < 0.01f) dist = 0.01f; if (mUseAlphaLod) { mAlphaLOD = 1.0f; if ((mAlphaLODStart < mAlphaLODEnd) && mAlphaLODStart > 0.1f) { if (mInvertAlphaLod) { if (dist <= mAlphaLODStart) { return; } if (dist < mAlphaLODEnd) { mAlphaLOD = ((dist - mAlphaLODStart) / (mAlphaLODEnd - mAlphaLODStart)); } } else { if (dist >= mAlphaLODEnd) { return; } if (dist > mAlphaLODStart) { mAlphaLOD -= ((dist - mAlphaLODStart) / (mAlphaLODEnd - mAlphaLODStart)); } } } } F32 invScale = (1.0f/getMax(getMax(mObjScale.x,mObjScale.y),mObjScale.z)); if ( mForceDetail == -1 ) mShapeInstance->setDetailFromDistance( state, dist * invScale ); else mShapeInstance->setCurrentDetail( mForceDetail ); if ( mShapeInstance->getCurrentDetail() < 0 ) return; GFXTransformSaver saver; // Set up our TS render state. TSRenderState rdata; rdata.setSceneState( state ); rdata.setFadeOverride( 1.0f ); rdata.setOriginSort( mUseOriginSort ); // If we have submesh culling enabled then prepare // the object space frustum to pass to the shape. Frustum culler; if ( mMeshCulling ) { culler = state->getCullingFrustum(); MatrixF xfm( true ); xfm.scale( Point3F::One / getScale() ); xfm.mul( getRenderWorldTransform() ); xfm.mul( culler.getTransform() ); culler.setTransform( xfm ); rdata.setCuller( &culler ); } // 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 ); GFX->setWorldMatrix( mat ); mShapeInstance->animate(); if(mShapeInstance) { if (mUseAlphaLod) { mShapeInstance->setAlphaAlways(mAlphaLOD); S32 s = mShapeInstance->mMeshObjects.size(); for(S32 x = 0; x < s; x++) { mShapeInstance->mMeshObjects[x].visible = mAlphaLOD; } } } mShapeInstance->render( rdata ); if ( mRenderNormalScalar > 0 ) { ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>(); ri->renderDelegate.bind( this, &TSStatic::_renderNormals ); ri->type = RenderPassManager::RIT_Editor; state->getRenderPass()->addInst( ri ); } }
bool ForestItem::castRay( const Point3F &start, const Point3F &end, RayInfo *outInfo, bool rendered ) const { if ( !mWorldBox.collideLine( start, end ) ) return false; Point3F s, e; MatrixF mat = getTransform(); mat.scale( Point3F(mScale) ); mat.inverse(); mat.mulP( start, &s ); mat.mulP( end, &e ); TSForestItemData *data = (TSForestItemData*)mDataBlock; TSShapeInstance *si = data->getShapeInstance(); if ( !si ) return false; if ( rendered ) { // Always raycast against detail level zero // because it makes lots of things easier. if ( !si->castRayRendered( s, e, outInfo, 0 ) ) return false; if ( outInfo->userData != NULL ) *(ForestItem*)(outInfo->userData) = *this; return true; } RayInfo shortest; shortest.t = 1e8; bool gotMatch = false; S32 detail; const Vector<S32> &details = data->getLOSDetails(); for (U32 i = 0; i < details.size(); i++) { detail = details[i]; if (detail != -1) { //si->animate(data->mLOSDetails[i]); if ( si->castRayOpcode( detail, s, e, outInfo ) ) { if (outInfo->t < shortest.t) { gotMatch = true; shortest = *outInfo; } } } } if ( !gotMatch ) return false; // Copy out the shortest time... *outInfo = shortest; if ( outInfo->userData != NULL ) *(ForestItem*)(outInfo->userData) = *this; return true; }
void ConvexShape::prepRenderImage( SceneRenderState *state ) { /* if ( state->isDiffusePass() ) { ObjectRenderInst *ri2 = state->getRenderPass()->allocInst<ObjectRenderInst>(); ri2->renderDelegate.bind( this, &ConvexShape::_renderDebug ); ri2->type = RenderPassManager::RIT_Editor; state->getRenderPass()->addInst( ri2 ); } */ if ( mVertexBuffer.isNull() ) return; // If we don't have a material instance after the override then // we can skip rendering all together. BaseMatInstance *matInst = state->getOverrideMaterial( mMaterialInst ? mMaterialInst : MATMGR->getWarningMatInstance() ); if ( !matInst ) return; // Get a handy pointer to our RenderPassmanager RenderPassManager *renderPass = state->getRenderPass(); // Allocate an MeshRenderInst so that we can submit it to the RenderPassManager MeshRenderInst *ri = renderPass->allocInst<MeshRenderInst>(); // Set our RenderInst as a standard mesh render ri->type = RenderPassManager::RIT_Mesh; // Calculate our sorting point if ( state ) { // Calculate our sort point manually. const Box3F& rBox = getRenderWorldBox(); ri->sortDistSq = rBox.getSqDistanceToPoint( state->getCameraPosition() ); } else ri->sortDistSq = 0.0f; // Set up our transforms MatrixF objectToWorld = getRenderTransform(); objectToWorld.scale( getScale() ); ri->objectToWorld = renderPass->allocUniqueXform( objectToWorld ); ri->worldToCamera = renderPass->allocSharedXform(RenderPassManager::View); ri->projection = renderPass->allocSharedXform(RenderPassManager::Projection); // If we need lights then set them up. if ( matInst->isForwardLit() ) { LightQuery query; query.init( getWorldSphere() ); query.getLights( ri->lights, 8 ); } // Make sure we have an up-to-date backbuffer in case // our Material would like to make use of it // NOTICE: SFXBB is removed and refraction is disabled! //ri->backBuffTex = GFX->getSfxBackBuffer(); // Set our Material ri->matInst = matInst; if ( matInst->getMaterial()->isTranslucent() ) { ri->translucentSort = true; ri->type = RenderPassManager::RIT_Translucent; } // Set up our vertex buffer and primitive buffer ri->vertBuff = &mVertexBuffer; ri->primBuff = &mPrimitiveBuffer; ri->prim = renderPass->allocPrim(); ri->prim->type = GFXTriangleList; ri->prim->minIndex = 0; ri->prim->startIndex = 0; ri->prim->numPrimitives = mPrimCount; ri->prim->startVertex = 0; ri->prim->numVertices = mVertCount; // We sort by the material then vertex buffer. ri->defaultKey = matInst->getStateHint(); ri->defaultKey2 = (U32)ri->vertBuff; // Not 64bit safe! // Submit our RenderInst to the RenderPassManager state->getRenderPass()->addInst( ri ); }
void TSStatic::prepRenderImage( SceneRenderState* state ) { if( !mShapeInstance ) return; Point3F cameraOffset; getRenderTransform().getColumn(3,&cameraOffset); cameraOffset -= state->getDiffuseCameraPosition(); F32 dist = cameraOffset.len(); if (dist < 0.01f) dist = 0.01f; if (mUseAlphaFade) { mAlphaFade = 1.0f; if ((mAlphaFadeStart < mAlphaFadeEnd) && mAlphaFadeStart > 0.1f) { if (mInvertAlphaFade) { if (dist <= mAlphaFadeStart) { return; } if (dist < mAlphaFadeEnd) { mAlphaFade = ((dist - mAlphaFadeStart) / (mAlphaFadeEnd - mAlphaFadeStart)); } } else { if (dist >= mAlphaFadeEnd) { return; } if (dist > mAlphaFadeStart) { mAlphaFade -= ((dist - mAlphaFadeStart) / (mAlphaFadeEnd - mAlphaFadeStart)); } } } } F32 invScale = (1.0f/getMax(getMax(mObjScale.x,mObjScale.y),mObjScale.z)); // If we're currently rendering our own reflection we // don't want to render ourselves into it. if ( mCubeReflector.isRendering() ) return; if ( mForceDetail == -1 ) mShapeInstance->setDetailFromDistance( state, dist * invScale ); else mShapeInstance->setCurrentDetail( mForceDetail ); if ( mShapeInstance->getCurrentDetail() < 0 ) return; GFXTransformSaver saver; // Set up our TS render state. TSRenderState rdata; rdata.setSceneState( state ); rdata.setFadeOverride( 1.0f ); rdata.setOriginSort( mUseOriginSort ); if ( mCubeReflector.isEnabled() ) rdata.setCubemap( mCubeReflector.getCubemap() ); // Acculumation rdata.setAccuTex(mAccuTex); // If we have submesh culling enabled then prepare // the object space frustum to pass to the shape. Frustum culler; if ( mMeshCulling ) { culler = state->getCullingFrustum(); MatrixF xfm( true ); xfm.scale( Point3F::One / getScale() ); xfm.mul( getRenderWorldTransform() ); xfm.mul( culler.getTransform() ); culler.setTransform( xfm ); rdata.setCuller( &culler ); } // 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 ); GFX->setWorldMatrix( mat ); if ( state->isDiffusePass() && mCubeReflector.isEnabled() && mCubeReflector.getOcclusionQuery() ) { RenderPassManager *pass = state->getRenderPass(); OccluderRenderInst *ri = pass->allocInst<OccluderRenderInst>(); ri->type = RenderPassManager::RIT_Occluder; ri->query = mCubeReflector.getOcclusionQuery(); mObjToWorld.mulP( mObjBox.getCenter(), &ri->position ); ri->scale.set( mObjBox.getExtents() ); ri->orientation = pass->allocUniqueXform( mObjToWorld ); ri->isSphere = false; state->getRenderPass()->addInst( ri ); } mShapeInstance->animate(); if(mShapeInstance) { if (mUseAlphaFade) { mShapeInstance->setAlphaAlways(mAlphaFade); S32 s = mShapeInstance->mMeshObjects.size(); for(S32 x = 0; x < s; x++) { mShapeInstance->mMeshObjects[x].visible = mAlphaFade; } } } mShapeInstance->render( rdata ); if ( mRenderNormalScalar > 0 ) { ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>(); ri->renderDelegate.bind( this, &TSStatic::_renderNormals ); ri->type = RenderPassManager::RIT_Editor; state->getRenderPass()->addInst( ri ); } }