3D Vector Functions

Share Your Own Code Samples With the World

Moderators: g3nuin3, SpeedWing, WhiteHat, mezzo

3D Vector Functions

Postby L. Spiro » Mon Dec 29, 2008 6:58 am

NOTICE: MHS 5.006 or above is required for these functions to work properly in L. Spiro Script. If you wish to use them in any other version, change function parameters from FLOAT to DOUBLE.

When I am working on 3D games I find it useful to have a set of 3D math functions available for testing things.
I decided to convert all of the DirectX math functions. I considered adding these to the API which would of course provide better performance, but I decided it would be more fun to use my language and to make them open-source. They may later be added as API functions.

I often see people looking for code for a certain matrix/vector function (for example D3DXVec3Hermite) because they wish to make their own math libraries instead of linking to DirectX and making their projects rely heavily on linking to a large bulky library that works only on one platform.

So here are all of the purely D3DXVECTOR3 (VECTOR3 here) functions in DirectX. By “pure” I mean functions that relate entirely to vectors, not matrices/planes/etc.


This file can be used as-is in C, C++, and L. Spiro Script.
The names are all the same as in DirectX with the “D3DX” removed.


Vector3.h:
Code: Select all
#pragma once

#ifdef _WIN32
#define MemCpy   CopyMemory
#define Sqrt   sqrtf
#endif

typedef struct VECTOR3 {
   FLOAT x;
   FLOAT y;
   FLOAT z;
} * LPVECTOR3;
typedef struct VECTOR3 VECTOR3;


// Adds two 3D vectors.
VECTOR3 * Vec3Add( VECTOR3 * pvOut, const VECTOR3 * pvV1, const VECTOR3 * pvV2 ) {
   pvOut->x = pvV1->x + pvV2->x;
   pvOut->y = pvV1->y + pvV2->y;
   pvOut->z = pvV1->z + pvV2->z;
   return pvOut;
}

// Subtracts two 3D vectors.
VECTOR3 * Vec3Subtract( VECTOR3 * pvOut, const VECTOR3 * pvV1, const VECTOR3 * pvV2 ) {
   pvOut->x = pvV1->x - pvV2->x;
   pvOut->y = pvV1->y - pvV2->y;
   pvOut->z = pvV1->z - pvV2->z;
   return pvOut;
}

// Returns the square of the length of a 3D vector
FLOAT Vec3LengthSq( const VECTOR3 * pvV ) {
   return pvV->x * pvV->x + pvV->y * pvV->y + pvV->z * pvV->z;
}

// Returns the length of a 3D vector
FLOAT Vec3Length( const VECTOR3 * pvV ) {
   return Sqrt( pvV->x * pvV->x + pvV->y * pvV->y + pvV->z * pvV->z );
}

// Determines the cross-product of two 3D vectors.
VECTOR3 * Vec3Cross( VECTOR3 * pvOut, const VECTOR3 * pvV1, const VECTOR3 * pvV2 ) {
   VECTOR3 vRet;

   vRet.x = pvV1->y * pvV2->z - pvV1->z * pvV2->y;
   vRet.y = pvV1->z * pvV2->x - pvV1->x * pvV2->z;
   vRet.z = pvV1->x * pvV2->y - pvV1->y * pvV2->x;

   MemCpy( pvOut, &vRet, sizeof( VECTOR3 ) );
   return pvOut;
}

// Determines the dot product of two 3D vectors.
FLOAT Vec3Dot( const VECTOR3 * pvV1, const VECTOR3 * pvV2 ) {
   return pvV1->x * pvV2->x + pvV1->y * pvV2->y + pvV1->z * pvV2->z;
}

// Scales a 3D vector.
VECTOR3 * Vec3Scale( VECTOR3 * pvOut, const VECTOR3 * pvV, FLOAT fS ) {
   pvOut->x = pvV->x * fS;
   pvOut->y = pvV->y * fS;
   pvOut->z = pvV->z * fS;
   return pvOut;
}

// Returns the normalized version of a 3D vector.
VECTOR3 * Vec3Normalize( VECTOR3 * pvOut, const VECTOR3 * pvV ) {
   FLOAT fLen = Vec3LengthSq( pvV );
   if ( fLen > 0.0000001f ) {
      Vec3Scale( pvOut, pvV, 1.0f / Sqrt( fLen ) );
      return pvOut;
   }
   return pvOut;
}

// Returns a 3D vector that is made up of the largest components of two 3D vectors.
VECTOR3 * Vec3Maximize( VECTOR3 * pvOut, const VECTOR3 * pvV1, const VECTOR3 * pvV2 ) {
   pvOut->x = pvV1->x > pvV2->x ? pvV1->x : pvV2->x;
   pvOut->y = pvV1->y > pvV2->y ? pvV1->y : pvV2->y;
   pvOut->z = pvV1->z > pvV2->z ? pvV1->z : pvV2->z;
   return pvOut;
}

// Returns a 3D vector that is made up of the smallest components of two 3D vectors
VECTOR3 * Vec3Minimize( VECTOR3 * pvOut, const VECTOR3 * pvV1, const VECTOR3 * pvV2 ) {
   pvOut->x = pvV1->x < pvV2->x ? pvV1->x : pvV2->x;
   pvOut->y = pvV1->y < pvV2->y ? pvV1->y : pvV2->y;
   pvOut->z = pvV1->z < pvV2->z ? pvV1->z : pvV2->z;
   return pvOut;
}

// Performs a linear interpolation between two 3D vectors.
VECTOR3 * Vec3Lerp( VECTOR3 * pvOut, const VECTOR3 * pvV1, const VECTOR3 * pvV2, FLOAT fS ) {
   return Vec3Add( pvOut, Vec3Scale( pvOut, Vec3Subtract( pvOut, pvV2, pvV1 ), fS ), pvV1 );
}

// Performs a Hermite spline interpolation using the specified 3D vectors.
VECTOR3 * Vec3Hermite( VECTOR3 * pvOut, const VECTOR3 * pvV1, const VECTOR3 * pvT1, const VECTOR3 * pvV2, const VECTOR3 * pvT2, FLOAT fS ) {
   FLOAT fS2   = fS * fS;
   FLOAT fS3   = fS2 * fS;
   FLOAT f2s2   = 2.0f * fS2;
   FLOAT f2s3   = 2.0f * fS3;
   FLOAT f3s2   = 3.0f * fS2;
   
   VECTOR3 vTemp1;
   VECTOR3 vTemp2;
   VECTOR3 vTemp3;
   VECTOR3 vTemp4;
   VECTOR3 vTemp5;
   VECTOR3 vTemp6;
   
   
   Vec3Scale( &vTemp1, pvV1, f2s3 - f3s2 + 1.0f );
   Vec3Scale( &vTemp3, pvV2, -f2s3 + f3s2 );
   Vec3Scale( &vTemp5, pvT1, fS3 - f2s2 + fS );
   Vec3Scale( &vTemp6, pvT2, fS3 - fS2 );
   
   return Vec3Add( pvOut, &vTemp1,
      Vec3Add( &vTemp2, &vTemp3,
      Vec3Add( &vTemp4, &vTemp5,
      &vTemp6 ) ) );
}

// Performs a Catmull-Rom interpolation using the specified 3D vectors.
VECTOR3 * Vec3CatmullRom( VECTOR3 * pvOut, const VECTOR3 * pvV1, const VECTOR3 * pvV2, const VECTOR3 * pvV3, const VECTOR3 * pvV4, FLOAT fS ) {
   VECTOR3 vT1;
   VECTOR3 vT2;
   
   Vec3Subtract( &vT1, pvV3, pvV1 );
   Vec3Scale( &vT1, &vT1, 0.5f );
   
   Vec3Subtract( &vT2, pvV4, pvV2 );
   Vec3Scale( &vT2, &vT2, 0.5f );
   
   return Vec3Hermite( pvOut, pvV2, &vT1, pvV3, &vT2, fS );
}

// Returns a point in Barycentric coordinates, using the specified 3D vectors.
VECTOR3 * Vec3BaryCentric( VECTOR3 * pvOut, const VECTOR3 * pvV1, const VECTOR3 * pvV2, const VECTOR3 * pvV3, FLOAT fF, FLOAT fG ) {
   VECTOR3 vP1;
   VECTOR3 vP2;
   
   Vec3Subtract( &vP1, pvV2, pvV1 );
   Vec3Scale( &vP1, &vP1, fF );
   
   Vec3Subtract( &vP2, pvV3, pvV1 );
   Vec3Scale( &vP2, &vP2, fG );

   VECTOR3 vP3;
   return Vec3Add( pvOut, pvV1, Vec3Add( &vP3, &vP1, &vP2 ) );
}



Matrix functions will come later. I have already rewritten most of them.


L. Spiro
Our songs remind you of songs you’ve never heard.
User avatar
L. Spiro
L. Spiro
 
Posts: 3129
Joined: Mon Jul 17, 2006 10:14 pm
Location: Tokyo, Japan

Return to Code Submissions

Who is online

Users browsing this forum: No registered users and 0 guests