Hello! I propose several new functions to "DarkGDK - Unofficial r114 update". I successfully use them in my game and I think they can be useful to others. Maybe WickedX will agree to include it in the "DarkGDK - Unofficial r114 update" code.
My testbed: CPU Intel i5-4670 3.4 GHz, Windows 7 x64, Visual C++ 2008 Express Edition, DirectX SDK (August 2007).
1) dbFastSqrt() -– Square root.
//Variant #1:
float dbFastSqrt (float n)
{
__asm{
fld n
fsqrt
}
}
//Variant #2:
double inline __declspec (naked) __fastcall dbFastSqrt (double n)
{
_asm fld qword ptr [esp+4]
_asm fsqrt
_asm ret 8
}
Usage example:
float fff = 0.00001f;
for (int i=0; i<10000000; i++) { fff += dbFastSqrt (fff); }
Using dbFastSqrt() with "Release configuration" gives me this result: speed of calling dbFastSqrt() is 21...26% from speed of calling sqrt(), i.e. 4 times faster.
You can choose any of the two variants. On my testbed both variants give the same speed, but
other people on other testbeds have the best speed in the second variant, so I personally use the second variant. (The second variant should be written in a .h file, and not in a .cpp file, because it uses "__declspec (naked)". )
Update (12 May 2014): in Variant #1 I changed "double" to "float", work good, as fast as with a "double".
2)
dbFind3DCoordinatesOn2DScreen() — Finding 3D coordinates (of any point on ground) on 2D screen for ordinary (non-orthogonal) camera.
void dbFind3DCoordinatesOn2DScreen (const int& mouseX, const int& mouseY, const float& cameraX, const float& cameraY, const float& cameraZ, float& X, float& Z)
{
dbPickScreen (mouseX, mouseY, -cameraY);
const float Y = dbGetPickVectorY();
X = dbGetPickVectorX();
Z = dbGetPickVectorZ();
X = X*(-cameraY)/Y + cameraX;
Z = Z*(-cameraY)/Y + cameraZ;
}
Usage example:
//X-axis and Z-axis is the ground. Y-axis is directed top. The camera is looking at the ground.
float cX=5.0f, cY=5.0f, cZ=5.0f;
dbPositionCamera (cX, cY, cZ);
dbPointCamera (cX, 0.0f, cZ);
int mX=dbMouseX(), mY=dbMouseY();
float x, z;
dbFind3DCoordinatesOn2DScreen (mX, mY, cX, cY, cZ, x, z);
//now 3D coordinates of ground under cursor are: (x, 0.0f, z)
I hope that WickedX will be able to embed this in the r114 source code so that to use the internal functions instead of dbPickScreen, dbGetPickVectorX, dbGetPickVectorY, dbGetPickVectorZ.
3)
dbFind2DCoordinatesFrom3DScene() — Finding 2D coordinates on screen of any 3D object (for camera 0). This piece of code extracted from the original DarkGDK source code, so it will be easy to get a user-accessible function.
void dbFind2DCoordinatesFrom3DScene (const float& X, const float& Y, const float& Z, const int& screenCenterX, const int& screenCenterY, int& screenX, int& screenY)
{
D3DXVECTOR3 vecBob;
vecBob.x=X; vecBob.y=Y; vecBob.z=Z;
// get current camera transformation matrices (camera 0)
D3DXMATRIX matTransform = dbGetViewMatrix(0) * dbGetProjectionMatrix(0);
// Transform object position from world-space to screen-space
D3DXVec3TransformCoord(&vecBob, &vecBob, &matTransform);
// Screen data
screenX=(vecBob.x+1.0f)*screenCenterX;
screenY=(1.0f-vecBob.y)*screenCenterY;
}
Usage example:
//center of the screen
int screenCX = GetSystemMetrics(SM_CXSCREEN)/2;
int screenCY = GetSystemMetrics(SM_CYSCREEN)/2;
//oX, oY, oZ – 3D coordinates of any object. mX, mY -- will be its coordinates on the screen.
int mX, mY;
dbFind2DCoordinatesFrom3DScene (oX, oY, oZ, screenCX, screenCY, mX, mY);
//now 2D coordinates on screen are: (mX, mY).