Torque3D Documentation / _generateds / VPathObject.cpp

VPathObject.cpp

Engine/source/Verve/VPath/VPathObject.cpp

More...

Detailed Description

Public Variables

 EndImplementEnumType 
U32 gOrientationTypeBits 

Public Functions

ImplementEnumType(VPathObjectOrientationType , "" )

  1
  2//-----------------------------------------------------------------------------
  3// Verve
  4// Copyright (C) 2014 - Violent Tulip
  5//
  6// Permission is hereby granted, free of charge, to any person obtaining a copy
  7// of this software and associated documentation files (the "Software"), to
  8// deal in the Software without restriction, including without limitation the
  9// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 10// sell copies of the Software, and to permit persons to whom the Software is
 11// furnished to do so, subject to the following conditions:
 12//
 13// The above copyright notice and this permission notice shall be included in
 14// all copies or substantial portions of the Software.
 15//
 16// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 21// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 22// IN THE SOFTWARE.
 23//-----------------------------------------------------------------------------
 24#include "VPathObject.h"
 25#include "VPath.h"
 26
 27#include "core/stream/bitStream.h"
 28#include "sim/netConnection.h"
 29
 30//-----------------------------------------------------------------------------
 31
 32static U32 gOrientationTypeBits = getBinLog2( getNextPow2( VPathObject::k_OrientationTypeSize ) );
 33
 34//-----------------------------------------------------------------------------
 35
 36VPathObject::VPathObject( void ) :
 37        mActive( false ),
 38        mLastTime( 0 ),
 39        mLastDelta( 0.f ),
 40        mObject( NULL ),
 41        mTimeInterp( 0.f ),
 42        mPathInterp( 0.f ),
 43        mPosition( 0.f, 0.f, 0.f ),
 44        mOffset( 0.f, 0.f, 0.f ),
 45        mOrientation( 0.f, 1.f, 0.f ),
 46        mForward( true ),
 47        mSpeed( 10.f ),
 48        mSourceNode( 0 ),
 49        mDestinationNode( 0 ),
 50        mStartNode( 0 ),
 51        mEndNode( 0 )
 52{
 53    // Init.
 54    mOrientationMode.Type   = k_OrientationToPath;
 55    mOrientationMode.Object = NULL;
 56    mOrientationMode.Point  = Point3F::Zero;
 57
 58    // Set the initial mask.
 59    mNetState.setMaskBits( k_StateInit );
 60
 61    // Reset Time.
 62    resetTime();
 63
 64    // Reset Delta.
 65    resetDelta();
 66
 67    VECTOR_SET_ASSOCIATION( mNetState );
 68}
 69
 70VPathObject::~VPathObject( void )
 71{
 72    // Void.
 73}
 74
 75//-----------------------------------------------------------------------------
 76//
 77// Network Methods.
 78//
 79//-----------------------------------------------------------------------------
 80
 81U32 VPathObject::packUpdate( NetConnection *pConnection, BitStream *pStream )
 82{
 83    // Init Return Mask.
 84    U32 retMask = 0;
 85
 86    // Fetch State.
 87    VNetStateInfo *state = getState( pConnection );
 88
 89    // Write Active.
 90    pStream->writeFlag( mActive );
 91
 92    // Send Object Update?
 93    if ( pStream->writeFlag( state->Mask & k_StateUpdateObject ) )
 94    {
 95        // Successful Send?
 96        bool success = false;
 97
 98        // Valid Object?
 99        if ( !mObject )
100        {
101            // No Object.
102            pStream->writeFlag( false );
103        }
104        else
105        {
106            // Write Ghost Index.
107            const S32 ghostIndex = pConnection->getGhostIndex( mObject );
108            if ( pStream->writeFlag( ghostIndex != -1 ) )
109            {
110                // Write Ghost Id.
111                pStream->writeInt( ghostIndex, NetConnection::GhostIdBitSize );
112
113                // Success!
114                success = true;
115                // Clear Update.
116                state->Mask &= ~<a href="/coding/class/structvpathobject/#structvpathobject_1acf711c693be92b0c218d6371d683c497a579474bcfe34691cd0ea99f7b3a7bb73">k_StateUpdateObject</a>;
117            }
118        }
119
120        if ( !success )
121        {
122            // Try Again Later.
123            retMask |= VPath::ObjectUpdateMask;
124        }
125    }
126
127    // Send Mount Update?
128    if ( pStream->writeFlag( state->Mask & k_StateUpdateMount ) )
129    {
130        // Successful Send?
131        bool success = false;
132
133        // Valid Objects?
134        if ( !mObject || !mObject->getObjectMount() || ( state->Mask & k_StateUpdateObject ) )
135        {
136            // No Object.
137            pStream->writeFlag( false );
138        }
139        else
140        {
141            // Write Ghost Index.
142            const S32 ghostIndex = pConnection->getGhostIndex( mObject->getObjectMount() );
143            if ( pStream->writeFlag( ghostIndex != -1 ) )
144            {
145                // Write Ghost Id.
146                pStream->writeInt( ghostIndex, NetConnection::GhostIdBitSize );
147                // Write Mount Node.
148                pStream->writeInt( mObject->getMountNode(), SceneObject::NumMountPointBits );
149
150                // Success!
151                success = true;
152                // Clear Update.
153                state->Mask &= ~<a href="/coding/class/structvpathobject/#structvpathobject_1acf711c693be92b0c218d6371d683c497a4ad23159bc855913ecd58dbb643db4cb">k_StateUpdateMount</a>;
154            }
155        }
156
157        if ( !success )
158        {
159            // Try Again Later.
160            retMask |= VPath::ObjectUpdateMask;
161        }
162    }
163
164    // Send Position Update?
165    if ( pStream->writeFlag( state->Mask & k_StateUpdatePosition ) )
166    {
167        // Write Position.
168        pStream->write( mTimeInterp );
169        pStream->write( mPathInterp );
170
171        pStream->write( mPosition.x );
172        pStream->write( mPosition.y );
173        pStream->write( mPosition.z );
174
175        pStream->write( mOrientation.x );
176        pStream->write( mOrientation.y );
177        pStream->write( mOrientation.z );
178
179        pStream->writeInt( mSourceNode,      VPath::gMaxNodeBits );
180        pStream->writeInt( mDestinationNode, VPath::gMaxNodeBits );
181
182        // Clear Update.
183        state->Mask &= ~<a href="/coding/class/structvpathobject/#structvpathobject_1acf711c693be92b0c218d6371d683c497a705ae34141c4f6a284a0f656b092e460">k_StateUpdatePosition</a>;
184    }
185
186    // Send State Update?
187    if ( pStream->writeFlag( state->Mask & k_StateUpdateState ) )
188    {
189        // Successful Send?
190        bool success = true;
191
192        // Write State.
193        pStream->writeInt( mOrientationMode.Type, gOrientationTypeBits );
194
195        switch ( mOrientationMode.Type )
196        {
197            case k_OrientationToObject :
198                {
199                    // Write Ghost Index.
200                    const S32 ghostIndex = pConnection->getGhostIndex( mOrientationMode.Object );
201                    if ( pStream->writeFlag( ghostIndex != -1 ) )
202                    {
203                        pStream->writeInt( ghostIndex, NetConnection::GhostIdBitSize );
204                    }
205                    else
206                    {
207                        // Failed.
208                        success = false;
209                    }
210
211                } break;
212
213            case k_OrientationToPoint :
214                {
215                    // Write Point.
216                    pStream->write( mOrientationMode.Point.x );
217                    pStream->write( mOrientationMode.Point.y );
218                    pStream->write( mOrientationMode.Point.z );
219
220                } break;
221        }
222
223        pStream->writeFlag( mForward );
224        pStream->write( mSpeed );
225
226        // Write Offset.
227        pStream->write( mOffset.x );
228        pStream->write( mOffset.y );
229        pStream->write( mOffset.z );
230
231        pStream->writeInt( mStartNode, VPath::gMaxNodeBits );
232        pStream->writeInt( mEndNode,   VPath::gMaxNodeBits );
233
234        if ( success )
235        {
236            // Clear Update.
237            state->Mask &= ~<a href="/coding/class/structvpathobject/#structvpathobject_1acf711c693be92b0c218d6371d683c497aeb785534ac8e27948cd84e4ec3b2a374">k_StateUpdateState</a>;
238        }
239        else
240        {
241            // Try Again Later.
242            retMask |= VPath::ObjectUpdateMask;
243        }
244    }
245
246    // Return Mask.
247    return retMask;
248}
249
250void VPathObject::unpackUpdate( NetConnection *pConnection, BitStream *pStream )
251{
252    // Read Active.
253    setActive( pStream->readFlag() );
254
255    // Update Object?
256    if ( pStream->readFlag() )
257    {
258        if ( pStream->readFlag() )
259        {
260            // Read Ghost Index.
261            const S32 ghostIndex = pStream->readInt( NetConnection::GhostIdBitSize );
262
263            // Resolve Object.
264            setObject( static_cast<SceneObject*>( pConnection->resolveGhost( ghostIndex ) ) );
265
266            // Reset Delta.
267            resetDelta();
268        }
269        else
270        {
271            // Clear Object.
272            mObject = NULL;
273        }
274    }
275
276    // Update Mount?
277    if ( pStream->readFlag() )
278    {
279        if ( pStream->readFlag() )
280        {
281            // Read Ghost Index.
282            const S32 ghostIndex = pStream->readInt( NetConnection::GhostIdBitSize );
283            // Read Mount Node.
284            const S32 nodeIndex = pStream->readInt( SceneObject::NumMountPointBits );
285
286            // Resolve Object.
287            SceneObject *mountObject = static_cast<SceneObject*>( pConnection->resolveGhost( ghostIndex ) );
288            // Mount Object.
289            mountObject->mountObject( mObject, nodeIndex );
290        }
291        else
292        {
293            // ... unmount?
294        }
295    }
296
297    // Update Position?
298    if ( pStream->readFlag() )
299    {
300        // Read Updates.
301        pStream->read( &mTimeInterp );
302        pStream->read( &mPathInterp );
303
304        pStream->read( &mPosition.x );
305        pStream->read( &mPosition.y );
306        pStream->read( &mPosition.z );
307
308        pStream->read( &mOrientation.x );
309        pStream->read( &mOrientation.y );
310        pStream->read( &mOrientation.z );
311
312        mSourceNode      = pStream->readInt( VPath::gMaxNodeBits );
313        mDestinationNode = pStream->readInt( VPath::gMaxNodeBits );
314    }
315
316    // Update Heading?
317    if ( pStream->readFlag() )
318    {
319        // Read Orientation Mode.
320        mOrientationMode.Type = ( eOrientationType )pStream->readInt( gOrientationTypeBits );
321
322        switch ( mOrientationMode.Type )
323        {
324            case VPathObject::k_OrientationToObject :
325                {
326                    if ( pStream->readFlag() )
327                    {
328                        // Read Ghost Index.
329                        const S32 ghostIndex = pStream->readInt( NetConnection::GhostIdBitSize );
330                        // Resolve Object.
331                        mOrientationMode.Object = static_cast<SceneObject*>( pConnection->resolveGhost( ghostIndex ) );
332                    }
333
334                } break;
335
336            case VPathObject::k_OrientationToPoint :
337                {
338                    // Read Point.
339                    pStream->read( &mOrientationMode.Point.x );
340                    pStream->read( &mOrientationMode.Point.y );
341                    pStream->read( &mOrientationMode.Point.z );
342
343                } break;
344        }
345
346        // Read Updates.
347        mForward = pStream->readFlag();
348
349        pStream->read( &mSpeed );
350
351        pStream->read( &mOffset.x );
352        pStream->read( &mOffset.y );
353        pStream->read( &mOffset.z );
354
355        mStartNode = pStream->readInt( VPath::gMaxNodeBits );
356        mEndNode   = pStream->readInt( VPath::gMaxNodeBits );
357    }
358}
359
360//-----------------------------------------------------------------------------
361//
362// Property Methods.
363//
364//-----------------------------------------------------------------------------
365
366Point3F VPathObject::getWorldPosition( void )
367{
368    return ( mPosition + mOffset );
369}
370
371Point3F VPathObject::getRenderWorldPosition( const F32 &pDelta )
372{
373    return ( getPositionDelta( pDelta ) + mOffset );
374}
375
376MatrixF VPathObject::getTransform( void )
377{
378    MatrixF mat( true );
379    switch ( mOrientationMode.Type )
380    {
381        case k_OrientationInterpolate :
382        case k_OrientationToObject :
383        case k_OrientationToPoint :
384        case k_OrientationToPath :
385            {
386                // Y-Axis.
387                VectorF yVec = mOrientation;
388                yVec.normalize();
389
390                // X-Axis.
391                VectorF xVec = mCross( yVec, VPath::gBezierUp );
392                xVec.normalize();
393
394                // Z-Axis.
395                VectorF zVec = mCross( xVec, yVec );
396                zVec.normalize();
397
398                // Setup Object Transform.
399                mat.setColumn( 0, xVec );
400                mat.setColumn( 1, yVec );
401                mat.setColumn( 2, zVec );
402                mat.setColumn( 3, getWorldPosition() );
403
404            } break;
405
406        case k_OrientationFree :
407            {
408                // Fetch Current Transform.
409                mat = mObject->getTransform();
410                mat.setPosition( getWorldPosition() );
411
412            } break;
413    }
414
415    // Return.
416    return mat;
417}
418
419MatrixF VPathObject::getRenderTransform( const F32 &pDelta )
420{
421    MatrixF mat( true );
422    switch ( mOrientationMode.Type )
423    {
424        case k_OrientationInterpolate :
425        case k_OrientationToObject :
426        case k_OrientationToPoint :
427        case k_OrientationToPath :
428            {
429                // Y-Axis.
430                VectorF yVec = getOrientationDelta( pDelta );
431                yVec.normalize();
432
433                // X-Axis.
434                VectorF xVec = mCross( yVec, VPath::gBezierUp );
435                xVec.normalize();
436
437                // Z-Axis.
438                VectorF zVec = mCross( xVec, yVec );
439                zVec.normalize();
440
441                // Setup Object Transform.
442                mat.setColumn( 0, xVec );
443                mat.setColumn( 1, yVec );
444                mat.setColumn( 2, zVec );
445                mat.setColumn( 3, getRenderWorldPosition( pDelta ) );
446
447            } break;
448
449        case k_OrientationFree :
450            {
451                // Fetch Current Transform.
452                mat = mObject->getRenderTransform();
453                mat.setPosition( getRenderWorldPosition( pDelta ) );
454
455            } break;
456    }
457
458    // Return.
459    return mat;
460}
461
462void VPathObject::setActive( const bool &pActive )
463{
464    // Update?
465    if ( pActive != mActive )
466    {
467        // Apply.
468        mActive = pActive;
469        // Flag Update.
470        setMaskBits( k_StateUpdatePosition );
471    }
472}
473
474void VPathObject::setObject( SceneObject *pObject )
475{
476    // Update?
477    if ( pObject != mObject )
478    {
479        // Apply.
480        mObject = pObject;
481        // Flag Update.
482        setMaskBits( k_StateUpdateObject );
483    }
484}
485
486void VPathObject::setTimeInterp( const F32 &pInterp )
487{
488    // Update?
489    if ( mTimeInterp != pInterp )
490    {
491        // Apply.
492        mTimeInterp = pInterp;
493        // Flag Update.
494        setMaskBits( k_StateUpdatePosition );
495    }
496}
497
498void VPathObject::setPathInterp( const F32 &pInterp )
499{
500    // Update?
501    if ( mPathInterp != pInterp )
502    {
503        // Apply.
504        mPathInterp = pInterp;
505        // Flag Update.
506        setMaskBits( k_StateUpdatePosition );
507    }
508}
509
510void VPathObject::setPosition( const Point3F &pPosition )
511{
512    // Update?
513    if ( mPosition != pPosition )
514    {
515        // Update.
516        mPosition = pPosition;
517        // Flag Update.
518        setMaskBits( k_StateUpdatePosition );
519    }
520}
521
522void VPathObject::setOffset( const Point3F &pOffset )
523{
524    // Update?
525    if ( mOffset != pOffset )
526    {
527        // Update.
528        mOffset = pOffset;
529        // Flag Update.
530        setMaskBits( k_StateUpdateState );
531    }
532}
533
534void VPathObject::setOrientation( const VectorF &pOrientation )
535{
536    // Update?
537    if ( mOrientation != pOrientation )
538    {
539        // Update.
540        mOrientation = pOrientation;
541        // Flag Update.
542        setMaskBits( k_StateUpdatePosition );
543    }
544}
545
546void VPathObject::setOrientationMode( const eOrientationType &pType )
547{
548    // Update?
549    if ( mOrientationMode.Type != pType )
550    {
551        // Update.
552        mOrientationMode.Type = pType;
553        // Flag Update.
554        setMaskBits( k_StateUpdateState );
555    }
556}
557
558void VPathObject::setOrientationMode( const eOrientationType &pType, SceneObject *pObject )
559{
560    AssertFatal( ( pType == k_OrientationToObject ) && ( pObject != NULL ), "VPathObject::setOrientationMode() - Invalid mOrientation Type." );
561
562    // Update?
563    if ( ( mOrientationMode.Type != pType ) || ( mOrientationMode.Object != pObject ) )
564    {
565        // Update.
566        mOrientationMode.Type   = pType;
567        mOrientationMode.Object = pObject;
568        // Flag Update.
569        setMaskBits( k_StateUpdateState );
570    }
571}
572
573void VPathObject::setOrientationMode( const eOrientationType &pType, const Point3F &pPoint )
574{
575    AssertFatal( pType == k_OrientationToPoint, "VPathObject::setOrientationMode() - Invalid mOrientation Type." );
576
577    // Update?
578    if ( ( mOrientationMode.Type != pType ) || ( mOrientationMode.Point != pPoint ) )
579    {
580        // Update.
581        mOrientationMode.Type  = pType;
582        mOrientationMode.Point = pPoint;
583        // Flag Update.
584        setMaskBits( k_StateUpdateState );
585    }
586}
587
588void VPathObject::setForward( const bool &pForward )
589{
590    // Update?
591    if ( mForward != pForward )
592    {
593        // Update.
594        mForward = pForward;
595        // Flag Update.
596        setMaskBits( k_StateUpdateState );
597    }
598}
599
600void VPathObject::setSpeed( const F32 &pSpeed )
601{
602    // Update?
603    if ( mSpeed != pSpeed )
604    {
605        // Update.
606        mSpeed = pSpeed;
607        // Flag Update.
608        setMaskBits( k_StateUpdateState );
609    }
610}
611
612void VPathObject::setNode( const S32 &pSourceNodeIndex, const S32 &pDestinationNodeIndex )
613{
614    // Update?
615    if ( ( mSourceNode != pSourceNodeIndex ) || ( mDestinationNode != pDestinationNodeIndex ) )
616    {
617        // Update.
618        mSourceNode      = pSourceNodeIndex;
619        mDestinationNode = pDestinationNodeIndex;
620        // Flag Update.
621        setMaskBits( k_StateUpdatePosition );
622    }
623}
624
625void VPathObject::setStartNode( const S32 &pNodeIndex )
626{
627    // Update?
628    if ( mStartNode != pNodeIndex )
629    {
630        // Update.
631        mStartNode = pNodeIndex;
632        // Flag Update.
633        setMaskBits( k_StateUpdateState );
634    }
635}
636
637void VPathObject::setEndNode( const S32 &pNodeIndex )
638{
639    // Update?
640    if ( mEndNode != pNodeIndex )
641    {
642        // Update.
643        mEndNode = pNodeIndex;
644        // Flag Update.
645        setMaskBits( k_StateUpdateState );
646    }
647}
648
649//-----------------------------------------------------------------------------
650//
651// Delta Methods.
652//
653//-----------------------------------------------------------------------------
654
655void VPathObject::resetDelta( void )
656{
657    mDelta.Position[0]    = mPosition;
658    mDelta.Position[1]    = mPosition;
659    mDelta.Orientation[0] = mOrientation;
660    mDelta.Orientation[1] = mOrientation;
661}
662
663void VPathObject::resetDelta( const Point3F &pPosition, const VectorF &pOrientation )
664{
665    mDelta.Position[0]    = pPosition;
666    mDelta.Position[1]    = pPosition;
667    mDelta.Orientation[0] = pOrientation;
668    mDelta.Orientation[1] = pOrientation;
669}
670
671void VPathObject::popDelta( void )
672{
673    mDelta.Position[0]    = mDelta.Position[1];
674    mDelta.Orientation[0] = mDelta.Orientation[1];
675}
676
677void VPathObject::pushDelta( const Point3F &pPosition, const VectorF &pOrientation )
678{
679    mDelta.Position[1]    = pPosition;
680    mDelta.Orientation[1] = pOrientation;
681}
682
683Point3F VPathObject::getPositionDelta( const F32 &pInterp )
684{
685    Point3F interpPosition;
686    interpPosition.interpolate( mDelta.Position[1], mDelta.Position[0], pInterp );
687
688    return interpPosition;
689}
690
691VectorF VPathObject::getOrientationDelta( const F32 &pInterp )
692{
693    VectorF interpOrientation;
694    interpOrientation.interpolate( mDelta.Orientation[1], mDelta.Orientation[0], pInterp );
695    interpOrientation.normalize();
696
697    return interpOrientation;
698}
699
700//-----------------------------------------------------------------------------
701//
702// Enumeration Methods.
703//
704//-----------------------------------------------------------------------------
705
706// Implement the Orientation Type enum list.
707ImplementEnumType( VPathObjectOrientationType, "" )
708    { VPathObject::k_OrientationFree,        "FREE"        },
709    { VPathObject::k_OrientationInterpolate, "INTERPOLATE" },
710    { VPathObject::k_OrientationToPath,      "TOPATH"      },
711    { VPathObject::k_OrientationToObject,    "TOOBJECT"    },
712    { VPathObject::k_OrientationToPoint,     "TOPOINT"     },
713EndImplementEnumType;
714
715VPathObject::eOrientationType VPathObject::getOrientationTypeEnum( const char *pLabel )
716{
717    VPathObject::eOrientationType out;
718    if ( !castConsoleTypeFromString( out, pLabel ) )
719    {
720        // Bah!
721        return VPathObject::k_OrientationFree;
722    }
723
724    // Return.
725    return out;
726}
727
728StringTableEntry VPathObject::getOrientationTypeLabel( const eOrientationType &pType )
729{
730    // Return.
731    return castConsoleTypeToString( pType );
732}
733