TriangleMesh* DebugGeometryBuilder::createBoxHeadedArrow( float size, const Vector& start, const Vector& end )
{
   FastFloat simdSize; simdSize.setFromFloat( size );

   Vector dir;
   dir.setSub( end, start );
   dir.normalize();

   Vector perpVec1, perpVec2;
   VectorUtil::calculatePerpendicularVector( dir, perpVec1 );
   perpVec1.normalize();
   perpVec2.setCross( dir, perpVec1 );

   perpVec1.mul( simdSize );
   perpVec2.mul( simdSize );


   // the line
   std::vector<LitVertex> vertices;
   std::vector<Face> faces;
   addCuboid( simdSize, start, end, vertices, faces );
   
   // and the box-shaped tip
   FastFloat tipSize; tipSize.setFromFloat( 6 * size );
   Vector tipEnd;
   tipEnd.setMulAdd( dir, tipSize, end );
   addCuboid( tipSize, end, tipEnd, vertices, faces );
   
   TriangleMesh* mesh = new TriangleMesh( FilePath(), vertices, faces );
   return mesh;
}
Exemple #2
0
bool Vector::isNormalized() const
{
   FastFloat v;
   v.setSub( lengthSq(), Float_1 );
   v.abs();
   return v < Float_1e_4;
}
void DebugGeometryBuilder::addCone( const FastFloat& baseSize, const Vector& start, const Vector& end, std::vector< LitVertex >& outVertices, std::vector< Face >& outFaces )
{
   // calculate additional vectors needed for cuboid construction
   Vector dir;
   dir.setSub( end, start );
   dir.normalize();

   Vector perpVec1, perpVec2;
   VectorUtil::calculatePerpendicularVector( dir, perpVec1 );
   perpVec1.normalize();
   perpVec2.setCross( dir, perpVec1 );

   perpVec1.mul( baseSize );
   perpVec2.mul( baseSize );

   // calculate the vertices and outFaces
   uint firstVtxIdx = outVertices.size();
   uint firstFaceIdx = outFaces.size();

   for( uint i = 0; i < 5; ++i )
   {
      outVertices.push_back( LitVertex() );
   }
   for( uint i = 0; i < 6; ++i )
   {
      outFaces.push_back( Face() );
   }

   Vector tmpVec;
   {
      perpVec1.mul( Float_6 );
      perpVec2.mul( Float_6 );

      tmpVec.setAdd( start, perpVec1 ); tmpVec.sub( perpVec2 ); tmpVec.store( outVertices[firstVtxIdx + 0].m_coords );
      tmpVec.setSub( start, perpVec1 ); tmpVec.sub( perpVec2 ); tmpVec.store( outVertices[firstVtxIdx + 1].m_coords );
      tmpVec.setAdd( start, perpVec1 ); tmpVec.add( perpVec2 ); tmpVec.store( outVertices[firstVtxIdx + 2].m_coords );
      tmpVec.setSub( start, perpVec1 ); tmpVec.add( perpVec2 ); tmpVec.store( outVertices[firstVtxIdx + 3].m_coords );

      FastFloat tipSizeMultiplier; tipSizeMultiplier.setFromFloat( 12 );
      tipSizeMultiplier.mul( baseSize );
      tmpVec.setMulAdd( dir, tipSizeMultiplier, end ); tmpVec.store( outVertices[firstVtxIdx + 4].m_coords );

      // cone bottom
      outFaces[firstFaceIdx + 0].idx[0] = firstVtxIdx + 0; outFaces[firstFaceIdx + 0].idx[1] = firstVtxIdx + 1; outFaces[firstFaceIdx + 0].idx[2] = firstVtxIdx + 2;
      outFaces[firstFaceIdx + 1].idx[0] = firstVtxIdx + 1; outFaces[firstFaceIdx + 1].idx[1] = firstVtxIdx + 3; outFaces[firstFaceIdx + 1].idx[2] = firstVtxIdx + 2;

      // cone top
      outFaces[firstFaceIdx + 2].idx[0] = firstVtxIdx + 0;   outFaces[firstFaceIdx + 2].idx[1] = firstVtxIdx + 4;   outFaces[firstFaceIdx + 2].idx[2] = firstVtxIdx + 1;
      outFaces[firstFaceIdx + 3].idx[0] = firstVtxIdx + 1;   outFaces[firstFaceIdx + 3].idx[1] = firstVtxIdx + 4;   outFaces[firstFaceIdx + 3].idx[2] = firstVtxIdx + 3;
      outFaces[firstFaceIdx + 4].idx[0] = firstVtxIdx + 3;   outFaces[firstFaceIdx + 4].idx[1] = firstVtxIdx + 4;   outFaces[firstFaceIdx + 4].idx[2] = firstVtxIdx + 2;
      outFaces[firstFaceIdx + 5].idx[0] = firstVtxIdx + 2;   outFaces[firstFaceIdx + 5].idx[1] = firstVtxIdx + 4;   outFaces[firstFaceIdx + 5].idx[2] = firstVtxIdx + 0;
   }

}
void CameraMovementController::update( float timeElapsed )
{
   float speedMul =m_uic->isKeyPressed( VK_SHIFT ) ? 4.0f : 1.0f;
   FastFloat movementSpeed; movementSpeed.setFromFloat( 10.0f * speedMul * timeElapsed );
   FastFloat negMovementSpeed; negMovementSpeed.setNeg( movementSpeed );
   float rotationSpeed = 0.1f * timeElapsed;

   // check which keys are pressed
   m_movementDir[MD_FRONT] = m_uic->isKeyPressed( 'W' );
   m_movementDir[MD_BACK] = m_uic->isKeyPressed( 'S' );
   m_movementDir[MD_LEFT] = m_uic->isKeyPressed( 'A' );
   m_movementDir[MD_RIGHT] = m_uic->isKeyPressed( 'D' );

   m_rotating = m_uic->isKeyPressed( VK_RBUTTON );
   m_uic->setRelativeMouseMovement( m_rotating );

   // process the keys
   Vector moveVec;
   if ( m_movementDir[MD_FRONT] )  
   { 
      moveVec.setMul( m_cameraController->getLookVec(), movementSpeed );
      m_cameraController->move( moveVec ); 
   }

   if ( m_movementDir[MD_BACK] )
   { 
      moveVec.setMul( m_cameraController->getLookVec(), negMovementSpeed );
      m_cameraController->move( moveVec ); 
   }

   if ( m_movementDir[MD_LEFT] )   
   { 
      moveVec.setMul( m_cameraController->getRightVec(), negMovementSpeed );
      m_cameraController->move( moveVec ); 
   }

   if ( m_movementDir[MD_RIGHT] )
   { 
      moveVec.setMul( m_cameraController->getRightVec(), movementSpeed );
      m_cameraController->move( moveVec ); 
   }

   if ( m_rotating )
   {
      float mouseSpeedX = m_uic->getMouseSpeed().v[0] * rotationSpeed;
      float mouseSpeedY = m_uic->getMouseSpeed().v[1] * rotationSpeed;
      m_cameraController->rotate( mouseSpeedY, mouseSpeedX );
   }
}
Exemple #5
0
bool Frustum::isInside( const Sphere& sphere ) const
{
   FastFloat negSphereRad;
   negSphereRad.setNeg( sphere.radius );

   for ( int i = 0; i < 6; ++i )
   {
      const FastFloat n = planes[i].dotCoord( sphere.origin );
      if ( n < negSphereRad ) 
      {
         return false;
      }
   }

   return true;
}
Exemple #6
0
BehTreeNode::Result BTAMoveWithVelocity::execute( BehaviorTreeRunner& runner ) const
{   
   RuntimeDataBuffer& data = runner.data( );
   PhysicsCharacterController* characterController = data[m_characterController];

   if ( !m_velocity  )
   {
      LOG( "BTAMoveWithVelocity: Assign a velocity variable" );
      return FAILED;
   }

   if ( !m_characterRotation )
   {
      LOG( "BTAMoveWithVelocity: Assign a character rotation variable" );
      return FAILED;
   }

   if ( !characterController )
   {
      LOG( "BTAMoveWithVelocity: The character doesn't have a PhysicsCharacterController component" );
      return FAILED;
   }

   StoryBehTreeContext* context = (StoryBehTreeContext*)runner.getContext();
   StoryNodeInstance* controlledNodeInstance = context->m_ownerInstance;

   // calculate displacement
   TimeController& timeController = TSingleton< TimeController >::getInstance();

   Vector movementVelocity = m_velocity->getRuntime( &runner );
   characterController->setLinearVelocity( movementVelocity );


   // calculate new facing direction and a corresponding orientation
   {
      Matrix nodeTransform = controlledNodeInstance->getLocalMtx( );

      FastFloat dYaw; dYaw.setFromFloat( m_characterRotation->getRuntime( &runner ) );

      Vector angularVelocity; angularVelocity.set( Float_0, Float_0, dYaw );

      characterController->setAngularVelocity( angularVelocity );
   }

   return FINISHED;
}
Exemple #7
0
void Camera::lookAt( Entity& node, const FastFloat& distance, const Vector& upVec )
{
   const Matrix& targetNodeMtx = node.getGlobalMtx();
   const Vector& targetNodePos = targetNodeMtx.position();
   const Vector& targetNodeLookVec = targetNodeMtx.forwardVec();

   // I used to normalize the look vector here, but is there a need to do it really? we assume
   // it's always normalized
   ASSERT_MSG( targetNodeLookVec.isNormalized(), "Look vector not normalized" );
   FastFloat negDist;
   negDist.setNeg( distance );
   Vector newPosition;
   newPosition.setMul( targetNodeLookVec, negDist );
   newPosition.add( targetNodePos );

   Matrix lookAtMtx;
   MatrixUtils::generateLookAtLH( newPosition, targetNodePos, upVec, lookAtMtx );
   setLocalMtx( lookAtMtx );
}
void DeferredPointLightRenderer::render( Renderer& renderer, const PointLight* light, const DeferredLightingRenderData& data )
{
   if ( !m_pixelShader || !m_vertexShader || !m_pointLightMesh )
   {
      return;
   }

   Camera& activeCamera = renderer.getActiveCamera();
   Matrix globalMtx = light->getGlobalMtx();

   Matrix viewProjMtx;
   viewProjMtx.setMul( activeCamera.getViewMtx(), activeCamera.getProjectionMtx() ); 

   // activate the final render target
   new ( renderer() ) RCActivateRenderTarget( data.m_finalLightColorTarget );

   // set and configure the pixel shader
   RCBindPixelShader* psComm = new ( renderer() ) RCBindPixelShader( *m_pixelShader, renderer );
   {
      Matrix mtxInvProj;
      mtxInvProj.setInverse( activeCamera.getProjectionMtx() );

      Vector lightOriginViewSpace;
      activeCamera.getViewMtx().transform( globalMtx.position(), lightOriginViewSpace );

      Vector halfPixel;
      ShaderUtils::calculateHalfPixel( renderer, data.m_depthTex, halfPixel );

      psComm->setVec4( "g_halfPixel", halfPixel );
      psComm->setVec4( "g_lightOriginVS", lightOriginViewSpace );
      psComm->setVec4( "g_lightColor", ( const Vector& )light->m_color );
      psComm->setFloat( "g_strength", light->m_strength );
      psComm->setFloat( "g_attenuation", light->m_attenuation );
      psComm->setFloat( "g_radius", light->m_radius );
      psComm->setFloat( "g_farZ", activeCamera.getFarClippingPlane() );
      psComm->setMtx( "g_mtxProjToView", mtxInvProj );
      psComm->setTexture( "g_Depth", data.m_depthTex );
      psComm->setTexture( "g_Normals", data.m_normalsTex );
      psComm->setTexture( "g_Specular", data.m_specularTex );
      psComm->setTexture( "g_SceneColor", data.m_sceneColorTex );
      psComm->setInt( "g_materialsTexSize", data.m_materialsDescriptorsTex->getWidth() );
      psComm->setTexture( "g_MaterialIndices", data.m_materialIndicesTex );
      psComm->setTexture( "g_MaterialsDescr", data.m_materialsDescriptorsTex );
   }

   // set and configure the vertex shader
   RCBindVertexShader* vsComm = new ( renderer() ) RCBindVertexShader( *m_vertexShader, renderer );
   {
      FastFloat rad; rad.setFromFloat( light->m_radius );
      Matrix scaleMtx; scaleMtx.scaleUniform( rad );
      Matrix modelViewProjMtx;      
      modelViewProjMtx.setMul( scaleMtx, globalMtx );
      modelViewProjMtx.mul( viewProjMtx );

      vsComm->setMtx( "g_mtxModelViewProj", modelViewProjMtx );
   }

   // draw the geometry
   m_pointLightMesh->render( renderer );

   // cleanup
   new ( renderer() ) RCUnbindVertexShader( *m_vertexShader );
   new ( renderer() ) RCUnbindPixelShader( *m_pixelShader, renderer );
   new ( renderer() ) RCDeactivateRenderTarget();
}
Exemple #9
0
void MeshUtils::calculateVertexTangents( const std::vector< Face >& faces, std::vector< LitVertex >& inOutVertices )
{
    /**
    * I used the algorithm from this page: http://www.terathon.com/code/tangent.html.
    */

   uint vertexCount = inOutVertices.size();
   Vector* tan1 = new Vector[vertexCount * 2];
   Vector* tan2 = tan1 + vertexCount;
   memset( tan1, 0, vertexCount * sizeof(Vector) * 2 );

   Vector sdir, tdir;
   uint trianglesCount = faces.size();
   for ( uint i = 0; i < trianglesCount; ++i )
   {
      const Face& tri = faces[i];
      uint i1 = tri.idx[0];
      uint i2 = tri.idx[1];
      uint i3 = tri.idx[2];

      const TVector<3>& v1 = inOutVertices[i1].m_coords;
      const TVector<3>& v2 = inOutVertices[i2].m_coords;
      const TVector<3>& v3 = inOutVertices[i3].m_coords;

      const TVector<2>& w1 = inOutVertices[i1].m_textureCoords;
      const TVector<2>& w2 = inOutVertices[i2].m_textureCoords;
      const TVector<2>& w3 = inOutVertices[i3].m_textureCoords;

      float x1 = v2[0] - v1[0];
      float x2 = v3[0] - v1[0];
      float y1 = v2[1] - v1[1];
      float y2 = v3[1] - v1[1];
      float z1 = v2[2] - v1[2];
      float z2 = v3[2] - v1[2];

      float s1 = w2[0] - w1[0];
      float s2 = w3[0] - w1[0];
      float t1 = w2[1] - w1[1];
      float t2 = w3[1] - w1[1];

      float r = (s1 * t2 - s2 * t1);
      if ( r != 0.0f )
      { 
         r = 1.0f / r;

         sdir.set( (t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r );
         tdir.set( (s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r );

         tan1[i1].add( sdir );
         tan1[i2].add( sdir );
         tan1[i3].add( sdir );

         tan2[i1].add( tdir );
         tan2[i2].add( tdir );
         tan2[i3].add( tdir );
      }
   }

   Vector vertexNorm, vertexTangent, normTanCross;
   for ( uint i = 0; i < vertexCount; ++i )
   {
      vertexNorm.load( inOutVertices[i].m_normal );
      const Vector& t = tan1[i];

      // Gram-Schmidt orthogonalize
      FastFloat normTan1Dot;
      normTan1Dot.setNeg( vertexNorm.dot( t ) );
      vertexTangent.setMulAdd( vertexNorm, normTan1Dot, t );
      vertexTangent.normalize();

      // Calculate handedness
      normTanCross.setCross( vertexNorm, t );
      FastFloat handedness;
      handedness.setSign( normTanCross.dot( tan2[i] ) );
      handedness.reciprocal();
      vertexTangent.mul( handedness );

      // store the results
      vertexTangent.store( inOutVertices[i].m_tangent );
   }

   delete[] tan1;
}
Exemple #10
0
const FastFloat FastFloat::fromWord( word val )
{
   FastFloat f;
   f.setFromWord( val );
   return f;
}
Exemple #11
0
const FastFloat FastFloat::fromByte( byte val )
{
   FastFloat f;
   f.setFromByte( val );
   return f;
}
Exemple #12
0
const FastFloat FastFloat::fromInt( int val )
{
   FastFloat f;
   f.setFromInt( val );
   return f;
}
Exemple #13
0
const FastFloat FastFloat::fromFloat( float val )
{
   FastFloat f;
   f.setFromFloat( val );
   return f;
}
TriangleMesh* DebugGeometryBuilder::createTorus( float innerRadius, float outerRadius, const Matrix& transform, int segmentsCount, int segmentVerticesCount )
{
   const Vector& origin = transform.position();
   const Vector& mainAxis = transform.forwardVec();
   const Vector& sideAxis = transform.sideVec();
   Vector circumferenceAxis = transform.upVec();

   FastFloat circumferenceWidth; circumferenceWidth.setFromFloat( outerRadius - innerRadius );
   FastFloat radius; radius.setFromFloat( innerRadius + outerRadius - innerRadius );

   // calculate torus vertices
   const uint verticesCount = segmentsCount * segmentVerticesCount;
   std::vector<LitVertex> vertices( verticesCount );
   {
      FastFloat dMainAngle; dMainAngle.setFromFloat( DEG2RAD( 360.0f / (float)segmentsCount ) );
      FastFloat dSegmentAngle; dSegmentAngle.setFromFloat( DEG2RAD( 360.0f / (float)segmentVerticesCount ) );
      FastFloat mainAngle = Float_0;

      Quaternion mainRot, circumferenceRot;
      Vector vtxPos, posOnCircumference, radiusDisplacement, radiusVec, torusVtx;
      radiusVec.setMul( sideAxis, radius );
      uint vtxIdx = 0;
      for ( uint segmentIdx = 0; segmentIdx < segmentsCount; ++segmentIdx, mainAngle.add( dMainAngle ) )
      {
         mainRot.setAxisAngle( mainAxis, mainAngle );
         mainRot.transform( radiusVec, radiusDisplacement );

         FastFloat segmentAngle = Float_0;
         for ( uint segVtxIdx = 0; segVtxIdx < segmentVerticesCount; ++segVtxIdx, segmentAngle.add( dSegmentAngle ) )
         {
            circumferenceRot.setAxisAngle( circumferenceAxis, segmentAngle );
            Quaternion rotQ;
            rotQ.setMul( circumferenceRot, mainRot );

            // first - create a point on the circumference of the toruses' segment
            vtxPos.setMul( sideAxis, circumferenceWidth );
            rotQ.transform( vtxPos, posOnCircumference );

            // and displace the circumference point so that it ends up in its final position on the toruses' circumference
            torusVtx.setAdd( radiusDisplacement, posOnCircumference );
            torusVtx.add( origin );

            // store the vertex
            torusVtx.store( vertices[vtxIdx].m_coords );
            ++vtxIdx;
         }
      }
   }

   // set torus indices
   const uint outFacesCount = verticesCount * 2;
   std::vector<Face> outFaces( outFacesCount );
   {
      uint faceIdx = 0;
      for ( uint segmentIdx = 0; segmentIdx < segmentsCount; ++segmentIdx )
      {
         uint currSegmentFirstVtx = segmentIdx * segmentVerticesCount;
         uint nextSegmentFirstVtx = ( currSegmentFirstVtx + segmentVerticesCount ) % verticesCount;

         for ( uint segVtxIdx = 0; segVtxIdx < segmentVerticesCount; ++segVtxIdx )
         {
            uint skipOffset = 0;
            if ( segVtxIdx == 0 )
            {
               skipOffset = segmentVerticesCount;
            }

            outFaces[faceIdx].idx[0] = currSegmentFirstVtx + segVtxIdx - 1 + skipOffset;
            outFaces[faceIdx].idx[1] = currSegmentFirstVtx + segVtxIdx;
            outFaces[faceIdx].idx[2] = nextSegmentFirstVtx + segVtxIdx - 1 + skipOffset;
            ++faceIdx;

            outFaces[faceIdx].idx[0] = currSegmentFirstVtx + segVtxIdx;
            outFaces[faceIdx].idx[1] = nextSegmentFirstVtx + segVtxIdx;
            outFaces[faceIdx].idx[2] = nextSegmentFirstVtx + segVtxIdx - 1 + skipOffset;
            ++faceIdx;
         }
      }
   }

   TriangleMesh* mesh = new TriangleMesh( FilePath(), vertices, outFaces );
   return mesh;
}