sceneObject.h
Engine/source/scene/sceneObject.h
Classes:
class
A 3D object.
class
TGE uses the term "mount" in a quirky, staticky way relating to its limited use to have riders and guns mounted on a vehicle (and similar) I did not alter that code at all (yet) and did not want to keep its terminology for other reasons I decided to support a hierarchy of scene objects and dubbed the operations attaching and removing child SceneObjects.
class
Mounted object.
class
Iterator over the zones that the object is assigned to.
class
Bidirectional link between a zone manager and its objects.
Detailed Description
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//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 25// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames 26// Copyright (C) 2015 Faust Logic, Inc. 27//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 28 29#ifndef _SCENEOBJECT_H_ 30#define _SCENEOBJECT_H_ 31 32#ifndef _NETOBJECT_H_ 33#include "sim/netObject.h" 34#endif 35 36#ifndef _COLLISION_H_ 37#include "collision/collision.h" 38#endif 39 40#ifndef _OBJECTTYPES_H_ 41#include "T3D/objectTypes.h" 42#endif 43 44#ifndef _COLOR_H_ 45#include "core/color.h" 46#endif 47 48#ifndef _BITSET_H_ 49#include "core/bitSet.h" 50#endif 51 52#ifndef _PROCESSLIST_H_ 53#include "T3D/gameBase/processList.h" 54#endif 55 56#ifndef _SCENECONTAINER_H_ 57#include "scene/sceneContainer.h" 58#endif 59 60#ifndef _GFXDEVICE_H_ 61#include "gfx/gfxDevice.h" 62#endif 63#ifndef _TSRENDERDATA_H_ 64#include "ts/tsRenderState.h" 65#endif 66 67#ifndef _COLLADA_UTILS_H_ 68#include "ts/collada/colladaUtils.h" 69#endif 70 71#ifndef _ASSET_PTR_H_ 72#include "assets/assetPtr.h" 73#endif 74#ifndef GAME_OBJECT_ASSET_H 75#include "T3D/assets/GameObjectAsset.h" 76#endif 77 78class SceneManager; 79class SceneRenderState; 80class SceneTraversalState; 81class SceneCameraState; 82class SceneObjectLink; 83class SceneObjectLightingPlugin; 84 85class Convex; 86class LightInfo; 87class SFXAmbience; 88 89struct ObjectRenderInst; 90struct Move; 91 92 93/// A 3D object. 94/// 95/// @section SceneObject_intro Introduction 96/// 97/// SceneObject exists as a foundation for 3D objects in Torque. It provides the 98/// basic functionality for: 99/// - A scene graph (in the Zones and Portals sections), allowing efficient 100/// and robust rendering of the game scene. 101/// - Various helper functions, including functions to get bounding information 102/// and momentum/velocity. 103/// - Collision detection, as well as ray casting. 104/// - Lighting. SceneObjects can register lights both at lightmap generation time, 105/// and dynamic lights at runtime (for special effects, such as from flame or 106/// a projectile, or from an explosion). 107/// - Manipulating scene objects, for instance varying scale. 108/// 109/// @section SceneObject_example An Example 110/// 111/// Melv May has written a most marvelous example object deriving from SceneObject. 112/// Unfortunately this page is too small to contain it. 113/// 114/// @see http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=3217 115/// for a copy of Melv's example. 116class SceneObject : public NetObject, private SceneContainer::Link, public ProcessObject 117{ 118 public: 119 120 typedef NetObject Parent; 121 122 friend class SceneManager; 123 friend class SceneContainer; 124 friend class SceneZoneSpaceManager; 125 friend class SceneCullingState; // _getZoneRefHead 126 friend class SceneObjectLink; // mSceneObjectLinks 127 128 enum 129 { 130 /// Maximum number of zones that an object can concurrently be assigned to. 131 MaxObjectZones = 128, 132 133 NumMountPoints = 32, 134 NumMountPointBits = 5, 135 }; 136 137 /// Networking dirty mask. 138 enum SceneObjectMasks 139 { 140 InitialUpdateMask = BIT( 0 ), 141 ScaleMask = BIT( 1 ), 142 FlagMask = BIT( 2 ), 143 MountedMask = BIT( 3 ), 144 NextFreeMask = BIT( 4 ) 145 }; 146 147 /// Bit-flags stored in mObjectFlags. 148 /// If a derived class adds more flags they must overload 149 /// getObjectFlagMax to ensure those flags will be transmitted over 150 /// the network. 151 /// @see getObjectFlagMax 152 enum SceneObjectFlags 153 { 154 /// If set, the object can be rendered. 155 /// @note The per-class render disable flag can override the per-object flag. 156 RenderEnabledFlag = BIT( 0 ), 157 158 /// If set, the object can be selected in the editor. 159 /// @note The per-class selection disable flag can override the per-object flag. 160 SelectionEnabledFlag = BIT( 1 ), 161 162 /// If set, object will not be subjected to culling when in the editor. 163 /// This is useful to bypass zone culling and always render certain editor-only 164 /// visual elements (like the zones themselves). 165 DisableCullingInEditorFlag = BIT( 2 ), 166 167 /// If set, object will be used as a visual occluder. In this case, 168 /// the object should implement buildSilhouette() and return a 169 /// *convex* silhouette polygon. 170 VisualOccluderFlag = BIT( 3 ), 171 172 /// If set, object will be used as a sound occluder. 173 SoundOccluderFlag = BIT( 4 ), 174 175 NextFreeFlag = BIT( 5 ) 176 }; 177 178 protected: 179 180 /// Combination of SceneObjectFlags. 181 BitSet32 mObjectFlags; 182 183 /// SceneManager to which this SceneObject belongs. 184 SceneManager* mSceneManager; 185 186 /// Links installed by SceneTrackers attached to this object. 187 SceneObjectLink* mSceneObjectLinks; 188 189 /// SceneObjectLightingPlugin attached to this object. 190 SceneObjectLightingPlugin* mLightPlugin; 191 192 /// Object type mask. 193 /// @see SimObjectTypes 194 U32 mTypeMask; 195 196 /// @name Mounting 197 /// @{ 198 199 /// Mounted object. 200 struct MountInfo 201 { 202 SceneObject* list; ///< Linked-list of objects mounted on this object 203 SceneObject* object; ///< Object this object is mounted on. 204 SceneObject* link; ///< Link to next object mounted to this object's mount 205 S32 node; ///< Node point we are mounted to. 206 MatrixF xfm; 207 }; 208 209 /// 210 MountInfo mMount; 211 212 /// 213 SimPersistID* mMountPID; 214 215 StringTableEntry mGameObjectAssetId; 216 AssetPtr<GameObjectAsset> mGameObjectAsset; 217 218 //Marked if this entity is a GameObject and deliniates from the parent GO asset 219 bool mDirtyGameObject; 220 221 /// @} 222 223 /// @name Zoning 224 /// @{ 225 226 /// Bidirectional link between a zone manager and its objects. 227 struct ZoneRef : public SceneObjectRefBase< ZoneRef > 228 { 229 /// ID of zone. 230 U32 zone; 231 }; 232 233 /// Iterator over the zones that the object is assigned to. 234 /// @note This iterator expects a clean zoning state. It will not update the 235 /// zoning state in case it is dirty. 236 struct ObjectZonesIterator 237 { 238 ObjectZonesIterator( SceneObject* object ) 239 : mCurrent( object->_getZoneRefHead() ) {} 240 241 bool isValid() const 242 { 243 return ( mCurrent != NULL ); 244 } 245 ObjectZonesIterator& operator++() 246 { 247 AssertFatal( isValid(), "SceneObject::ObjectZonesIterator::operator++ - Invalid iterator!" ); 248 mCurrent = mCurrent->nextInObj; 249 return *this; 250 } 251 U32 operator*() const 252 { 253 AssertFatal( isValid(), "SceneObject::ObjectZonesIterator::operator* - Invalid iterator!" ); 254 return mCurrent->zone; 255 } 256 257 private: 258 ZoneRef* mCurrent; 259 }; 260 261 friend struct ObjectZonesIterator; 262 263 /// If an object moves, its zoning state needs to be updated. This is deferred 264 /// to when the state is actually needed and this flag indicates a refresh 265 /// is necessary. 266 mutable bool mZoneRefDirty; 267 268 /// Number of zones this object is assigned to. 269 /// @note If #mZoneRefDirty is set, this might be outdated. 270 mutable U32 mNumCurrZones; 271 272 /// List of zones that this object is part of. 273 /// @note If #mZoneRefDirty is set, this might be outdated. 274 mutable ZoneRef* mZoneRefHead; 275 276 /// Refresh the zoning state of this object, if it isn't up-to-date anymore. 277 void _updateZoningState() const; 278 279 /// Return the first link in the zone list of this object. Each link represents 280 /// a single zone that the object is assigned to. 281 /// 282 /// @note This method will return the zoning list as is. In case the zoning state 283 /// of the object is dirty, the list contents may be outdated. 284 ZoneRef* _getZoneRefHead() const { return mZoneRefHead; } 285 286 /// @} 287 288 /// @name Transform and Collision Members 289 /// @{ 290 291 // PATHSHAPE 292 MatrixF mLastXform; 293 // PATHSHAPE END 294 295 /// Transform from object space to world space. 296 MatrixF mObjToWorld; 297 298 /// Transform from world space to object space (inverse). 299 MatrixF mWorldToObj; 300 301 /// Object scale. 302 Point3F mObjScale; 303 304 /// Bounding box in object space. 305 Box3F mObjBox; 306 307 /// Bounding box (AABB) in world space. 308 Box3F mWorldBox; 309 310 /// Bounding sphere in world space. 311 SphereF mWorldSphere; 312 313 /// Render matrix to transform object space to world space. 314 MatrixF mRenderObjToWorld; 315 316 /// Render matrix to transform world space to object space. 317 MatrixF mRenderWorldToObj; 318 319 /// Render bounding box in world space. 320 Box3F mRenderWorldBox; 321 322 /// Render bounding sphere in world space. 323 SphereF mRenderWorldSphere; 324 325 /// Whether this object is considered to have an infinite bounding box. 326 bool mGlobalBounds; 327 328 /// 329 S32 mCollisionCount; 330 331 /// Regenerates the world-space bounding box and bounding sphere. 332 void resetWorldBox(); 333 334 /// Regenerates the render-world-space bounding box and sphere. 335 void resetRenderWorldBox(); 336 337 /// Regenerates the object-space bounding box from the world-space 338 /// bounding box, the world space to object space transform, and 339 /// the object scale. 340 void resetObjectBox(); 341 342 /// Called when the size of the object changes. 343 virtual void onScaleChanged() {} 344 345 /// @} 346 347 /// Object which must be ticked before this object. 348 SimObjectPtr< SceneObject> mAfterObject; 349 350 /// @name SceneContainer Interface 351 /// 352 /// When objects are searched, we go through all the zones and ask them for 353 /// all of their objects. Because an object can exist in multiple zones, the 354 /// container sequence key is set to the id of the current search. Then, while 355 /// searching, we check to see if an object's sequence key is the same as the 356 /// current search key. If it is, it will NOT be added to the list of returns 357 /// since it has already been processed. 358 /// 359 /// @{ 360 361 /// Container database that the object is assigned to. 362 SceneContainer* mContainer; 363 364 /// SceneContainer sequence key. 365 U32 mContainerSeqKey; 366 367 /// 368 SceneObjectRef* mBinRefHead; 369 370 U32 mBinMinX; 371 U32 mBinMaxX; 372 U32 mBinMinY; 373 U32 mBinMaxY; 374 375 /// Returns the container sequence key. 376 U32 getContainerSeqKey() const { return mContainerSeqKey; } 377 378 /// Sets the container sequence key. 379 void setContainerSeqKey( const U32 key ) { mContainerSeqKey = key; } 380 381 /// @} 382 383 /// Called when this is added to a SceneManager. 384 virtual bool onSceneAdd() { return true; } 385 386 /// Called when this is removed from its current SceneManager. 387 virtual void onSceneRemove() {} 388 389 /// Returns the greatest object flag bit defined. 390 /// Only bits within this range will be transmitted over the network. 391 virtual U32 getObjectFlagMax() const { return NextFreeFlag - 1; } 392 393 public: 394 395 SceneObject(); 396 virtual ~SceneObject(); 397 bool mPathfindingIgnore; 398 399 /// Triggered when a SceneObject onAdd is called. 400 static Signal< void( SceneObject* ) > smSceneObjectAdd; 401 402 /// Triggered when a SceneObject onRemove is called. 403 static Signal< void( SceneObject* ) > smSceneObjectRemove; 404 405 /// Return the type mask that indicates to which broad object categories 406 /// this object belongs. 407 U32 getTypeMask() const { return mTypeMask; } 408 409 /// @name SceneManager Functionality 410 /// @{ 411 412 /// Return the SceneManager that this SceneObject belongs to. 413 SceneManager* getSceneManager() const { return mSceneManager; } 414 415 /// Adds object to the client or server container depending on the object 416 void addToScene(); 417 418 /// Removes the object from the client/server container 419 void removeFromScene(); 420 421 /// Returns a pointer to the container that contains this object 422 SceneContainer* getContainer() { return mContainer; } 423 424 /// @} 425 426 /// @name Flags 427 /// @{ 428 429 /// Return true if this object is rendered. 430 bool isRenderEnabled() const; 431 432 /// Set whether the object gets rendered. 433 void setRenderEnabled( bool value ); 434 435 /// Return true if this object can be selected in the editor. 436 bool isSelectionEnabled() const; 437 438 /// Set whether the object can be selected in the editor. 439 void setSelectionEnabled( bool value ); 440 441 /// Return true if the object doesn't want to be subjected to culling 442 /// when in the editor. 443 bool isCullingDisabledInEditor() const { return mObjectFlags.test( DisableCullingInEditorFlag ); } 444 445 /// Return true if the object should be taken into account for visual occlusion. 446 bool isVisualOccluder() const { return mObjectFlags.test( VisualOccluderFlag ); } 447 448 /// @} 449 450 /// @name Collision and transform related interface 451 /// 452 /// The Render Transform is the interpolated transform with respect to the 453 /// frame rate. The Render Transform will differ from the object transform 454 /// because the simulation is updated in fixed intervals, which controls the 455 /// object transform. The framerate is, most likely, higher than this rate, 456 /// so that is why the render transform is interpolated and will differ slightly 457 /// from the object transform. 458 /// 459 /// @{ 460 461 /// Disables collisions for this object including raycasts 462 virtual void disableCollision(); 463 464 /// Enables collisions for this object 465 virtual void enableCollision(); 466 467 /// Returns true if collisions are enabled 468 bool isCollisionEnabled() const { return mCollisionCount == 0; } 469 470 /// This gets called when an object collides with this object. 471 /// @param object Object colliding with this object 472 /// @param vec Vector along which collision occurred 473 virtual void onCollision( SceneObject *object, const VectorF &vec ) {} 474 475 /// Returns true if this object allows itself to be displaced 476 /// @see displaceObject 477 virtual bool isDisplacable() const { return false; } 478 479 /// Returns the momentum of this object 480 virtual Point3F getMomentum() const { return Point3F( 0, 0, 0 ); } 481 482 /// Sets the momentum of this object 483 /// @param momentum Momentum 484 virtual void setMomentum( const Point3F& momentum ) {} 485 486 /// Returns the mass of this object 487 virtual F32 getMass() const { return 1.f; } 488 489 /// Displaces this object by a vector 490 /// @param displaceVector Displacement vector 491 virtual bool displaceObject( const Point3F& displaceVector ) { return false; } 492 493 /// Returns the transform which can be used to convert object space 494 /// to world space 495 virtual const MatrixF& getTransform() const { return mObjToWorld; } 496 497 /// Returns the transform which can be used to convert world space 498 /// into object space 499 const MatrixF& getWorldTransform() const { return mWorldToObj; } 500 501 /// Returns the scale of the object 502 virtual const VectorF& getScale() const { return mObjScale; } 503 504 /// Returns the bounding box for this object in local coordinates. 505 const Box3F& getObjBox() const { return mObjBox; } 506 507 /// Returns the bounding box for this object in world coordinates. 508 const Box3F& getWorldBox() const { return mWorldBox; } 509 510 /// Returns the bounding sphere for this object in world coordinates. 511 const SphereF& getWorldSphere() const { return mWorldSphere; } 512 513 /// Returns the center of the bounding box in world coordinates 514 Point3F getBoxCenter() const { return ( mWorldBox.minExtents + mWorldBox.maxExtents ) * 0.5f; } 515 516 /// Sets the Object -> World transform 517 /// 518 /// @param mat New transform matrix 519 virtual void setTransform( const MatrixF &mat ); 520 521 /// Sets the scale for the object 522 /// @param scale Scaling values 523 virtual void setScale( const VectorF &scale ); 524 525 /// Sets the forward vector of the object 526 void setForwardVector(VectorF newForward, VectorF upVector = VectorF(0, 0, 1)); 527 528 /// This sets the render transform for this object 529 /// @param mat New render transform 530 virtual void setRenderTransform(const MatrixF &mat); 531 532 /// Returns the render transform 533 const MatrixF& getRenderTransform() const { return mRenderObjToWorld; } 534 535 /// Returns the render transform to convert world to local coordinates 536 const MatrixF& getRenderWorldTransform() const { return mRenderWorldToObj; } 537 538 /// Returns the render world box 539 const Box3F& getRenderWorldBox() const { return mRenderWorldBox; } 540 541 /// Sets the state of this object as hidden or not. If an object is hidden 542 /// it is removed entirely from collisions, it is not ghosted and is 543 /// essentially "non existant" as far as simulation is concerned. 544 /// @param hidden True if object is to be hidden 545 virtual void setHidden( bool hidden ); 546 547 /// Builds a convex hull for this object. 548 /// 549 /// Think of a convex hull as a low-res mesh which covers, as tightly as 550 /// possible, the object mesh, and is used as a collision mesh. 551 /// @param box 552 /// @param convex Convex mesh generated (out) 553 virtual void buildConvex( const Box3F& box,Convex* convex ) {} 554 555 /// Builds a list of polygons which intersect a bounding volume. 556 /// 557 /// This will use either the sphere or the box, not both, the 558 /// SceneObject implementation ignores sphere. 559 /// 560 /// @see AbstractPolyList 561 /// @param context A contentual hint as to the type of polylist to build. 562 /// @param polyList Poly list build (out) 563 /// @param box Box bounding volume 564 /// @param sphere Sphere bounding volume 565 /// 566 virtual bool buildPolyList( PolyListContext context, 567 AbstractPolyList* polyList, 568 const Box3F& box, 569 const SphereF& sphere ) { return false; } 570 571 /// Builds a list of polygons which intersect a bounding volume for exporting 572 /// 573 /// This will use either the sphere or the box, not both, the 574 /// SceneObject implementation ignores sphere. 575 /// 576 /// @see AbstractPolyList 577 /// @param context A contentual hint as to the type of polylist to build. 578 /// @param polyList Poly list build (out) 579 /// @param box Box bounding volume 580 /// @param sphere Sphere bounding volume 581 /// 582 virtual bool buildExportPolyList(ColladaUtils::ExportData *exportData, 583 const Box3F& box, 584 const SphereF& sphere) { 585 return false; 586 } 587 588 /// Casts a ray and obtain collision information, returns true if RayInfo is modified. 589 /// 590 /// @param start Start point of ray 591 /// @param end End point of ray 592 /// @param info Collision information obtained (out) 593 virtual bool castRay( const Point3F& start, const Point3F& end, RayInfo* info ) { return false; } 594 595 /// Casts a ray against rendered geometry, returns true if RayInfo is modified. 596 /// 597 /// @param start Start point of ray 598 /// @param end End point of ray 599 /// @param info Collision information obtained (out) 600 virtual bool castRayRendered( const Point3F& start, const Point3F& end, RayInfo* info ); 601 602 /// Build a world-space silhouette polygon for the object for the given camera settings. 603 /// This is used for occlusion. 604 /// 605 /// @param cameraState Camera view parameters. 606 /// @param outPoints Vector to store the resulting polygon points in. Leave untouched 607 /// if method is not implemented. 608 virtual void buildSilhouette( const SceneCameraState& cameraState, Vector< Point3F>& outPoints ) {} 609 610 /// Return true if the given point is contained by the object's (collision) shape. 611 /// 612 /// The default implementation will return true if the point is within the object's 613 /// bounding box. Subclasses should implement more precise tests. 614 virtual bool containsPoint( const Point3F &point ); 615 616 virtual bool collideBox( const Point3F& start, const Point3F& end, RayInfo* info ); 617 618 /// Returns the position of the object. 619 virtual Point3F getPosition() const; 620 621 /// Returns the render-position of the object. 622 /// 623 /// @see getRenderTransform 624 Point3F getRenderPosition() const; 625 626 /// Sets the position of the object 627 void setPosition ( const Point3F& pos ); 628 629 /// Gets the velocity of the object. 630 virtual Point3F getVelocity() const { return Point3F::Zero; } 631 632 /// Sets the velocity of the object 633 /// @param v Velocity 634 virtual void setVelocity( const Point3F &v ) {} 635 636 /// Applies an impulse force to this object 637 /// @param pos Position where impulse came from in world space 638 /// @param vec Velocity vector (Impulse force F = m * v) 639 virtual void applyImpulse( const Point3F &pos, const VectorF &vec ) {} 640 641 /// Applies a radial impulse to the object 642 /// using the impulse origin and force. 643 /// @param origin Point of origin of the radial impulse. 644 /// @param radius The radius of the impulse area. 645 /// @param magnitude The strength of the impulse. 646 virtual void applyRadialImpulse( const Point3F &origin, F32 radius, F32 magnitude ) {} 647 648 /// Returns the distance from this object to a point 649 /// @param pnt World space point to measure to 650 virtual F32 distanceTo( const Point3F &pnt ) const; 651 652 /// @} 653 654 /// @name Mounting 655 /// @{ 656 657 /// ex: Mount B to A at A's node N 658 /// A.mountObject( B, N ) 659 /// 660 /// @param obj Object to mount 661 /// @param node Mount node ID 662 virtual void mountObject( SceneObject *obj, S32 node, const MatrixF &xfm = MatrixF::Identity ); 663 664 /// Remove an object mounting 665 /// @param obj Object to unmount 666 virtual void unmountObject( SceneObject *obj ); 667 668 /// Unmount this object from it's mount 669 virtual void unmount(); 670 671 /// Callback when this object is mounted. 672 /// @param obj Object we are mounting to. 673 /// @param node Node we are unmounting from. 674 virtual void onMount( SceneObject *obj, S32 node ); 675 676 /// Callback when this object is unmounted. This should be overridden to 677 /// set maskbits or do other object type specific work. 678 /// @param obj Object we are unmounting from. 679 /// @param node Node we are unmounting from. 680 virtual void onUnmount( SceneObject *obj, S32 node ); 681 682 // Returns mount point to world space transform at tick time. 683 virtual void getMountTransform( S32 index, const MatrixF &xfm, MatrixF *outMat ); 684 685 // Returns mount point to world space transform at render time. 686 // Note this will only be correct if called after this object has interpolated. 687 virtual void getRenderMountTransform( F32 delta, S32 index, const MatrixF &xfm, MatrixF *outMat ); 688 689 /// Return the object that this object is mounted to. 690 virtual SceneObject* getObjectMount() { return mMount.object; } 691 692 /// Return object link of next object mounted to this object's mount 693 virtual SceneObject* getMountLink() { return mMount.link; } 694 695 /// Returns object list of objects mounted to this object. 696 virtual SceneObject* getMountList() { return mMount.list; } 697 698 /// Returns the mount id that this is mounted to. 699 virtual U32 getMountNode() { return mMount.node; } 700 701 /// Returns true if this object is mounted to anything at all 702 /// Also try to resolve the PID to objectId here if it is pending. 703 virtual bool isMounted(); 704 705 /// Returns the number of object mounted along with this 706 virtual S32 getMountedObjectCount(); 707 708 /// Returns the object mounted at a position in the mount list 709 /// @param idx Position on the mount list 710 virtual SceneObject* getMountedObject( S32 idx ); 711 712 /// Returns the node the object at idx is mounted to 713 /// @param idx Index 714 virtual S32 getMountedObjectNode( S32 idx ); 715 716 /// Returns the object a object on the mount list is mounted to 717 /// @param node 718 virtual SceneObject* getMountNodeObject( S32 node ); 719 720 void resolveMountPID(); 721 722 /// @} 723 724 /// @name Sound 725 /// @{ 726 727 /// Return whether the object's collision shape is blocking sound. 728 bool isOccludingSound() const { return mObjectFlags.test( SoundOccluderFlag ); } 729 730 /// Return the ambient sound space active inside the volume of this object or NULL if the object does 731 /// not have its own ambient space. 732 virtual SFXAmbience* getSoundAmbience() const { return NULL; } 733 734 /// @} 735 736 /// @name Rendering 737 /// @{ 738 739 /// Called when the SceneManager is ready for the registration of render instances. 740 /// @param state Rendering state. 741 virtual void prepRenderImage( SceneRenderState* state ) {} 742 743 /// @} 744 745 /// @name Lighting 746 /// @{ 747 748 void setLightingPlugin( SceneObjectLightingPlugin* plugin ) { mLightPlugin = plugin; } 749 SceneObjectLightingPlugin* getLightingPlugin() { return mLightPlugin; } 750 751 /// Gets the number of zones containing this object. 752 U32 getNumCurrZones() const { return mNumCurrZones; } 753 754 /// Returns the nth zone containing this object. 755 U32 getCurrZone(const U32 index) const; 756 757 /// @} 758 759 /// @name Global Bounds 760 /// @{ 761 762 const bool isGlobalBounds() const 763 { 764 return mGlobalBounds; 765 } 766 767 /// If global bounds are set to be true, then the object is assumed to 768 /// have an infinitely large bounding box for collision and rendering 769 /// purposes. 770 /// 771 /// They can't be toggled currently. 772 void setGlobalBounds(); 773 774 /// @} 775 776 /// Return the ProcessList for this object to use. 777 ProcessList* getProcessList() const; 778 779 // ProcessObject, 780 virtual void processAfter( ProcessObject *obj ); 781 virtual void clearProcessAfter(); 782 virtual ProcessObject* getAfterObject() const { return mAfterObject; } 783 virtual void setProcessTick( bool t ); 784 785 // NetObject. 786 virtual U32 packUpdate( NetConnection* conn, U32 mask, BitStream* stream ); 787 virtual void unpackUpdate( NetConnection* conn, BitStream* stream ); 788 virtual void onCameraScopeQuery( NetConnection* connection, CameraScopeQuery* query ); 789 790 // SimObject. 791 virtual bool onAdd(); 792 virtual void onRemove(); 793 virtual void onDeleteNotify( SimObject *object ); 794 virtual void inspectPostApply(); 795 virtual bool writeField( StringTableEntry fieldName, const char* value ); 796 797 static void initPersistFields(); 798 799 static bool _setGameObject(void* object, const char* index, const char* data); 800 801 DECLARE_CONOBJECT( SceneObject ); 802 private: 803 804 SceneObject( const SceneObject& ); ///< @deprecated disallowed 805 806 /// For ScopeAlways objects to be able to properly implement setHidden(), they 807 /// need to temporarily give up ScopeAlways status while being hidden. Otherwise 808 /// the client-side ghost will not disappear as the server-side object will be 809 /// forced to stay in scope. 810 bool mIsScopeAlways; 811 812 /// @name Protected field getters/setters 813 /// @{ 814 815 static const char* _getRenderEnabled( void *object, const char *data ); 816 static bool _setRenderEnabled( void *object, const char *index, const char *data ); 817 static const char* _getSelectionEnabled( void *object, const char *data ); 818 static bool _setSelectionEnabled( void *object, const char *index, const char *data ); 819 static bool _setFieldPosition( void *object, const char *index, const char *data ); 820 static bool _setFieldRotation( void *object, const char *index, const char *data ); 821 static bool _setFieldScale( void *object, const char *index, const char *data ); 822 static bool _setMountPID( void* object, const char* index, const char* data ); 823 static bool _setAccuEnabled( void *object, const char *index, const char *data ); 824 825 /// @} 826// PATHSHAPE 827 /// @} 828 //Anthony's Original Code, still used so i keep it here 829 /// TGE uses the term "mount" in a quirky, staticky way relating to its limited use to have 830 /// riders and guns mounted on a vehicle (and similar) 831 /// I did not alter that code at all (yet) and did not want to keep its terminology for other reasons 832 /// I decided to support a hierarchy of scene objects and dubbed the operations 833 /// attaching and removing child SceneObjects 834 protected: 835 836 // this member struct tracks the relationship to parent and children 837 // sceneObjects in a hierarchical scene graph whose root is the entire Scene 838 struct AttachInfo { 839 SceneObject* firstChild; ///< Objects mounted on this object 840 SimObjectPtr<SceneObject> parent; ///< Object this object is mounted on. 841 SceneObject* nextSibling; ///< Link to next child object of this object's parent 842 MatrixF objToParent; ///< this obects transformation in the parent object's space 843 MatrixF RenderobjToParent; ///< this obects Render Offset transformation to the parent object 844 } mGraph; 845// PATHSHAPE END 846 847 848 // Accumulation Texture 849 // Note: This was placed in SceneObject to both ShapeBase and TSStatic could support it. 850 public: 851 GFXTextureObject* mAccuTex; 852 // mSelectionFlags field keeps track of flags related to object selection. 853 // PRE_SELECTED marks an object as pre-selected (object under cursor) 854 // SELECTED marks an object as selected (a target) 855 protected: 856 U8 mSelectionFlags; 857 public: 858 enum { 859 SELECTED = BIT(0), 860 PRE_SELECTED = BIT(1), 861 }; 862 virtual void setSelectionFlags(U8 flags) { mSelectionFlags = flags; } 863 U8 getSelectionFlags() const { return mSelectionFlags; } 864 bool needsSelectionHighlighting() const { return (mSelectionFlags != 0); } 865 // This should only return true if the object represents an independent camera 866 // as opposed to something like a Player that has a built-in camera that requires 867 // special calculations to determine the view transform. 868 virtual bool isCamera() const { return false; } 869 // AFX CODE BLOCK (is-camera) >> 870// PATHSHAPE 871// Added for dynamic attaching 872 void UpdateXformChange(const MatrixF &mat); 873 /// this is useful for setting NULL parent (making SceneObject a root object) 874 virtual bool attachToParent(SceneObject *parent, MatrixF *atThisOffset = NULL, S32 node=0); 875 SceneObject *getParent() { return mGraph.parent; }; 876 877 878 /// attach a subobject, but do not alter the subObject's present absolute position or orientation 879 bool attachChild(SceneObject* subObject); 880 /// attach a subobject, at the specified offset expressed in our local coordinate space 881 bool attachChildAt(SceneObject* subObject, MatrixF atThisTransform, S32 node); 882 883 /// attach a subobject, at the specified position expressed in our local coordinate space 884 bool attachChildAt(SceneObject* subObject, Point3F atThisPosition); 885 886 /// how many child SceneObjects are (directly) attached to this one? 887 U32 getNumChildren() const; 888 889 /// how many child objects does this SceneObject have when we count them recursively? 890 U32 getNumProgeny() const; 891 892 /// returns the (direct) child SceneObject at the given index (0 <= index <= getNumChildren() - 1) 893 SceneObject *getChild(U32 index) const; 894 895 /// is this SceneObject a child (directly or indirectly) of the given object? 896 bool isChildOf(SceneObject *); 897 898 /// set position in parent SceneObject's coordinate space (or in world space if no parent) 899 //void setLocalPosition(const Point3F &pos); 900 901 /// move the object in parent SceneObject's coordinate space (or in world space if no parent) 902 //void localMove(const Point3F &delta); 903 /// as localMove(const Point3F &delta), with different signature 904 //void localMove(F32 x, F32 y, F32 z); 905 906 /// move the object in world space, without altering place in scene hierarchy 907 void move(const Point3F &delta); 908 909 // Does checks for children objects and updates their positions 910 void PerformUpdatesForChildren(MatrixF mat); 911 912 // Move the RenderTransform 913 void moveRender(const Point3F &delta); 914 //Calculate how much to adjust the render transform - Called by the child objects 915 void updateRenderChangesByParent(); 916 //Calculate how much to adjust the transform - Called by the parent object 917 void updateChildTransform(); 918 /// as move(const Point3F &delta), with different signature 919 void move(F32 x, F32 y, F32 z); 920 921 /// returns the transform relative to parent SceneObject transform (or world transform if no parent) 922 //const MatrixF& getLocalTransform() const; 923 /// returns the position within parent SceneObject space (or world space if no parent) 924 //Point3F getLocalPosition() const; 925 926 927// virtual void onParentScaleChanged(); 928// virtual void onParentTransformChanged(); 929 930 /// Sets the Object -> Parent transform. If no parent SceneObject, this is equivalent to 931 /// setTransform() 932 /// 933 /// @param mat New transform matrix 934 //virtual void setLocalTransform(const MatrixF & mat); 935 936 937 /// Called to let instance specific code happen 938 virtual void onLostParent(SceneObject *oldParent); 939 /// Called to let instance specific code happen 940 virtual void onNewParent(SceneObject *newParent); 941 /// notification that a direct child object has been attached 942 virtual void onNewChild(SceneObject *subObject); 943 /// notification that a direct child object has been detached 944 virtual void onLostChild(SceneObject *subObject); 945// PATHSHAPE END 946 947 virtual void getUtilizedAssets(Vector<StringTableEntry>* usedAssetsList) {} 948}; 949 950#endif // _SCENEOBJECT_H_ 951 952