renderShapeExample.cpp
Engine/source/T3D/examples/renderShapeExample.cpp
Public Functions
ConsoleDocClass(RenderShapeExample , "@brief An example scene object which renders <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">DTS.\n\n</a>" "This class implements <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> basic <a href="/coding/class/classsceneobject/">SceneObject</a> that can exist in the world at <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> " "3D position and <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> itself. There are several valid ways <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> an " "object in Torque. This class makes use of the 'TS' (three space) shape " "system. TS manages loading the various mesh formats supported by Torque as " "well was rendering those meshes (including LOD and animation...though this " "example doesn'<a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1aded116371789db1fd63c90ef00c95a3d">t</a> include any animation over time).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "See the C++ code <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> implementation <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">details.\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Examples\n</a>" )
Detailed Description
Public Functions
ConsoleDocClass(RenderShapeExample , "@brief An example scene object which renders <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">DTS.\n\n</a>" "This class implements <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> basic <a href="/coding/class/classsceneobject/">SceneObject</a> that can exist in the world at <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> " "3D position and <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> itself. There are several valid ways <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/editortool_8cpp/#editortool_8cpp_1a4cb041169a32ea3d4cacadbb955e06b4">render</a> an " "object in Torque. This class makes use of the 'TS' (three space) shape " "system. TS manages loading the various mesh formats supported by Torque as " "well was rendering those meshes (including LOD and animation...though this " "example doesn'<a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1aded116371789db1fd63c90ef00c95a3d">t</a> include any animation over time).\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "See the C++ code <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> implementation <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">details.\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Examples\n</a>" )
IMPLEMENT_CO_NETOBJECT_V1(RenderShapeExample )
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "T3D/examples/renderShapeExample.h" 25 26#include "math/mathIO.h" 27#include "sim/netConnection.h" 28#include "scene/sceneRenderState.h" 29#include "console/consoleTypes.h" 30#include "core/resourceManager.h" 31#include "core/stream/bitStream.h" 32#include "gfx/gfxTransformSaver.h" 33#include "renderInstance/renderPassManager.h" 34#include "lighting/lightQuery.h" 35 36 37IMPLEMENT_CO_NETOBJECT_V1(RenderShapeExample); 38 39ConsoleDocClass( RenderShapeExample, 40 "@brief An example scene object which renders a DTS.\n\n" 41 "This class implements a basic SceneObject that can exist in the world at a " 42 "3D position and render itself. There are several valid ways to render an " 43 "object in Torque. This class makes use of the 'TS' (three space) shape " 44 "system. TS manages loading the various mesh formats supported by Torque as " 45 "well was rendering those meshes (including LOD and animation...though this " 46 "example doesn't include any animation over time).\n\n" 47 "See the C++ code for implementation details.\n\n" 48 "@ingroup Examples\n" ); 49 50//----------------------------------------------------------------------------- 51// Object setup and teardown 52//----------------------------------------------------------------------------- 53RenderShapeExample::RenderShapeExample() 54{ 55 // Flag this object so that it will always 56 // be sent across the network to clients 57 mNetFlags.set( Ghostable | ScopeAlways ); 58 59 // Set it as a "static" object. 60 mTypeMask |= StaticObjectType | StaticShapeObjectType; 61 62 // Make sure to initialize our TSShapeInstance to NULL 63 mShapeInstance = NULL; 64} 65 66RenderShapeExample::~RenderShapeExample() 67{ 68} 69 70//----------------------------------------------------------------------------- 71// Object Editing 72//----------------------------------------------------------------------------- 73void RenderShapeExample::initPersistFields() 74{ 75 addGroup( "Rendering" ); 76 addField( "shapeFile", TypeStringFilename, Offset( mShapeFile, RenderShapeExample ), 77 "The path to the DTS shape file." ); 78 endGroup( "Rendering" ); 79 80 // SceneObject already handles exposing the transform 81 Parent::initPersistFields(); 82} 83 84void RenderShapeExample::inspectPostApply() 85{ 86 Parent::inspectPostApply(); 87 88 // Flag the network mask to send the updates 89 // to the client object 90 setMaskBits( UpdateMask ); 91} 92 93bool RenderShapeExample::onAdd() 94{ 95 if ( !Parent::onAdd() ) 96 return false; 97 98 // Set up a 1x1x1 bounding box 99 mObjBox.set( Point3F( -0.5f, -0.5f, -0.5f ), 100 Point3F( 0.5f, 0.5f, 0.5f ) ); 101 102 resetWorldBox(); 103 104 // Add this object to the scene 105 addToScene(); 106 107 // Setup the shape. 108 createShape(); 109 110 return true; 111} 112 113void RenderShapeExample::onRemove() 114{ 115 // Remove this object from the scene 116 removeFromScene(); 117 118 // Remove our TSShapeInstance 119 if ( mShapeInstance ) 120 SAFE_DELETE( mShapeInstance ); 121 122 Parent::onRemove(); 123} 124 125void RenderShapeExample::setTransform(const MatrixF & mat) 126{ 127 // Let SceneObject handle all of the matrix manipulation 128 Parent::setTransform( mat ); 129 130 // Dirty our network mask so that the new transform gets 131 // transmitted to the client object 132 setMaskBits( TransformMask ); 133} 134 135U32 RenderShapeExample::packUpdate( NetConnection *conn, U32 mask, BitStream *stream ) 136{ 137 // Allow the Parent to get a crack at writing its info 138 U32 retMask = Parent::packUpdate( conn, mask, stream ); 139 140 // Write our transform information 141 if ( stream->writeFlag( mask & TransformMask ) ) 142 { 143 mathWrite(*stream, getTransform()); 144 mathWrite(*stream, getScale()); 145 } 146 147 // Write out any of the updated editable properties 148 if ( stream->writeFlag( mask & UpdateMask ) ) 149 { 150 stream->write( mShapeFile ); 151 152 // Allow the server object a chance to handle a new shape 153 createShape(); 154 } 155 156 return retMask; 157} 158 159void RenderShapeExample::unpackUpdate(NetConnection *conn, BitStream *stream) 160{ 161 // Let the Parent read any info it sent 162 Parent::unpackUpdate(conn, stream); 163 164 if ( stream->readFlag() ) // TransformMask 165 { 166 mathRead(*stream, &mObjToWorld); 167 mathRead(*stream, &mObjScale); 168 169 setTransform( mObjToWorld ); 170 } 171 172 if ( stream->readFlag() ) // UpdateMask 173 { 174 stream->read( &mShapeFile ); 175 176 if ( isProperlyAdded() ) 177 createShape(); 178 } 179} 180 181//----------------------------------------------------------------------------- 182// Object Rendering 183//----------------------------------------------------------------------------- 184void RenderShapeExample::createShape() 185{ 186 if ( mShapeFile.isEmpty() ) 187 return; 188 189 // If this is the same shape then no reason to update it 190 if ( mShapeInstance && mShapeFile.equal( mShape.getPath().getFullPath(), String::NoCase ) ) 191 return; 192 193 // Clean up our previous shape 194 if ( mShapeInstance ) 195 SAFE_DELETE( mShapeInstance ); 196 mShape = NULL; 197 198 // Attempt to get the resource from the ResourceManager 199 mShape = ResourceManager::get().load( mShapeFile ); 200 201 if ( !mShape ) 202 { 203 Con::errorf( "RenderShapeExample::createShape() - Unable to load shape: %s", mShapeFile.c_str() ); 204 return; 205 } 206 207 // Attempt to preload the Materials for this shape 208 if ( isClientObject() && 209 !mShape->preloadMaterialList( mShape.getPath() ) && 210 NetConnection::filesWereDownloaded() ) 211 { 212 mShape = NULL; 213 return; 214 } 215 216 // Update the bounding box 217 mObjBox = mShape->mBounds; 218 resetWorldBox(); 219 setRenderTransform(mObjToWorld); 220 221 // Create the TSShapeInstance 222 mShapeInstance = new TSShapeInstance( mShape, isClientObject() ); 223} 224 225void RenderShapeExample::prepRenderImage( SceneRenderState *state ) 226{ 227 // Make sure we have a TSShapeInstance 228 if ( !mShapeInstance ) 229 return; 230 231 // Calculate the distance of this object from the camera 232 Point3F cameraOffset; 233 getRenderTransform().getColumn( 3, &cameraOffset ); 234 cameraOffset -= state->getDiffuseCameraPosition(); 235 F32 dist = cameraOffset.len(); 236 if ( dist < 0.01f ) 237 dist = 0.01f; 238 239 // Set up the LOD for the shape 240 F32 invScale = ( 1.0f / getMax( getMax( mObjScale.x, mObjScale.y ), mObjScale.z ) ); 241 242 mShapeInstance->setDetailFromDistance( state, dist * invScale ); 243 244 // Make sure we have a valid level of detail 245 if ( mShapeInstance->getCurrentDetail() < 0 ) 246 return; 247 248 // GFXTransformSaver is a handy helper class that restores 249 // the current GFX matrices to their original values when 250 // it goes out of scope at the end of the function 251 GFXTransformSaver saver; 252 253 // Set up our TS render state 254 TSRenderState rdata; 255 rdata.setSceneState( state ); 256 rdata.setFadeOverride( 1.0f ); 257 258 // We might have some forward lit materials 259 // so pass down a query to gather lights. 260 LightQuery query; 261 query.init( getWorldSphere() ); 262 rdata.setLightQuery( &query ); 263 264 // Set the world matrix to the objects render transform 265 MatrixF mat = getRenderTransform(); 266 mat.scale( mObjScale ); 267 GFX->setWorldMatrix( mat ); 268 269 // Animate the the shape 270 mShapeInstance->animate(); 271 272 // Allow the shape to submit the RenderInst(s) for itself 273 mShapeInstance->render( rdata ); 274} 275