예제 #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;
}
void collisionFilter(SceneObject* object,void *key)
{
   SceneContainer::CallbackInfo* info = reinterpret_cast<SceneContainer::CallbackInfo*>(key);
   ShapeBase* ptr = reinterpret_cast<ShapeBase*>(info->key);

   if (object->getTypeMask() & ItemObjectType) {
      // We've hit it's bounding box, that's close enough for items.
      Item* item = static_cast<Item*>(object);
      if (ptr != item->getCollisionObject())
         ptr->queueCollision(item,ptr->getVelocity() - item->getVelocity());
   }
   else
      if (object->getTypeMask() & TriggerObjectType) {
         // We've hit it's bounding box, that's close enough for triggers
         Trigger* pTrigger = static_cast<Trigger*>(object);
         pTrigger->potentialEnterObject(ptr);
      }
      else
         if (object->getTypeMask() & CorpseObjectType)  {
            // Ok, guess it's close enough for corpses too...
            ShapeBase* col = static_cast<ShapeBase*>(object);
            ptr->queueCollision(col,ptr->getVelocity() - col->getVelocity());
         }
         else
            object->buildPolyList(info->context,info->polyList,info->boundingBox,info->boundingSphere);
}
void SFX3DObject::getEarTransform( MatrixF& transform ) const
{
   // If it's not a ShapeBase, just use the object transform.   
   ShapeBase* shape = dynamic_cast< ShapeBase* >( mObject );
   if ( !shape )
   {
      transform = mObject->getTransform();
      return;
   }

   // It it's ShapeBase, use the earNode transform if one was defined.
   // Otherwise, use the camera transform.
   TSShapeInstance* shapeInstance = shape->getShapeInstance();
   if ( !shapeInstance )
   {
      // Just in case.
      transform = mObject->getTransform();
      return;
   }

   ShapeBaseData* datablock = dynamic_cast< ShapeBaseData* >( shape->getDataBlock() );
   AssertFatal( datablock, "SFX3DObject::getEarTransform() - shape without ShapeBaseData datablock!" );
   
   // Get the transform for the ear node.
       
   const S32 earNode = datablock->earNode;

   if ( earNode != -1 && earNode != datablock->eyeNode )
   {
      transform = shape->getTransform();
      transform *= shapeInstance->mNodeTransforms[ earNode ];
   }
   else
   {
      GameConnection* connection = dynamic_cast<GameConnection *>(NetConnection::getConnectionToServer());
      if ( !connection || !connection->getControlCameraTransform( 0.0f, &transform ) )
         transform = mObject->getTransform();
   }
}
예제 #4
0
void FishWave::addFish(){
    fishPos = polyline.getPointAtPercent(ofRandom(0, 1));
    fishes.clear();
    shapes.clear();
    particle myParticle;
    myParticle.setInitialCondition(fishPos.x, fishPos.y, 0, ofRandom(-0.7, -0.8));
    fishGravity = ofRandom(-3, -0.8);
    fishDirection = ofRandom(-0.7, 0.7);
    myParticle.radius = ofRandom(20, 30);
    fishes.push_back(myParticle);
    
    ofPath p;
    float  scale = 100;
    float angle = 0;
    float r = ofRandom(30, 60);
    
    int index = (int)ofRandom(shapeTypes.size());
    ShapeType t = shapeTypes[index];
    ShapeBase* s = ShapeFactory(t);
    s->setColor(baseColor);
    s->setup();
    shapes.push_back(s);
}
예제 #5
0
// Used to build potential target list
static void _scanCallback( SceneObject* object, void* data )
{
   AITurretShape* turret = (AITurretShape*)data;

   ShapeBase* shape = dynamic_cast<ShapeBase*>(object);
   if (shape && shape->getDamageState() == ShapeBase::Enabled)
   {
      Point3F targetPos = shape->getBoxCenter();

      // Put target position into the scan node's space
      turret->mScanWorkspaceScanWorldMat.mulP(targetPos);

      // Is the target within scanning distance
      if (targetPos.lenSquared() > turret->getMaxScanDistanceSquared())
         return;

      // Make sure the target is in front and within the maximum
      // heading range
      Point2F targetXY(targetPos.x, targetPos.y);
      targetXY.normalizeSafe();
      F32 headingDot = mDot(Point2F(0, 1), targetXY);
      F32 heading = mAcos(headingDot);
      if (headingDot < 0 || heading > turret->getMaxScanHeading())
         return;

      // Make sure the target is in front and within the maximum
      // pitch range
      Point2F targetZY(targetPos.z, targetPos.y);
      targetZY.normalizeSafe();
      F32 pitchDot = mDot(Point2F(0, 1), targetZY);
      F32 pitch = mAcos(pitchDot);
      if (pitchDot < 0 || pitch > turret->getMaxScanPitch())
         return;

      turret->addPotentialTarget(shape);
   }
}
예제 #6
0
void AITurretShape::_performScan()
{
   // Only on server
   if (isClientObject())
      return;

   // Are we ready for a scan?
   --mTicksToNextScan;
   if (mTicksToNextScan > 0)
      return;

   _cleanupPotentialTargets();

   _setScanBox();

   // Set up for the scan
   getScanTransform(mScanWorkspaceScanMat);
   mScanWorkspaceScanWorldMat = mScanWorkspaceScanMat;
   mScanWorkspaceScanWorldMat.affineInverse();

   disableCollision();
   for ( SimSetIterator iter(&mIgnoreObjects); *iter; ++iter )
   {
      ShapeBase* obj = static_cast<ShapeBase*>( *iter );
      obj->disableCollision();
   }

   gServerContainer.findObjects( mTransformedScanBox, sScanTypeMask, _scanCallback, (void*)this );

   for ( SimSetIterator iter(&mIgnoreObjects); *iter; ++iter )
   {
      ShapeBase* obj = static_cast<ShapeBase*>( *iter );
      obj->enableCollision();
   }
   enableCollision();

   if (mPotentialTargets.size() == 0)
   {
      // No targets in range.  Clear out our current target, if necessary.
      _lostTarget();
   }
   else
   {
      // Sort the targets
      comparePoint = getPosition();
      dQsort(mPotentialTargets.address(),mPotentialTargets.size(),sizeof(SimObjectList::value_type),_sortCallback);

      // Go through the targets in order to find one that is not blocked from view
      Point3F start;
      mScanWorkspaceScanMat.getColumn(3, &start);
      S32 index = 0;
      bool los = false;

      disableCollision();
      for (index=0; index < mPotentialTargets.size(); ++index)
      {
         ShapeBase* shape = (ShapeBase*)mPotentialTargets[index];

         Point3F sightPoint;
         los = _testTargetLineOfSight(start, shape, sightPoint);

         // Check if we have a clear line of sight
         if (los)
            break;
      }
      enableCollision();

      // If we found a valid, visible target (no hits between here and there), latch on to it
      if (los)
      {
         _gainedTarget((ShapeBase*)mPotentialTargets[index]);
      }
   }

   // Prepare for next scan period
   mTicksToNextScan = mScanTickFrequency;
   if (mScanTickFrequencyVariance > 0)
   {
      mTicksToNextScan += gRandGen.randI(0, mScanTickFrequencyVariance);
   }
}
예제 #7
0
void SimpleDeferredDemo::render()
{
    if( m_firstFrame )
    {
        for(int i=0; i<MAX_BODIES; i++)
        {
            const float4& pos = m_pos[i];
            const Quaternion& quat = qtGetIdentity();

            ShapeBase* boxShape = m_shapes[i];

            const float4* vtx = boxShape->getVertexBuffer();
            const int4* tris = boxShape->getTriangleBuffer();

            float4* v = new float4[boxShape->getNumTris()*3];
            u32* idx = new u32[boxShape->getNumTris()*3];
            float4* n = new float4[boxShape->getNumTris()*3];

            const float4 colors[] = { make_float4(0,1,1,1), make_float4(1,0,1,1), make_float4(1,1,0,1),
                                      make_float4(0,0,1,1), make_float4(0,1,0,1), make_float4(1,0,0,1)
                                    };

            float c = 0.4f;
            float4 color = make_float4(0.8f-c,0.8f-c,0.8f,1.f)*1.8f;
            color = make_float4(0.5f,1,0.5f,1);

            if( i==0 ) color = make_float4(1.f,1.f,1.f, 1.f);

            for(int it=0; it<boxShape->getNumTris(); it++)
            {
                const int4& t = tris[it];

                idx[3*it+0] = it*3;
                idx[3*it+1] = it*3+1;
                idx[3*it+2] = it*3+2;

                v[3*it+0] = vtx[t.x];
                v[3*it+1] = vtx[t.y];
                v[3*it+2] = vtx[t.z];
                if( i==0 ) swap2(v[3*it+1], v[3*it+2]);

                float4 tn = cross3( v[3*it+1] - v[3*it+0], v[3*it+2] - v[3*it+0] );

                tn = normalize3( tn );
                n[3*it+0] = tn;
                n[3*it+1] = tn;
                n[3*it+2] = tn;
            }

            int nTris = boxShape->getNumTris();
            int nVtx = boxShape->getNumVertex();


//		pxReleaseDrawTriangleListTransformed( v, n, idx, nTris*3, nTris*3, color, pos, quat );
            pxDrawTriangleListTransformed( v, n, idx, nTris*3, nTris*3, color, pos, quat );

            delete [] v;
            delete [] idx;
            delete [] n;
        }
//	m_firstFrame = false;
    }
}
예제 #8
0
파일: item.cpp 프로젝트: Bloodknight/GMK
void Item::updatePos(const U32 /*mask*/, const F32 dt)
{
   // Try and move
   Point3F pos;
   mObjToWorld.getColumn(3,&pos);
   delta.posVec = pos;

   bool contact = false;
   bool nonStatic = false;
   bool stickyNotify = false;
   CollisionList collisionList;
   F32 time = dt;

   static Polyhedron sBoxPolyhedron;
   static ExtrudedPolyList sExtrudedPolyList;
   static EarlyOutPolyList sEarlyOutPolyList;
   MatrixF collisionMatrix(true);
   Point3F end = pos + mVelocity * time;
   U32 mask = isServerObject() ? sServerCollisionMask : sClientCollisionMask;

   // Part of our speed problem here is that we don't track contact surfaces, like we do
   //  with the player.  In order to handle the most common and performance impacting
   //  instance of this problem, we'll use a ray cast to detect any contact surfaces below
   //  us.  This won't be perfect, but it only needs to catch a few of these to make a
   //  big difference.  We'll cast from the top center of the bounding box at the tick's
   //  beginning to the bottom center of the box at the end.
   Point3F startCast((mObjBox.minExtents.x + mObjBox.maxExtents.x) * 0.5,
                     (mObjBox.minExtents.y + mObjBox.maxExtents.y) * 0.5,
                     mObjBox.maxExtents.z);
   Point3F endCast((mObjBox.minExtents.x + mObjBox.maxExtents.x) * 0.5,
                   (mObjBox.minExtents.y + mObjBox.maxExtents.y) * 0.5,
                   mObjBox.minExtents.z);
   collisionMatrix.setColumn(3, pos);
   collisionMatrix.mulP(startCast);
   collisionMatrix.setColumn(3, end);
   collisionMatrix.mulP(endCast);
   RayInfo rinfo;
   bool doToughCollision = true;
   disableCollision();
   if (mCollisionObject)
      mCollisionObject->disableCollision();
   if (getContainer()->castRay(startCast, endCast, mask, &rinfo))
   {
      F32 bd = -mDot(mVelocity, rinfo.normal);

      if (bd >= 0.0)
      {
         // Contact!
         if (mDataBlock->sticky && rinfo.object->getTypeMask() & (STATIC_COLLISION_TYPEMASK)) {
            mVelocity.set(0, 0, 0);
            mAtRest = true;
            mAtRestCounter = 0;
            stickyNotify = true;
            mStickyCollisionPos    = rinfo.point;
            mStickyCollisionNormal = rinfo.normal;
            doToughCollision = false;;
         } else {
            // Subtract out velocity into surface and friction
            VectorF fv = mVelocity + rinfo.normal * bd;
            F32 fvl = fv.len();
            if (fvl) {
               F32 ff = bd * mDataBlock->friction;
               if (ff < fvl) {
                  fv *= ff / fvl;
                  fvl = ff;
               }
            }
            bd *= 1 + mDataBlock->elasticity;
            VectorF dv = rinfo.normal * (bd + 0.002);
            mVelocity += dv;
            mVelocity -= fv;

            // Keep track of what we hit
            contact = true;
            U32 typeMask = rinfo.object->getTypeMask();
            if (!(typeMask & StaticObjectType))
               nonStatic = true;
            if (isServerObject() && (typeMask & ShapeBaseObjectType)) {
               ShapeBase* col = static_cast<ShapeBase*>(rinfo.object);
               queueCollision(col,mVelocity - col->getVelocity());
            }
         }
      }
   }
   enableCollision();
   if (mCollisionObject)
      mCollisionObject->enableCollision();

   if (doToughCollision)
   {
      U32 count;
      for (count = 0; count < 3; count++)
      {
         // Build list from convex states here...
         end = pos + mVelocity * time;


         collisionMatrix.setColumn(3, end);
         Box3F wBox = getObjBox();
         collisionMatrix.mul(wBox);
         Box3F testBox = wBox;
         Point3F oldMin = testBox.minExtents;
         Point3F oldMax = testBox.maxExtents;
         testBox.minExtents.setMin(oldMin + (mVelocity * time));
         testBox.maxExtents.setMin(oldMax + (mVelocity * time));

         sEarlyOutPolyList.clear();
         sEarlyOutPolyList.mNormal.set(0,0,0);
         sEarlyOutPolyList.mPlaneList.setSize(6);
         sEarlyOutPolyList.mPlaneList[0].set(wBox.minExtents,VectorF(-1,0,0));
         sEarlyOutPolyList.mPlaneList[1].set(wBox.maxExtents,VectorF(0,1,0));
         sEarlyOutPolyList.mPlaneList[2].set(wBox.maxExtents,VectorF(1,0,0));
         sEarlyOutPolyList.mPlaneList[3].set(wBox.minExtents,VectorF(0,-1,0));
         sEarlyOutPolyList.mPlaneList[4].set(wBox.minExtents,VectorF(0,0,-1));
         sEarlyOutPolyList.mPlaneList[5].set(wBox.maxExtents,VectorF(0,0,1));

         CollisionWorkingList& eorList = mConvex.getWorkingList();
         CollisionWorkingList* eopList = eorList.wLink.mNext;
         while (eopList != &eorList) {
            if ((eopList->mConvex->getObject()->getTypeMask() & mask) != 0)
            {
               Box3F convexBox = eopList->mConvex->getBoundingBox();
               if (testBox.isOverlapped(convexBox))
               {
                  eopList->mConvex->getPolyList(&sEarlyOutPolyList);
                  if (sEarlyOutPolyList.isEmpty() == false)
                     break;
               }
            }
            eopList = eopList->wLink.mNext;
         }
         if (sEarlyOutPolyList.isEmpty())
         {
            pos = end;
            break;
         }

         collisionMatrix.setColumn(3, pos);
         sBoxPolyhedron.buildBox(collisionMatrix, mObjBox, true);

         // Build extruded polyList...
         VectorF vector = end - pos;
         sExtrudedPolyList.extrude(sBoxPolyhedron, vector);
         sExtrudedPolyList.setVelocity(mVelocity);
         sExtrudedPolyList.setCollisionList(&collisionList);

         CollisionWorkingList& rList = mConvex.getWorkingList();
         CollisionWorkingList* pList = rList.wLink.mNext;
         while (pList != &rList) {
            if ((pList->mConvex->getObject()->getTypeMask() & mask) != 0)
            {
               Box3F convexBox = pList->mConvex->getBoundingBox();
               if (testBox.isOverlapped(convexBox))
               {
                  pList->mConvex->getPolyList(&sExtrudedPolyList);
               }
            }
            pList = pList->wLink.mNext;
         }

         if (collisionList.getTime() < 1.0)
         {
            // Set to collision point
            F32 dt = time * collisionList.getTime();
            pos += mVelocity * dt;
            time -= dt;

            // Pick the most resistant surface
            F32 bd = 0;
            const Collision* collision = 0;
            for (int c = 0; c < collisionList.getCount(); c++) {
               const Collision &cp = collisionList[c];
               F32 dot = -mDot(mVelocity,cp.normal);
               if (dot > bd) {
                  bd = dot;
                  collision = &cp;
               }
            }

            if (collision && mDataBlock->sticky && collision->object->getTypeMask() & (STATIC_COLLISION_TYPEMASK)) {
               mVelocity.set(0, 0, 0);
               mAtRest = true;
               mAtRestCounter = 0;
               stickyNotify = true;
               mStickyCollisionPos    = collision->point;
               mStickyCollisionNormal = collision->normal;
               break;
            } else {
               // Subtract out velocity into surface and friction
               if (collision) {
                  VectorF fv = mVelocity + collision->normal * bd;
                  F32 fvl = fv.len();
                  if (fvl) {
                     F32 ff = bd * mDataBlock->friction;
                     if (ff < fvl) {
                        fv *= ff / fvl;
                        fvl = ff;
                     }
                  }
                  bd *= 1 + mDataBlock->elasticity;
                  VectorF dv = collision->normal * (bd + 0.002);
                  mVelocity += dv;
                  mVelocity -= fv;

                  // Keep track of what we hit
                  contact = true;
                  U32 typeMask = collision->object->getTypeMask();
                  if (!(typeMask & StaticObjectType))
                     nonStatic = true;
                  if (isServerObject() && (typeMask & ShapeBaseObjectType)) {
                     ShapeBase* col = static_cast<ShapeBase*>(collision->object);
                     queueCollision(col,mVelocity - col->getVelocity());
                  }
               }
            }
         }
         else
         {
            pos = end;
            break;
         }
      }
      if (count == 3)
      {
         // Couldn't move...
         mVelocity.set(0, 0, 0);
      }
   }

   // If on the client, calculate delta for backstepping
   if (isGhost()) {
      delta.pos     = pos;
      delta.posVec -= pos;
      delta.dt = 1;
   }

   // Update transform
   MatrixF mat = mObjToWorld;
   mat.setColumn(3,pos);
   Parent::setTransform(mat);
   enableCollision();
   if (mCollisionObject)
      mCollisionObject->enableCollision();
   updateContainer();

   if ( mPhysicsRep )
      mPhysicsRep->setTransform( mat );

   //
   if (contact) {
      // Check for rest condition
      if (!nonStatic && mVelocity.len() < sAtRestVelocity) {
         mVelocity.x = mVelocity.y = mVelocity.z = 0;
         mAtRest = true;
         mAtRestCounter = 0;
      }

      // Only update the client if we hit a non-static shape or
      // if this is our final rest pos.
      if (nonStatic || mAtRest)
         setMaskBits(PositionMask);
   }

   // Collision callbacks. These need to be processed whether we hit
   // anything or not.
   if (!isGhost())
   {
      SimObjectPtr<Item> safePtr(this);
      if (stickyNotify)
      {
         notifyCollision();
         if(bool(safePtr))
			 onStickyCollision_callback( getIdString() );
      }
      else
         notifyCollision();

      // water
      if(bool(safePtr))
      {
         if(!mInLiquid && mWaterCoverage != 0.0f)
         {
            mInLiquid = true;
            if ( !isGhost() )
             mDataBlock->onEnterLiquid_callback( this, mWaterCoverage, mLiquidType.c_str() );
         }

         else if(mInLiquid && mWaterCoverage == 0.0f)
         {
            mInLiquid = false;
            if ( !isGhost() )
             mDataBlock->onLeaveLiquid_callback( this, mLiquidType.c_str() );
         }
      }
   }
}
예제 #9
0
void Turret::shoot (bool playerControlled, Player* targetPlayer)
{
   if (data && data->isSustained == false) {
	   if (data && data->projectile.type == -1)
	   	{
	   		if (!isGhost())
	   			if (const char* script = scriptName("onFire"))
	   				Console->executef(2, script, scriptThis());
	   	}
	   else
	   	{
	   		float energy = getEnergy();
	   		if (waitTime <= manager->getCurrentTime() && data && energy >= data->minGunEnergy && data->projectile.type != -1)
	   			{
                  TMat3F muzzleTransform;
	   				getMuzzleTransform(0, &muzzleTransform);
	   				Projectile* bullet = createProjectile(data->projectile);

	   				if (!playerControlled && data->deflection)
	   					{
	   						static Random random;
	   						EulerF angles;
	   					   muzzleTransform.angles (&angles);
	   						angles.x += (random.getFloat() - 0.5) * M_2PI * data->deflection;
	   						angles.z += (random.getFloat() - 0.5) * M_2PI * data->deflection;
	   						muzzleTransform.set (angles, muzzleTransform.p);
	   					}
	   				else
	   					if (playerControlled)
	   						{
	   							Point3F start = muzzleTransform.p;
	   							muzzleTransform = getEyeTransform ();
	   							aimedTransform (&muzzleTransform, start);
	   							muzzleTransform.p = start;
	   						}

	   				bullet->initProjectile (muzzleTransform, Point3F (0, 0, 0), getId());

	   	         if (bullet->isTargetable() == true) {
	   	            if (targetPlayer != NULL) {
	   						if (GameBase* mo = targetPlayer->getMountObject())
	   		               bullet->setTarget(static_cast<ShapeBase*>(mo));
	   						else
	   		               bullet->setTarget(targetPlayer);
                     } else if (playerControlled) {
                        ShapeBase* pClosest   = NULL;
                        Point3F    closeHisPos;
                        float      closestVal = -2.0f;
                        SimSet::iterator itr;
                     
                        Point3F lookDir;
                        getEyeTransform().getRow(1, &lookDir);
                        lookDir.normalize();

                        SimContainerQuery collisionQuery;
                        SimCollisionInfo  info;
                        collisionQuery.id     = getId();
                        collisionQuery.type   = -1;
                        collisionQuery.mask   = Projectile::csm_collisionMask;
                        collisionQuery.detail = SimContainerQuery::DefaultDetail;
                        collisionQuery.box.fMin = getEyeTransform().p;
                        SimContainer* pRoot = (SimContainer*)manager->findObject(SimRootContainerId);

                        SimSet* pSet = dynamic_cast<SimSet*>(manager->findObject(PlayerSetId));
                        AssertFatal(pSet != NULL, "No player set?");
                        for (itr = pSet->begin(); itr != pSet->end(); itr++) {
                           Player* pPlayer = dynamic_cast<Player*>(*itr);

                           if (!pPlayer || pPlayer->getVisibleToTeam(getTeam()) == false)
                              continue;

                           collisionQuery.box.fMax = pPlayer->getBoxCenter();
                           if (pRoot->findLOS(collisionQuery, &info, SimCollisionImageQuery::High) == true) {
                              if (info.object != (SimObject*)pPlayer)
                                 continue;
                           }

                           Point3F hisPos = pPlayer->getBoxCenter();
                           hisPos -= getLinearPosition();
                           hisPos.normalize();

                           float prod = m_dot(hisPos, lookDir);
                           if (prod > 0.0f && prod > closestVal) {
                              closestVal = prod;
                              pClosest   = pPlayer;
                              closeHisPos = hisPos;
                           }
                        }

                        pSet = dynamic_cast<SimSet*>(manager->findObject(MoveableSetId));
                        AssertFatal(pSet != NULL, "No moveable set?");
                        for (itr = pSet->begin(); itr != pSet->end(); itr++) {
                           if (((*itr)->getType() & VehicleObjectType) == 0)
                              continue;

                           ShapeBase* pObject = dynamic_cast<ShapeBase*>(*itr);
                           
                           if (pObject->getVisibleToTeam(getTeam()) == false)
                              continue;

                           collisionQuery.box.fMax = pObject->getBoxCenter();
                           if (pRoot->findLOS(collisionQuery, &info, SimCollisionImageQuery::High) == true) {
                              if (info.object != (SimObject*)pObject)
                                 continue;
                           }

                           Point3F hisPos = pObject->getBoxCenter();
                           hisPos -= getLinearPosition();
                           hisPos.normalize();

                           float prod = m_dot(hisPos, lookDir);
                           if (prod > 0.0f && prod > closestVal) {
                              closestVal = prod;
                              closeHisPos = hisPos;
                              pClosest   = pObject;
                           }
                        }

                        // We need to find the current FOV, and take the percentage of
                        //  it specified in the .dat file for this turret.  Only if the
                        //  do product is greater than this, do we allow the target to
                        //  be set...
                        //
                        float myFov   = (fov / 2.0) * data->targetableFovRatio;
                        float compCos = cos(myFov);
                        if (compCos > 0.996f)   // hack for single precision math.  It's very
                           compCos = 0.996;     // hard to get more precise answers from the dot prod.

                        if (pClosest != NULL && closestVal > compCos)
                           bullet->setTarget(pClosest);
                     }
                  }

	   				if (data->maxGunEnergy)
	   					{
	   						float e;
	   						e = energy > data->maxGunEnergy ? data->maxGunEnergy : energy;

                        float pofm = e / float(data->maxGunEnergy);

	   						bullet->setEnergy (e, pofm);

	   						energy -= e;
	   						setEnergy (energy);
	   					}

                  SimGroup *grp = NULL;
                  if(SimObject *obj = manager->findObject("MissionCleanup"))
                     grp = dynamic_cast<SimGroup*>(obj);
                  if(!manager->registerObject(bullet))
                     delete bullet;
                  else
                  {
                     if(grp)
                        grp->addObject(bullet);
                     else
                        manager->addObject(bullet);
                  }

	   				waitTime = manager->getCurrentTime() + data->reloadDelay;

	   				if (animThread)
	   					{
	   						setFireThread ();
	   						animThread->SetPosition (0.0);
	   					}
	   				
	   				fireCount++;
	   				setMaskBits (ShootingMask);
	   			}
	   	}
   } else {
      if (data && data->projectile.type == -1) {
         if (!isGhost())
            if (const char* script = scriptName("onFire"))
               Console->executef(2, script, scriptThis());
      }
      else {
         float energy = getEnergy();
         if (waitTime <= manager->getCurrentTime() && data && energy >= data->minGunEnergy && data->projectile.type != -1) {
            TMat3F muzzleTransform;
            getMuzzleTransform(0, &muzzleTransform);
            Projectile* bullet = createProjectile(data->projectile);

            if (!playerControlled && data->deflection) {
               static Random random;
               EulerF angles;
               muzzleTransform.angles (&angles);
               angles.x += (random.getFloat() - 0.5) * M_2PI * data->deflection;
               angles.z += (random.getFloat() - 0.5) * M_2PI * data->deflection;
               muzzleTransform.set (angles, muzzleTransform.p);
            } else if (playerControlled) {
               Point3F start = muzzleTransform.p;
               muzzleTransform = getEyeTransform ();
               aimedTransform (&muzzleTransform, start);
               muzzleTransform.p = start;
            }

            bullet->initProjectile (muzzleTransform, Point3F (0, 0, 0), getId());
            AssertFatal(bullet->isSustained() == true, "Error, must be sustained bullet");
            SimGroup *grp = NULL;
            if(SimObject *obj = manager->findObject("MissionCleanup"))
               grp = dynamic_cast<SimGroup*>(obj);
            if(!manager->registerObject(bullet))
               delete bullet;
            else
            {
               if(grp)
                  grp->addObject(bullet);
               else
                  manager->addObject(bullet);
            }

            if (animThread) {
               setFireThread ();
               animThread->SetPosition (0.0);
            }
            
            fireCount++;
            setMaskBits (ShootingMask);

            m_fireState  = Firing;
            m_beganState = wg->currentTime;

            m_pProjectile = bullet;
            m_pTarget     = targetPlayer;
            
            if (m_pTarget)
               deleteNotify(m_pTarget);
         }
      }
   }
}
예제 #10
0
Move HoverPodController::getMove(ShapeBase* obj)
{
	Move retMove = NullMove;

	GameConnection* client = NULL;
	if(!Sim::findObject(mClientId, client)) 
		return retMove;

	ShapeBase* control = client->getControlObject();
	if(control)
	{
		Move cMove = client->lastReceivedMove();

		Point3F v1, v2;
		control->getTransform().getColumn(0, &v1);
		control->getTransform().getColumn(1, &v2);
		Point3F pv = v1*cMove.x + v2*cMove.y;

		//pv = mDirection * mDot(pv, mDirection);

		obj->getTransform().getColumn(0, &v1);
		obj->getTransform().getColumn(1, &v2);
		retMove.x = mDot(v1, pv);
		retMove.y = mDot(v2, pv);
	}
	return retMove;
	
#if 0
   if(this->isServerObject() && this->isMounted())
   {
		Move mMove = NullMove;
		ShapeBase* mount = this->getObjectMount();
		if(mount->getType() & VehicleObjectType)
		{
			Vehicle* vehicle = (Vehicle*)mount;
			if(move && move->x != 0)
			{
				mMove.yaw = move->x;
			}
			else
			{
				Point3F zv; vehicle->getTransform().getColumn(2, &zv);
				zv.normalize();
				Point3F m = vehicle->getRigid().angMomentum;
				//Point3F v = vehicle->getRigid().angVelocity;
				F32 dot = mDot(zv, m);
				//Con::printf("%f / %f %f %f / %f %f %f", dot,
				//	m.x, m.y, m.z, v.x, v.y, v.z);
				mMove.yaw = dot / 50;
			}

			if(move)
				mMove.y = move->y;

		}
		else if(move)
		{
			Point3F v1, v2;
			this->getTransform().getColumn(0, &v1);
			this->getTransform().getColumn(1, &v2);
			Point3F pv = v1*move->x + v2*move->y;

			mount->getTransform().getColumn(0, &v1);
			mount->getTransform().getColumn(1, &v2);

			mMove.x = mDot(v1, pv);
			mMove.y = mDot(v2, pv);
		}
		mount->processTick(&mMove);
   }
#endif
예제 #11
0
//----------------------------------------------------------------------------
/// Core rendering method for this control.
///
/// This method scans through all the current client ShapeBase objects.
/// If one is named, it displays the name and damage information for it.
///
/// Information is offset from the center of the object's bounding box,
/// unless the object is a PlayerObjectType, in which case the eye point
/// is used.
///
/// @param   updateRect   Extents of control.
void afxGuiTextHud::onRender( Point2I, const RectI &updateRect)
{
   // Background fill first
   if (mShowFill)
      GFX->getDrawUtil()->drawRectFill(updateRect, mFillColor.toColorI());

   // Must be in a TS Control
   GuiTSCtrl *parent = dynamic_cast<GuiTSCtrl*>(getParent());
   if (!parent) return;

   // Must have a connection and control object
   GameConnection* conn = GameConnection::getConnectionToServer();
   if (!conn)
      return;

   GameBase * control = dynamic_cast<GameBase*>(conn->getControlObject());
   if (!control)
      return;

   // Get control camera info
   MatrixF cam;
   Point3F camPos;
   VectorF camDir;
   conn->getControlCameraTransform(0,&cam);
   cam.getColumn(3, &camPos);
   cam.getColumn(1, &camDir);

   F32 camFovCos;
   conn->getControlCameraFov(&camFovCos);
   camFovCos = mCos(mDegToRad(camFovCos) / 2);

   // Visible distance info & name fading
   F32 visDistance = gClientSceneGraph->getVisibleDistance();
   F32 visDistanceSqr = visDistance * visDistance;
   F32 fadeDistance = visDistance * mDistanceFade;

   // Collision info. We're going to be running LOS tests and we
   // don't want to collide with the control object.
   static U32 losMask = TerrainObjectType | TerrainLikeObjectType | ShapeBaseObjectType;

   if (!mEnableControlObjectOcclusion)
      control->disableCollision();

   if (mLabelAllShapes)
   {
     // This section works just like GuiShapeNameHud and renders labels for
     // all the shapes.

     // All ghosted objects are added to the server connection group,
     // so we can find all the shape base objects by iterating through
     // our current connection.
     for (SimSetIterator itr(conn); *itr; ++itr) 
     {
       ///if ((*itr)->getTypeMask() & ShapeBaseObjectType) 
       ///{
       ShapeBase* shape = dynamic_cast<ShapeBase*>(*itr);
       if ( shape ) {
         if (shape != control && shape->getShapeName()) 
         {

           // Target pos to test, if it's a player run the LOS to his eye
           // point, otherwise we'll grab the generic box center.
           Point3F shapePos;
           if (shape->getTypeMask() & PlayerObjectType) 
           {
             MatrixF eye;

             // Use the render eye transform, otherwise we'll see jittering
             shape->getRenderEyeTransform(&eye);
             eye.getColumn(3, &shapePos);
           }
           else 
           {
             // Use the render transform instead of the box center
             // otherwise it'll jitter.
             MatrixF srtMat = shape->getRenderTransform();
             srtMat.getColumn(3, &shapePos);
           }

           VectorF shapeDir = shapePos - camPos;

           // Test to see if it's in range
           F32 shapeDist = shapeDir.lenSquared();
           if (shapeDist == 0 || shapeDist > visDistanceSqr)
             continue;
           shapeDist = mSqrt(shapeDist);

           // Test to see if it's within our viewcone, this test doesn't
           // actually match the viewport very well, should consider
           // projection and box test.
           shapeDir.normalize();
           F32 dot = mDot(shapeDir, camDir);
           if (dot < camFovCos)
             continue;

           // Test to see if it's behind something, and we want to
           // ignore anything it's mounted on when we run the LOS.
           RayInfo info;
           shape->disableCollision();
           SceneObject *mount = shape->getObjectMount();
           if (mount)
             mount->disableCollision();
           bool los = !gClientContainer.castRay(camPos, shapePos,losMask, &info);
           shape->enableCollision();
           if (mount)
             mount->enableCollision();

           if (!los)
             continue;

           // Project the shape pos into screen space and calculate
           // the distance opacity used to fade the labels into the
           // distance.
           Point3F projPnt;
           shapePos.z += mVerticalOffset;
           if (!parent->project(shapePos, &projPnt))
             continue;
           F32 opacity = (shapeDist < fadeDistance)? 1.0:
             1.0 - (shapeDist - fadeDistance) / (visDistance - fadeDistance);

           // Render the shape's name
           drawName(Point2I((S32)projPnt.x, (S32)projPnt.y),shape->getShapeName(),opacity);
         }
       }
     }
   }

   // This section renders all text added by afxGuiText effects.
   for (S32 i = 0; i < text_items.size(); i++)
   {
     HudTextSpec* spec = &text_items[i];
     if (spec->text && spec->text[0] != '\0') 
     {
       VectorF shapeDir = spec->pos - camPos;

       // do range test
       F32 shapeDist = shapeDir.lenSquared();
       if (shapeDist == 0 || shapeDist > visDistanceSqr)
         continue;
       shapeDist = mSqrt(shapeDist);

       // Test to see if it's within our viewcone, this test doesn't
       // actually match the viewport very well, should consider
       // projection and box test.
       shapeDir.normalize();
       F32 dot = mDot(shapeDir, camDir);
       if (dot < camFovCos)
         continue;

       // Test to see if it's behind something, and we want to
       // ignore anything it's mounted on when we run the LOS.
       RayInfo info;
       if (spec->obj)
         spec->obj->disableCollision();
       bool los = !gClientContainer.castRay(camPos, spec->pos, losMask, &info);
       if (spec->obj)
         spec->obj->enableCollision();
       if (!los)
         continue;

       // Project the shape pos into screen space.
       Point3F projPnt;
       if (!parent->project(spec->pos, &projPnt))
         continue;

       // Calculate the distance opacity used to fade text into the distance.
       F32 opacity = (shapeDist < fadeDistance)? 1.0 : 1.0 - (shapeDist - fadeDistance) / (25.0f);
       if (opacity > 0.01f)
        drawName(Point2I((S32)projPnt.x, (S32)projPnt.y), spec->text, opacity, &spec->text_clr);
     }
   }

   // Restore control object collision
   if (!mEnableControlObjectOcclusion)
      control->enableCollision();

   // Border last
   if (mShowFrame)
      GFX->getDrawUtil()->drawRect(updateRect, mFrameColor.toColorI());

   reset();
}