Пример #1
0
 bool default_print( String & result, const AngAxisF & data )
 {
    F32 angle = mRadToDeg(data.angle);
    angle = mFmod(angle + 360.0f,360.0f);
    result = String::ToString("%g %g %g %g", data.axis.x, data.axis.y, data.axis.z, angle);
    return true;
 }
Пример #2
0
void TimeOfDay::_updateTimeEvents()
{
   // Sort by trigger times here.
   //dQsort( mTimeEvents.address(), mTimeEvents.size(), sizeof( TimeOfDayEvent ), cmpTriggerElevation ); 

   // Get the prev, next elevation within 0-360 range.
   F32 prevElevation = mRadToDeg( mPrevElevation );
   F32 nextElevation = mRadToDeg( mNextElevation );

   // Walk the list, and fire any 
   // events whose trigger times 
   // are equal to the current time
   // or lie between the previous and
   // current times.
   for ( U32 i = 0; i < mTimeEvents.size(); i++ )
   {
      const TimeOfDayEvent &timeEvent = mTimeEvents[i];

      bool fire = false;

      // Elevation just rolled over form 360 to 0
      if ( nextElevation < prevElevation )
      {
         if ( nextElevation >= timeEvent.triggerElevation ||
              prevElevation < timeEvent.triggerElevation )
         {
            fire = true;
         }
      }
      // Normal progression, nextElevation is greater than previous
      else
      {
         if ( nextElevation >= timeEvent.triggerElevation &&
              prevElevation < timeEvent.triggerElevation )
         {
            fire = true;
         }
      }
            
      if ( fire )
      {
         // Call the time event callback.
         _onTimeEvent( timeEvent.identifier );
      }
   }
}
Пример #3
0
bool OculusVRSensorDevice::process(U32 deviceType, bool generateRotAsAngAxis, bool generateRotAsEuler, bool generateRotationAsAxisEvents, F32 maxAxisRadius)
{
   if(!mIsValid)
      return false;

   // Store the current data from the sensor and compare with previous data
   U32 diff;
   OculusVRSensorData* currentBuffer = (mPrevData == mDataBuffer[0]) ? mDataBuffer[1] : mDataBuffer[0];
   if(!mIsSimulation)
   {
      currentBuffer->setData(mSensorFusion, maxAxisRadius);
   }
   else
   {
      currentBuffer->simulateData(maxAxisRadius);
   }
   diff = mPrevData->compare(currentBuffer);

   // Update the previous data pointer.  We do this here in case someone calls our
   // console functions during one of the input events below.
   mPrevData = currentBuffer;

   // Rotation event
   if(diff & OculusVRSensorData::DIFF_ROT)
   {
      if(generateRotAsAngAxis)
      {
         INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_ROT, OVR_SENSORROT[mActionCodeIndex], SI_MOVE, currentBuffer->mRotQuat);
      }

      if(generateRotAsEuler)
      {
         // Convert angles to degrees
         VectorF angles;
         for(U32 i=0; i<3; ++i)
         {
            angles[i] = mRadToDeg(currentBuffer->mRotEuler[i]);
         }
         INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_POS, OVR_SENSORROTANG[mActionCodeIndex], SI_MOVE, angles);
      }
   }

   // Rotation as axis event
   if(generateRotationAsAxisEvents && diff & OculusVRSensorData::DIFF_ROTAXIS)
   {
      if(diff & OculusVRSensorData::DIFF_ROTAXISX)
         INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_AXIS, OVR_SENSORROTAXISX[mActionCodeIndex], SI_MOVE, currentBuffer->mRotAxis.x);
      if(diff & OculusVRSensorData::DIFF_ROTAXISY)
         INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_AXIS, OVR_SENSORROTAXISY[mActionCodeIndex], SI_MOVE, currentBuffer->mRotAxis.y);
   }

   return true;
}
Пример #4
0
void TimeOfDay::_onTimeEvent( const String &identifier )
{
   String strCurrentTime = String::ToString( "%g", mTimeOfDay );

   F32 elevation = mRadToDeg( mElevation );
   while( elevation < 0 )
      elevation += 360.0f;
   while( elevation > 360.0f )
      elevation -= 360.0f;

   String strCurrentElevation = String::ToString( "%g", elevation );

   Con::executef( this, "onTimeEvent", identifier.c_str(), strCurrentTime.c_str(), strCurrentElevation.c_str() );
}
F32 afxEA_ZodiacPlane::calc_facing_angle() 
{
  // get direction player is facing
  VectorF shape_vec;
  MatrixF shape_xfm;

  afxConstraint* orient_constraint = getOrientConstraint();
  if (orient_constraint)
    orient_constraint->getTransform(shape_xfm);
  else
    shape_xfm.identity();

  shape_xfm.getColumn(1, &shape_vec);
  shape_vec.z = 0.0f;
  shape_vec.normalize();

  F32 pitch, yaw;
  MathUtils::getAnglesFromVector(shape_vec, yaw, pitch);

  return mRadToDeg(yaw); 
}
Пример #6
0
void TimeOfDay::advanceTime( F32 timeDelta )
{
   if ( !mPlay )
      return;
   
   F32 elevation = mRadToDeg( mElevation );
   bool daytime = false;

   if ( elevation > 350.0f || ( 0.0f <= elevation && elevation < 190.0f ) )
   {
      timeDelta *= mDayScale;
      daytime = true;
   }
   else
   {
      timeDelta *= mNightScale;
      daytime = false;
   }

   //Con::printf( "elevation ( %f ), ( %s )", elevation, ( daytime ) ? "day" : "night" );

   // do time updates   
   mTimeOfDay += timeDelta / mDayLen;

   // It could be possible for more than a full day to 
   // pass in a single advance time, so I put this inside a loop
   // but timeEvents will not actually be called for the
   // skipped day.
   while ( mTimeOfDay > 1.0f )
      mTimeOfDay -= 1.0f;

   _updatePosition();

   if ( isServerObject() )
      _updateTimeEvents();
}
Пример #7
0
void DecalRoad::_generateEdges()
{      
   PROFILE_SCOPE( DecalRoad_generateEdges );

   //Con::warnf( "%s - generateEdges", isServerObject() ? "server" : "client" );

   if ( mNodes.size() > 0 )
   {
      // Set our object position to the first node.
      const Point3F &nodePt = mNodes.first().point;
      MatrixF mat( true );
      mat.setPosition( nodePt );
      Parent::setTransform( mat );

      // The server object has global bounds, which Parent::setTransform 
      // messes up so we must reset it.
      if ( isServerObject() )
      {
         mObjBox.minExtents.set(-1e10, -1e10, -1e10);
         mObjBox.maxExtents.set( 1e10,  1e10,  1e10);
      }
   }


   if ( mNodes.size() < 2 )
      return;

   // Ensure nodes are above the terrain height at their xy position
   for ( U32 i = 0; i < mNodes.size(); i++ )
   {
      _getTerrainHeight( mNodes[i].point );
   }

   // Now start generating edges...

   U32 nodeCount = mNodes.size();
   Point3F *positions = new Point3F[nodeCount];

   for ( U32 i = 0; i < nodeCount; i++ )
   {
      const RoadNode &node = mNodes[i];
      positions[i].set( node.point.x, node.point.y, node.width );
   }

   CatmullRom<Point3F> spline;
   spline.initialize( nodeCount, positions );
   delete [] positions;

   mEdges.clear();

   Point3F lastBreakVector(0,0,0);      
   RoadEdge slice;
   Point3F lastBreakNode;
   lastBreakNode = spline.evaluate(0.0f);

   for ( U32 i = 1; i < mNodes.size(); i++ )
   {
      F32 t1 = spline.getTime(i);
      F32 t0 = spline.getTime(i-1);

      F32 segLength = spline.arcLength( t0, t1 );

      U32 numSegments = mCeil( segLength / MIN_METERS_PER_SEGMENT );
      numSegments = getMax( numSegments, (U32)1 );
      F32 tstep = ( t1 - t0 ) / numSegments; 

      U32 startIdx = 0;
      U32 endIdx = ( i == nodeCount - 1 ) ? numSegments + 1 : numSegments;

      for ( U32 j = startIdx; j < endIdx; j++ )
      {
         F32 t = t0 + tstep * j;
         Point3F splineNode = spline.evaluate(t);
         F32 width = splineNode.z;
         _getTerrainHeight( splineNode );

         Point3F toNodeVec = splineNode - lastBreakNode;
         toNodeVec.normalizeSafe();

         if ( lastBreakVector.isZero() )
            lastBreakVector = toNodeVec;

         F32 angle = mRadToDeg( mAcos( mDot( toNodeVec, lastBreakVector ) ) );

         if ( j == startIdx || 
            ( j == endIdx - 1 && i == mNodes.size() - 1 ) ||
            angle > mBreakAngle )
         {
            // Push back a spline node
            //slice.p1.set( splineNode.x, splineNode.y, 0.0f );
            //_getTerrainHeight( slice.p1 );
            slice.p1 = splineNode;
            slice.uvec.set(0,0,1);
            slice.width = width;            
            slice.parentNodeIdx = i-1;
            mEdges.push_back( slice );         

            lastBreakVector = splineNode - lastBreakNode;
            lastBreakVector.normalizeSafe();

            lastBreakNode = splineNode;
         }          
      }
   }

   /*
   for ( U32 i = 1; i < nodeCount; i++ )
   {
      F32 t0 = spline.getTime( i-1 );
      F32 t1 = spline.getTime( i );

      F32 segLength = spline.arcLength( t0, t1 );

      U32 numSegments = mCeil( segLength / mBreakAngle );
      numSegments = getMax( numSegments, (U32)1 );
      F32 tstep = ( t1 - t0 ) / numSegments;

      AssertFatal( numSegments > 0, "DecalRoad::_generateEdges, got zero segments!" );   

      U32 startIdx = 0;
      U32 endIdx = ( i == nodeCount - 1 ) ? numSegments + 1 : numSegments;

      for ( U32 j = startIdx; j < endIdx; j++ )
      {
         F32 t = t0 + tstep * j;
         Point3F val = spline.evaluate(t);

         RoadEdge edge;         
         edge.p1.set( val.x, val.y, 0.0f );    
         _getTerrainHeight( val.x, val.y, edge.p1.z );    
         edge.uvec.set(0,0,1);
         edge.width = val.z;
         edge.parentNodeIdx = i-1;
         mEdges.push_back( edge );
      }   
   }
   */

   //
   // Calculate fvec and rvec for all edges
   //
   RoadEdge *edge = NULL;
   RoadEdge *nextEdge = NULL;

   for ( U32 i = 0; i < mEdges.size() - 1; i++ )
   {
      edge = &mEdges[i];
      nextEdge = &mEdges[i+1];

      edge->fvec = nextEdge->p1 - edge->p1;
      edge->fvec.normalize();

      edge->rvec = mCross( edge->fvec, edge->uvec );
      edge->rvec.normalize();
   }

   // Must do the last edge outside the loop
   RoadEdge *lastEdge = &mEdges[mEdges.size()-1];
   RoadEdge *prevEdge = &mEdges[mEdges.size()-2];
   lastEdge->fvec = prevEdge->fvec;
   lastEdge->rvec = prevEdge->rvec;


   //
   // Calculate p0/p2 for all edges
   //      
   for ( U32 i = 0; i < mEdges.size(); i++ )
   {
      RoadEdge *edge = &mEdges[i];
      edge->p0 = edge->p1 - edge->rvec * edge->width * 0.5f;
      edge->p2 = edge->p1 + edge->rvec * edge->width * 0.5f;
      _getTerrainHeight( edge->p0 );
      _getTerrainHeight( edge->p2 );
   }   
}
Пример #8
0
bool OculusVRSensorDevice::process(U32 deviceType, bool generateRotAsAngAxis, bool generateRotAsEuler, bool generateRotationAsAxisEvents, bool generatePositionEvents, F32 maxAxisRadius, bool generateRawSensor)
{
    if(!mIsValid)
        return false;

    // Grab current state
    ovrTrackingState ts = ovrHmd_GetTrackingState(mDevice, ovr_GetTimeInSeconds());
    mLastStatus = ts.StatusFlags;

    // Store the current data from the sensor and compare with previous data
    U32 diff;
    OculusVRSensorData* currentBuffer = (mPrevData == mDataBuffer[0]) ? mDataBuffer[1] : mDataBuffer[0];
    currentBuffer->setData(ts, maxAxisRadius);
    diff = mPrevData->compare(currentBuffer, generateRawSensor);

    // Update the previous data pointer.  We do this here in case someone calls our
    // console functions during one of the input events below.
    mPrevData = currentBuffer;

    // Rotation event
    if(diff & OculusVRSensorData::DIFF_ROT)
    {
        if(generateRotAsAngAxis)
        {
            INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_ROT, OVR_SENSORROT[mActionCodeIndex], SI_MOVE, currentBuffer->mRotQuat);
        }

        if(generateRotAsEuler)
        {
            // Convert angles to degrees
            VectorF angles;
            for(U32 i=0; i<3; ++i)
            {
                angles[i] = mRadToDeg(currentBuffer->mRotEuler[i]);
            }
            INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_POS, OVR_SENSORROTANG[mActionCodeIndex], SI_MOVE, angles);
        }
    }

    // Rotation as axis event
    if(generateRotationAsAxisEvents && diff & OculusVRSensorData::DIFF_ROTAXIS)
    {
        if(diff & OculusVRSensorData::DIFF_ROTAXISX)
            INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_AXIS, OVR_SENSORROTAXISX[mActionCodeIndex], SI_MOVE, currentBuffer->mRotAxis.x);
        if(diff & OculusVRSensorData::DIFF_ROTAXISY)
            INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_AXIS, OVR_SENSORROTAXISY[mActionCodeIndex], SI_MOVE, currentBuffer->mRotAxis.y);
    }

    if (generatePositionEvents && diff & OculusVRSensorData::DIFF_POS)
    {
        INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_AXIS, OVR_SENSORROTAXISX[mActionCodeIndex], SI_MOVE, currentBuffer->mPosition);
    }

    // Raw sensor event
    if(generateRawSensor && diff & OculusVRSensorData::DIFF_RAW)
    {
        if(diff & OculusVRSensorData::DIFF_ACCEL)
            INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_POS, OVR_SENSORACCELERATION[mActionCodeIndex], SI_MOVE, currentBuffer->mAcceleration);

        if(diff & OculusVRSensorData::DIFF_ANGVEL)
        {
            // Convert angles to degrees
            VectorF angles;
            for(U32 i=0; i<3; ++i)
            {
                angles[i] = mRadToDeg(currentBuffer->mAngVelocity[i]);
            }
            INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_POS, OVR_SENSORANGVEL[mActionCodeIndex], SI_MOVE, angles);
        }

        if(diff & OculusVRSensorData::DIFF_MAG)
            INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_POS, OVR_SENSORMAGNETOMETER[mActionCodeIndex], SI_MOVE, currentBuffer->mMagnetometer);
    }

    if (diff & OculusVRSensorData::DIFF_STATUS)
    {
        if (Con::isFunction("onOculusStatusUpdate"))
        {
            Con::executef("onOculusStatusUpdate", ts.StatusFlags);
        }
    }

    return true;
}
bool afxEA_ZodiacPlane::ea_update(F32 dt)
{
  if (!pzode)
  {
    // create and register effect
    pzode = new afxZodiacPlane();
    pzode->onNewDataBlock(zode_data, false);
    if (!pzode->registerObject())
    {
      delete pzode;
      pzode = 0;
      Con::errorf("afxEA_ZodiacPlane::ea_update() -- effect failed to register.");
      return false;
    }
    deleteNotify(pzode);

    ///pzode->setSequenceRateFactor(datablock->rate_factor/prop_time_factor);
    ///pzode->setSortPriority(datablock->sort_priority);
  }

  if (pzode)
  {
    //ColorF zode_color = zode_data->color;
    ColorF zode_color = updated_color;

    if (live_color_factor > 0.0)
       zode_color.interpolate(zode_color, live_color, live_color_factor);

    if (do_fades)
    {
      if (zode_data->blend_flags == afxZodiacDefs::BLEND_SUBTRACTIVE)
        zode_color *= fade_value*live_fade_factor;
      else
        zode_color.alpha *= fade_value*live_fade_factor;
    }

    // scale and grow zode
    //F32 zode_radius = zode_data->radius_xy*updated_scale.x + life_elapsed*zode_data->growth_rate;
    F32 zode_radius = zode_data->radius_xy + life_elapsed*zode_data->growth_rate;

    // zode is growing
    if (life_elapsed < zode_data->grow_in_time)
    {
      F32 t = life_elapsed/zode_data->grow_in_time;
      zode_radius = afxEase::eq(t, 0.001f, zode_radius, 0.2f, 0.8f);
    }
    // zode is shrinking
    else if (full_lifetime - life_elapsed < zode_data->shrink_out_time)
    {
      F32 t = (full_lifetime - life_elapsed)/zode_data->shrink_out_time;
      zode_radius = afxEase::eq(t, 0.001f, zode_radius, 0.0f, 0.9f);
    }

    zode_radius *= live_scale_factor;

    if (zode_data->respect_ori_cons && !zode_data->use_full_xfm)
    {
      VectorF shape_vec;
      updated_xfm.getColumn(1, &shape_vec);
      shape_vec.normalize();

      F32 ang;

      switch (zode_data->face_dir)
      {
      case afxZodiacPlaneData::FACES_FORWARD:
      case afxZodiacPlaneData::FACES_BACK:
        ang = mAtan2(shape_vec.x, shape_vec.z);
        break;  
      case afxZodiacPlaneData::FACES_RIGHT:
      case afxZodiacPlaneData::FACES_LEFT:
        ang = mAtan2(shape_vec.y, shape_vec.z);
        break;  
      case afxZodiacPlaneData::FACES_UP:
      case afxZodiacPlaneData::FACES_DOWN:
      default:
        ang = mAtan2(shape_vec.x, shape_vec.y);
        break;  
      }

      if (ang < 0.0f)
        ang += M_2PI_F;

      switch (zode_data->face_dir)
      {
      case afxZodiacPlaneData::FACES_DOWN:
      case afxZodiacPlaneData::FACES_BACK:
      case afxZodiacPlaneData::FACES_LEFT:
        ang = -ang;
        break;  
      }

      zode_angle_offset = mRadToDeg(ang); 
    }

    F32 zode_angle = zode_data->calcRotationAngle(life_elapsed, datablock->rate_factor/prop_time_factor);
    zode_angle = mFmod(zode_angle + zode_angle_offset, 360.0f); 
    aa_rot.angle = mDegToRad(zode_angle);
    
    MatrixF spin_xfm; 
    aa_rot.setMatrix(&spin_xfm);

    // set color, radius
    pzode->setColor(zode_color);
    pzode->setRadius(zode_radius);
    if (zode_data->use_full_xfm)
    {
      updated_xfm.mul(spin_xfm);
      pzode->setTransform(updated_xfm);
    }
    else
      pzode->setTransform(spin_xfm);
    pzode->setPosition(updated_pos);
    pzode->setScale(updated_scale);
  }

  return true;
}