Ejemplo n.º 1
0
bool WaterObject::_setFullReflect( void *object, const char *index, const char *data )
{
   WaterObject *water = static_cast<WaterObject*>( object );
   water->mFullReflect = dAtob( data );
   
   if ( water->isProperlyAdded() && water->isClientObject() )
   {
      bool isEnabled = water->mPlaneReflector.isEnabled();

      bool enable = water->mFullReflect && !smDisableTrueReflections;

      if ( enable && !isEnabled )
         water->mPlaneReflector.registerReflector( water, &water->mReflectorDesc );
      else if ( !enable && isEnabled )
         water->mPlaneReflector.unregisterReflector();
   }

   return false;
}
bool Ned3DObjectManager::interactPlaneWater(PlaneObject &plane, WaterObject &water)
{
  Water *pWater = water.getWater();
  if(pWater == NULL) return false;
  
  // Test for plane collision with water
  
  Vector3 planePos = plane.getPosition();
  EulerAngles planeOrient = plane.getOrientation();
  Vector3 disp = planePos - disp;
  RotationMatrix planeMatrix;
  planeMatrix.setup(plane.getOrientation()); // get plane's orientation
  float planeBottom = plane.getBoundingBox().min.y;
  float waterHeight = pWater->getWaterHeight();
  
  if(plane.isPlaneAlive() && planeBottom < waterHeight)
  { //collision
    Vector3 viewVector = planeMatrix.objectToInertial(Vector3(0,0,1));
    plane.killPlane();
    plane.setSpeed(0.0f);
    planePos += 2.0f * viewVector;
    planeOrient.pitch = kPi / 4.0f;
    planeOrient.bank = kPi / 4.0f;
    plane.setOrientation(planeOrient);
    plane.setPPosition(planePos);
    
    int partHndl = gParticle.createSystem("planeexplosion");
    gParticle.setSystemPos(partHndl, plane.getPosition());
    int boomHndl = gSoundManager.requestSoundHandle("Boom.wav");
    int boomInst = gSoundManager.requestInstance(boomHndl);
    if(boomInst != SoundManager::NOINSTANCE)
    {
      gSoundManager.setPosition(boomHndl,boomInst,plane.getPosition());
      gSoundManager.play(boomHndl,boomInst);
      gSoundManager.releaseInstance(boomHndl,boomInst);
    }
    return true;
  }
  return false;
}
void waterFind( SceneObject *obj, void *key )
{     
   PROFILE_SCOPE( waterFind );

   // This is called for each WaterObject the ShapeBase object is overlapping.

   ContainerQueryInfo *info = static_cast<ContainerQueryInfo*>(key);
   WaterObject *water = dynamic_cast<WaterObject*>(obj);      
   AssertFatal( water != NULL, "containerQuery - waterFind(), passed object was not of class WaterObject!");      

   // Get point at the bottom/center of the box.
   Point3F testPnt = info->box.getCenter();
   testPnt.z = info->box.minExtents.z;

   F32 coverage = water->getWaterCoverage(info->box);

   // Since a WaterObject can have global bounds we may get this call
   // even though we have zero coverage.  If so we want to early out and
   // not save the water properties.
   if ( coverage == 0.0f )
      return;

   // Add in flow force.  Would be appropriate to try scaling it by coverage
   // thought. Or perhaps have getFlow do that internally and take
   // the box parameter.
   info->appliedForce += water->getFlow( testPnt );

   // Only save the following properties for the WaterObject with the
   // greatest water coverage for this ShapeBase object.
   if ( coverage < info->waterCoverage )
      return;
   
   info->waterCoverage = coverage;
   info->liquidType = water->getLiquidType();
   info->waterViscosity = water->getViscosity();
   info->waterDensity = water->getDensity();
   info->waterHeight = water->getSurfaceHeight( Point2F(testPnt.x,testPnt.y) );   
   info->waterObject = water;
}
Ejemplo n.º 4
0
//-----------------------------------------------------------------------------
//
// VActorPhysicsController::postTickUpdate( pDelta );
//
// ...
//
//-----------------------------------------------------------------------------
void VActorPhysicsController::postTickUpdate( const F32 &pDelta )
{
    switch( mControlState )
    {
    case k_PathControlState :
        {
            AssertFatal( isPathing(), "VActorPhysicsController::postTickUpdate() - Invalid Path State." );

            // Fetch Mount Transform.
            MatrixF transform;
            mMountedPath->getMountTransform( mObject->getMountNode(), getTransform(), &transform );
            // Fetch Mount Position.
            const Point3F &mountPosition = transform.getPosition();

            // Update X & Y Position.
            Point3F position = getPosition();
            position.x = mountPosition.x;
            position.y = mountPosition.y;

            // In Water?
            bool underWater = false;
            if ( isInWater() )
            {
                // Fetch Body of Water.
                WaterObject *waterBody = getWaterObject();

                // Fetch Surface Position.
                const F32 &waterSurfacePosition = waterBody->getSurfaceHeight( Point2F( position.x, position.y ) );
                // Fetch Submersion Position.
                const F32 sumbersionPosition = waterSurfacePosition - ( mObject->getWorldBox().len_z() * mObject->getDataBlock()->getSumbergeCoverage() );

                // Choose a Z Value.
                // Note: This is done so that the Actor will either path under the
                //       water, or it will swim along the water's surface.
                position.z = getMin( mountPosition.z, sumbersionPosition );

                // Under Water?
                underWater = ( position.z < sumbersionPosition );
            }

            // Under Water?
            if ( !underWater )
            {
                // Fetch Y Column.
                VectorF forwardVector;
                transform.getColumn( 1, &forwardVector );

                // Determine Angle.
                const F32 &angle = -mAtan2( -forwardVector.x, forwardVector.y );

                // Reset Transform.
                transform.set( EulerF( 0.f, 0.f, angle ) );

                // In the air?
                if ( !isOnGround() )
                {
                    // Apply z-axis force.
                    position.z += ( getVelocity().z * pDelta );
                }
            }

            // Update Transform.
            transform.setPosition( position );

            // Apply Update.
            setTransform( transform );

        } break;

    default :
        {
            // Fetch Transform.
            MatrixF transform = getTransform();

            // Determine the Post-Tick Position.
            Point3F postTickPosition = getPosition() + ( getVelocity() * pDelta );
            // Set the Post Tick Position.
            transform.setPosition( postTickPosition );

            // Apply the Transform.
            setTransform( transform );

        } break;
    }

    // Push Delta.
    mInterpController.pushDelta( getTransform() );
}