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; }
//----------------------------------------------------------------------------- // // 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() ); }