Beispiel #1
0
void Etherform::findContact(VectorF *contactNormal)
{
   SceneObject *contactObject = NULL;

   Vector<SceneObject*> overlapObjects;
   _findContact(&contactObject, contactNormal, &overlapObjects );

   // Check for triggers, corpses and items.
   const U32 filterMask = isGhost() ? sClientCollisionContactMask : sServerCollisionContactMask;
   for ( U32 i=0; i < overlapObjects.size(); i++ )
   {
      SceneObject *obj = overlapObjects[i];
      U32 objectMask = obj->getTypeMask();

      if ( !( objectMask & filterMask ) )
         continue;

      // Check: triggers, tactical zones, corpses and items...
      //
      if (objectMask & TriggerObjectType)
      {
         Trigger* pTrigger = static_cast<Trigger*>( obj );
         pTrigger->potentialEnterObject(this);
      }
      else if (objectMask & TacticalZoneObjectType)
      {
         TacticalZone* pZone = static_cast<TacticalZone*>( obj );
         pZone->potentialEnterObject(this);
      }
      else if (objectMask & CorpseObjectType)
      {
         // If we've overlapped the worldbounding boxes, then that's it...
         if ( getWorldBox().isOverlapped( obj->getWorldBox() ) )
         {
            ShapeBase* col = static_cast<ShapeBase*>( obj );
            queueCollision(col,getVelocity() - col->getVelocity());
         }
      }
      else if (objectMask & ItemObjectType)
      {
         // If we've overlapped the worldbounding boxes, then that's it...
         Item* item = static_cast<Item*>( obj );
         if (  getWorldBox().isOverlapped(item->getWorldBox()) &&
               item->getCollisionObject() != this && 
               !item->isHidden() )
            queueCollision(item,getVelocity() - item->getVelocity());
      }
   }

   mContactInfo.clear();
   mContactInfo.contacted = contactObject != NULL;
   mContactInfo.contactObject = contactObject;

   if(mContactInfo.contacted)
      mContactInfo.contactNormal = *contactNormal;
}
Beispiel #2
0
void NavPath::renderSimple(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat)
{
   if(overrideMat)
      return;

   if(state->isReflectPass() || !(isSelected() || mAlwaysRender))
      return;

   GFXDrawUtil *drawer = GFX->getDrawUtil();
   GFXStateBlockDesc desc;
   desc.setZReadWrite(true, false);
   desc.setBlend(true);
   desc.setCullMode(GFXCullNone);

   if(isSelected())
   {
      drawer->drawCube(desc, getWorldBox(), ColorI(136, 255, 228, 5));
      desc.setFillModeWireframe();
      drawer->drawCube(desc, getWorldBox(), ColorI::BLACK);
   }

   desc.setZReadWrite(!mXray, false);

   ColorI pathColour(255, 0, 255);

   if(!mIsLooping)
   {
      desc.setFillModeSolid();
      if(mFromSet) drawer->drawCube(desc, Point3F(0.2f, 0.2f, 0.2f), mFrom, pathColour);
      if(mToSet)   drawer->drawCube(desc, Point3F(0.2f, 0.2f, 0.2f), mTo, pathColour);
   }

   GFXStateBlockRef sb = GFX->createStateBlock(desc);
   GFX->setStateBlock(sb);

   PrimBuild::color3i(pathColour.red, pathColour.green, pathColour.blue);

   PrimBuild::begin(GFXLineStrip, mPoints.size());
   for (U32 i = 0; i < mPoints.size(); i++)
      PrimBuild::vertex3fv(mPoints[i]);
   PrimBuild::end();

   if(mRenderSearch && getServerObject())
   {
      NavPath *np = static_cast<NavPath*>(getServerObject());
      if(np->mQuery && !dtStatusSucceed(np->mStatus))
      {
         duDebugDrawTorque dd;
         dd.overrideColor(duRGBA(250, 20, 20, 255));
         duDebugDrawNavMeshNodes(&dd, *np->mQuery);
         dd.render();
      }
   }
}
Beispiel #3
0
   void NavMesh::render(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat)
   {
      if(overrideMat)
         return;

      if(state->isReflectPass())
         return;

      PROFILE_SCOPE(NavMesh_Render);

      GFXDrawUtil *drawer = GFX->getDrawUtil();

      GFXStateBlockDesc desc;
      desc.setZReadWrite(true, false);
      desc.setBlend(true);
      desc.setCullMode(GFXCullNone);

      drawer->drawCube(desc, getWorldBox(), ColorI(136, 255, 228, 45));
      desc.setFillModeWireframe();
      drawer->drawCube(desc, getWorldBox(), ColorI::BLACK);

      // Recast debug draw
      duDebugDrawTorque dd;
      NetObject *no = getServerObject();
      if(no && isSelected())
      {
         NavMesh *n = static_cast<NavMesh*>(no);
         RenderMode mode = mRenderMode;
         bool build = n->mBuilding;
         if(build)
         {
            mode = RENDER_NAVMESH;
            dd.overrideColour(duRGBA(255, 0, 0, 80));
         }
         n->mNavMeshLock.lock();
         switch(mode)
         {
         case RENDER_NAVMESH:    if(n->nm) duDebugDrawNavMesh          (&dd, *n->nm, 0); break;
         case RENDER_CONTOURS:   if(n->cs) duDebugDrawContours         (&dd, *n->cs); break;
         case RENDER_POLYMESH:   if(n->pm) duDebugDrawPolyMesh         (&dd, *n->pm); break;
         case RENDER_DETAILMESH: if(n->pmd) duDebugDrawPolyMeshDetail  (&dd, *n->pmd); break;
         case RENDER_PORTALS:    if(n->nm) duDebugDrawNavMeshPortals   (&dd, *n->nm); break;
         }
         if(n->cs && mRenderConnections && !build)   duDebugDrawRegionConnections(&dd, *n->cs);
         if(n->mInPolys && mRenderInput && !build)   n->mInPolys->render();
         n->mNavMeshLock.unlock();
      }
   }
void Mortar::fire() {
	//Only fire if a soldier to occupying the mortar
	if (occupied) {
		// See if time to fire.
		if (fire_countdown > 0)
			return;

		//Reset countdown
		fire_countdown = fire_slowdown + (int)(rand() % 10);

		//Check if player is in range
		int y_offset = player->getPosition().getY() - getPosition().getY();

		if (y_offset > 0 && boxIntersectsBox(getWorldBox(this), df::WorldManager::getInstance().getView())) {
			// Fire bomb on player
			EnemyBombShot *p = new EnemyBombShot(player->getPosition());

			//Reset countdown
			firing_anim_countdown = firing_anim_slowdown;
			firing = true;

			// Play "fire" sound.
		}
	}
}
void FootSoldier::fire() {
	// See if time to fire.
	if (fire_countdown > 0)
		return;

	//Reset countdown
	fire_countdown = fire_slowdown;

	//Check if player is in range
	int y_offset = player->getPosition().getY() - getPosition().getY();

	if (y_offset < df::GraphicsManager::getInstance().getVertical() * 3 / 4 && y_offset > 0 &&
		boxIntersectsBox(getWorldBox(this), df::WorldManager::getInstance().getView())) {
		// Fire Bullet towards target.
		df::Position pos;
		if (player->getPosition().getX() > getPosition().getX())
			pos = df::Position::Position(getPosition().getX() + 2, getPosition().getY());
		else
			pos = df::Position::Position(getPosition().getX() - 2, getPosition().getY());
		EnemyGunShot *p = new EnemyGunShot(pos);
		p->setXVelocity((float)(player->getPosition().getX() - pos.getX()) /
			(float)(player->getPosition().getY() - pos.getY()));

		// Play "fire" sound.
	}
}
void VehicleBlocker::buildConvex(const Box3F& box, Convex* convex)
{
   // These should really come out of a pool
   mConvexList->collectGarbage();

   if (box.isOverlapped(getWorldBox()) == false)
      return;

   // Just return a box convex for the entire shape...
   Convex* cc = 0;
   CollisionWorkingList& wl = convex->getWorkingList();
   for (CollisionWorkingList* itr = wl.wLink.mNext; itr != &wl; itr = itr->wLink.mNext) 
   {
      if (itr->mConvex->getType() == BoxConvexType &&
          itr->mConvex->getObject() == this) {
         cc = itr->mConvex;
         break;
      }
   }
   if (cc)
      return;

   // Create a new convex.
   BoxConvex* cp = new BoxConvex;
   mConvexList->registerObject(cp);
   convex->addToWorkingList(cp);
   cp->init(this);

   mObjBox.getCenter(&cp->mCenter);
   cp->mSize.x = mObjBox.len_x() / 2.0f;
   cp->mSize.y = mObjBox.len_y() / 2.0f;
   cp->mSize.z = mObjBox.len_z() / 2.0f;
}
Beispiel #7
0
//.logicking >>
void StaticShape::updatePhysics()
{
	SAFE_DELETE(mPhysicsRep);
	if ( PHYSICSMGR)
	{
		mShapeInstance->animate();

		// Get the interior collision geometry.
		ConcretePolyList polylist;
		if (buildPolyList(PLC_Collision, &polylist, getWorldBox(), getWorldSphere()))
		{
			polylist.triangulate();

			PhysicsCollision *colShape = PHYSICSMGR->createCollision();
			colShape->addTriangleMesh( polylist.mVertexList.address(), 
				polylist.mVertexList.size(),
				polylist.mIndexList.address(),
				polylist.mIndexList.size() / 3,
				MatrixF::Identity );

			PhysicsWorld *world = PHYSICSMGR->getWorld( isServerObject() ? "server" : "client" );
			mPhysicsRep = PHYSICSMGR->createBody();
			//.hack - set kinematic flag to prevent crash on deleting static shape in character sweep(deleting Doors)
			mPhysicsRep->init( colShape, 0, PhysicsBody::BF_KINEMATIC, this, world );
		}
		if (isServerObject())
			setMaskBits(PhysicsMask);
	}
}
void EnemyTank::fire() {

    // See if time to fire.
    if (fire_countdown > 0)
        return;

    //Reset countdown
    fire_countdown = fire_slowdown;

    //Check if player is in range
    int y_offset = player->getPosition().getY() - getPosition().getY();
    int x_offset = player->getPosition().getX() - getPosition().getX();

    if (y_offset < df::GraphicsManager::getInstance().getVertical() * 3 / 4 && y_offset > 0 &&
            boxIntersectsBox(getWorldBox(this), df::WorldManager::getInstance().getView()) &&
            abs(x_offset) < 4) {
        // Fire Cannon
        EnemyCannonShot *p = new EnemyCannonShot(df::Position(getPosition().getX(), getPosition().getY() + 6));

        // Play "cannonFire" sound.
        df::Sound *p_sound = df::ResourceManager::getInstance().getSound("cannon-shot");
        p_sound->play();
    }
}
Beispiel #9
0
void DecalRoad::unpackUpdate( NetConnection *con, BitStream *stream )
{
   // Unpack Parent.
   Parent::unpackUpdate( con, stream );

   // DecalRoadMask
   if ( stream->readFlag() )
   {
      String matName;
      stream->read( &matName );
      
      if ( matName != mMaterialName )
      {
         mMaterialName = matName;
         Material *pMat = NULL;
         if ( !Sim::findObject( mMaterialName, pMat ) )
         {
            Con::printf( "DecalRoad::unpackUpdate, failed to find Material of name %s!", mMaterialName.c_str() );
         }
         else
         {
            mMaterial = pMat;
            if ( isProperlyAdded() )
               _initMaterial(); 
         }
      }

      stream->read( &mBreakAngle );    

      stream->read( &mSegmentsPerBatch );

      stream->read( &mTextureLength );

      stream->read( &mRenderPriority );
   }

   // NodeMask
   if ( stream->readFlag() )
   {
      //U32 count = stream->readInt( 16 );

      //mNodes.clear();

      //Point3F pos;
      //F32 width;
      //for ( U32 i = 0; i < count; i++ )
      //{
      //   mathRead( *stream, &pos );
      //   stream->read( &width );         
      //   _addNode( pos, width );         
      //}

      if (stream->readFlag())
      {
         // Nodes have been passed in this update
         U32 count = stream->readInt( 16 );

         mNodes.clear();

         Point3F pos;
         F32 width;
         for ( U32 i = 0; i < count; i++ )
         {
            mathRead( *stream, &pos );
            stream->read( &width );         
            _addNode( pos, width );         
         }
      }
      else
      {
         // Nodes will arrive as events
         U32 id;
         stream->read( &id );

         // Check if the road's nodes made it here before we did.
         NodeListManager::NodeList* list = NULL;
         if ( gClientNodeListManager->findListById( id, &list, true) )
         {
            // Work with the completed list
            DecalRoadNodeList* roadList = dynamic_cast<DecalRoadNodeList*>( list );
            if (roadList)
               buildNodesFromList( roadList );

            delete list;
         }
         else
         {
            // Nodes have not yet arrived, so register our interest in the list
            DecalRoadNodeListNotify* notify = new DecalRoadNodeListNotify( this, id );
            gClientNodeListManager->registerNotification( notify );
         }
      }
   }

    // GenEdgesMask
   if ( stream->readFlag() && isProperlyAdded() )
      _generateEdges();

   // ReClipMask
   if ( stream->readFlag() && isProperlyAdded() )
      _captureVerts();

   // TerrainChangedMask
   if ( stream->readFlag() )
   {      
      if ( isProperlyAdded() )
      {
         if ( mTerrainUpdateRect.isOverlapped( getWorldBox() ) )
         {
            _generateEdges();
            _captureVerts();
            // Clear out the mTerrainUpdateRect since we have updated its
            // region and we now need to store future terrain changes
            // in it.
            mTerrainUpdateRect = Box3F::Invalid;
         }         
      }      
   }
}
F32 GameBase::getUpdatePriority(CameraScopeQuery *camInfo, U32 updateMask, S32 updateSkips)
{
   TORQUE_UNUSED(updateMask);

   // Calculate a priority used to decide if this object
   // will be updated on the client.  All the weights
   // are calculated 0 -> 1  Then weighted together at the
   // end to produce a priority.
   Point3F pos;
   getWorldBox().getCenter(&pos);
   pos -= camInfo->pos;
   F32 dist = pos.len();
   if (dist == 0.0f) dist = 0.001f;
   pos *= 1.0f / dist;

   // Weight based on linear distance, the basic stuff.
   F32 wDistance = (dist < camInfo->visibleDistance)?
      1.0f - (dist / camInfo->visibleDistance): 0.0f;

   // Weight by field of view, objects directly in front
   // will be weighted 1, objects behind will be 0
   F32 dot = mDot(pos,camInfo->orientation);
   //Winterleaf Modification
   //bool inFov = dot > camInfo->cosFov;
   bool inFov = dot > (cos(  (camInfo->fov + 40) >360?360:camInfo->fov + 40)/2);  
   //Winterleaf Modification


   F32 wFov = inFov? 1.0f: 0;

   // Weight by linear velocity parallel to the viewing plane
   // (if it's the field of view, 0 if it's not).
   F32 wVelocity = 0.0f;
   if (inFov)
   {
      Point3F vec;
      mCross(camInfo->orientation,getVelocity(),&vec);
      wVelocity = (vec.len() * camInfo->fov) /
         (camInfo->fov * camInfo->visibleDistance);
      if (wVelocity > 1.0f)
         wVelocity = 1.0f;
   }

   // Weight by interest.
   F32 wInterest;
   if (getTypeMask() & PlayerObjectType)
      wInterest = 0.75f;
   else if (getTypeMask() & ProjectileObjectType)
   {
      // Projectiles are more interesting if they
      // are heading for us.
      wInterest = 0.30f;
      F32 dot = -mDot(pos,getVelocity());
      if (dot > 0.0f)
         wInterest += 0.20 * dot;
   }
   else
   {
      if (getTypeMask() & ItemObjectType)
         wInterest = 0.25f;
      else
         // Everything else is less interesting.
         wInterest = 0.0f;
   }

   // Weight by updateSkips
   F32 wSkips = updateSkips * 0.5;

   // Calculate final priority, should total to about 1.0f
   //
   return
      wFov       * sUpFov +
      wDistance  * sUpDistance +
      wVelocity  * sUpVelocity +
      wSkips     * sUpSkips +
      wInterest  * sUpInterest;
}
void PxSingleActor::_updateContainerForces()
{   
   if ( !mWorld->getEnabled() )
      return;

   PROFILE_SCOPE( PxSingleActor_updateContainerForces );

   // Update container drag and buoyancy properties      

   ContainerQueryInfo info;
   info.box = getWorldBox();
   info.mass = getMass();

   // Find and retreive physics info from intersecting WaterObject(s)
   mContainer->findObjects( getWorldBox(), WaterObjectType|PhysicalZoneObjectType, findRouter, &info );
   
   // Calculate buoyancy and drag
   F32 angDrag = mBuildAngDrag;
   F32 linDrag = mBuildLinDrag;
   F32 buoyancy = 0.0f;

   if ( true ) //info.waterCoverage >= 0.1f) 
   {
      F32 waterDragScale = info.waterViscosity * mDataBlock->waterDragScale;
      F32 powCoverage = mPow( info.waterCoverage, 0.25f );

      if ( info.waterCoverage > 0.0f )
      {
         //angDrag = mBuildAngDrag * waterDragScale;
         //linDrag = mBuildLinDrag * waterDragScale;
         angDrag = mLerp( mBuildAngDrag, mBuildAngDrag * waterDragScale, powCoverage );
         linDrag = mLerp( mBuildLinDrag, mBuildLinDrag * waterDragScale, powCoverage );
      }

      buoyancy = ( info.waterDensity / mDataBlock->buoyancyDensity ) * mPow( info.waterCoverage, 2.0f );
   }

   // Apply drag (dampening)
   mActor->setLinearDamping( linDrag );
   mActor->setAngularDamping( angDrag );   

   // Apply buoyancy force
   if ( buoyancy != 0 )
   {     
      // A little hackery to prevent oscillation
      // Based on this blog post (http://reinot.blogspot.com/2005/11/oh-yes-they-float-georgie-they-all.html)
      // JCF: DISABLED
      NxVec3 gravity;
      mWorld->getScene()->getGravity(gravity);
      //NxVec3 velocity = mActor->getLinearVelocity();

      NxVec3 buoyancyForce = buoyancy * -gravity * TickSec;
      //F32 currHeight = getPosition().z;
      //const F32 C = 2.0f;
      //const F32 M = 0.1f;

      //if ( currHeight + velocity.z * TickSec * C > info.waterHeight )
      //   buoyancyForce *= M;

      mActor->addForceAtPos( buoyancyForce, mActor->getCMassGlobalPosition(), NX_IMPULSE );
   }

   // Apply physical zone forces
   if ( info.appliedForce.len() > 0.001f )
      mActor->addForceAtPos( pxCast<NxVec3>(info.appliedForce), mActor->getCMassGlobalPosition(), NX_IMPULSE );
}
Beispiel #12
0
   bool NavMesh::generateMesh()
   {
      // Parse objects from level into RC-compatible format
      NavModelData data = NavMeshLoader::mergeModels(
         NavMeshLoader::parseTerrainData(getWorldBox(), 0),
         NavMeshLoader::parseStaticObjects(getWorldBox()),
         true);

      // Check for no geometry
      if(!data.getVertCount())
         return false;

      // Free intermediate and final results
      freeIntermediates(true);

      // Create mInPolys if we don't have one already
      if(!mInPolys && mSaveIntermediates)
         mInPolys = new ConcretePolyList();

      // Reconstruct input geometry from out data
      if(mSaveIntermediates)
         RCtoPolyList(&data, mInPolys);

      // Recast initialisation data
      rcContext ctx(false);
      rcConfig cfg;

      dMemset(&cfg, 0, sizeof(cfg));
      cfg.cs = mCellSize;
      cfg.ch = mCellHeight;
      rcCalcBounds(data.verts, data.getVertCount(), cfg.bmin, cfg.bmax);
      rcCalcGridSize(cfg.bmin, cfg.bmax, cfg.cs, &cfg.width, &cfg.height);
      cfg.walkableHeight = mCeil(mWalkableHeight / mCellHeight);
      cfg.walkableClimb = mCeil(mWalkableClimb / mCellHeight);
      cfg.walkableRadius = mCeil(mWalkableRadius / mCellSize);
      cfg.walkableSlopeAngle = mWalkableSlope;
      cfg.borderSize = mBorderSize;
      cfg.detailSampleDist = mDetailSampleDist;
      cfg.detailSampleMaxError = mDetailSampleMaxError;
      cfg.maxEdgeLen = mMaxEdgeLen;
      cfg.maxSimplificationError = mMaxSimplificationError;
      cfg.maxVertsPerPoly = 3;
      cfg.minRegionArea = mMinRegionArea;
      cfg.mergeRegionArea = mMergeRegionArea;
      cfg.tileSize = mTileSize;

      if(!createPolyMesh(cfg, data, &ctx))
         return false;

      //Detour initialisation data
      dtNavMeshCreateParams params;
      dMemset(&params, 0, sizeof(params));

      params.walkableHeight = cfg.walkableHeight;
      params.walkableRadius = cfg.walkableRadius;
      params.walkableClimb = cfg.walkableClimb;
      params.tileX = 0;
      params.tileY = 0;
      params.tileLayer = 0;
      rcVcopy(params.bmax, cfg.bmax);
      rcVcopy(params.bmin, cfg.bmin);
      params.buildBvTree = true;
      params.ch = cfg.ch;
      params.cs = cfg.cs;

      params.verts = pm->verts;
      params.vertCount = pm->nverts;
      params.polys = pm->polys;
      params.polyAreas = pm->areas;
      params.polyFlags = pm->flags;
      params.polyCount = pm->npolys;
      params.nvp = pm->nvp;

      params.detailMeshes = pmd->meshes;
      params.detailVerts = pmd->verts;
      params.detailVertsCount = pmd->nverts;
      params.detailTris = pmd->tris;
      params.detailTriCount = pmd->ntris;

      if(!createNavMesh(params))
         return false;

      return true;
   }
Beispiel #13
0
void DecalRoad::unpackUpdate( NetConnection *con, BitStream *stream )
{
   // Unpack Parent.
   Parent::unpackUpdate( con, stream );

   // NodeMask
   if ( stream->readFlag() )
   {
      U32 count = stream->readInt( 16 );

      mNodes.clear();

      Point3F pos;
      F32 width;
      for ( U32 i = 0; i < count; i++ )
      {
         mathRead( *stream, &pos );
         stream->read( &width );         
         _addNode( pos, width );         
      }
   }

   // DecalRoadMask
   if ( stream->readFlag() )
   {
      String matName;
      stream->read( &matName );
      
      if ( matName != mMaterialName )
      {
         mMaterialName = matName;
         Material *pMat = NULL;
         if ( !Sim::findObject( mMaterialName, pMat ) )
         {
            Con::printf( "DecalRoad::unpackUpdate, failed to find Material of name %s!", mMaterialName.c_str() );
         }
         else
         {
            mMaterial = pMat;
            if ( isProperlyAdded() )
               _initMaterial(); 
         }
      }

      stream->read( &mBreakAngle );    

      stream->read( &mSegmentsPerBatch );

      stream->read( &mTextureLength );

      stream->read( &mRenderPriority );
   }

    // GenEdgesMask
   if ( stream->readFlag() && isProperlyAdded() )
      _generateEdges();

   // ReClipMask
   if ( stream->readFlag() && isProperlyAdded() )
      _captureVerts();

   // TerrainChangedMask
   if ( stream->readFlag() )
   {      
      if ( isProperlyAdded() )
      {
         if ( mTerrainUpdateRect.isOverlapped( getWorldBox() ) )
         {
            _generateEdges();
            _captureVerts();
            // Clear out the mTerrainUpdateRect since we have updated its
            // region and we now need to store future terrain changes
            // in it.
            mTerrainUpdateRect = Box3F::Invalid;
         }         
      }      
   }
}