@ Niels Henriksen,
Should you be interested, and should we have overlapping areas in our respective projects, then maybe you might be interested in working together so that we can help each other, and progress faster..... just a though
.
As far as the terrain is concerned, here is my current relevant function.
void CreateWorld( void )
{
// make the 3D world
dbFogDistance ( 300000.0f ); // Give a 300KM sight distance
dbFogColor ( 100, 250 , 0 );// void dbFogColor ( int iG, int iB, 0 )....Red does not work
if (dbFogAvailable ( ))
dbFogOn ( );
dbColorBackdrop ( dbRGB ( 0, 100, 255 ));
// prepare land matrix memblock data
dbLoadImage ( "Terrainheightmap.bmp" , 2 );
dbMakeMemblockFromImage ( 7, 2 );
dbLoadImage ( "Terraincolormap.bmp", 4 );
dbMakeMemblockFromImage ( 8, 4 );
int WorldXNodes = dbMemblockDword ( 7, 0); // number of X direction nodes/pixels
int WorldZNodes = dbMemblockDword ( 7, 4); // number of Z direction nodes/pixels
int WorldColorDepth = dbMemblockDword ( 7, 8);
int WorldXSegments = WorldXNodes - 1;
int WorldZSegments = WorldZNodes - 1;
// make the water
dbLoadObject ( "TerrainWater.x", 4 );
dbPositionObject ( 4, -500000.0, 0.0, -500000.0 );
dbSetObjectFog ( 4, 0 );
dbSetObjectTransparency ( 4, 1);
dbGhostObjectOn ( 4);
// make to ocean floor
dbLoadObject ( "TerrainOceanBed.x", 3 );
dbPositionObject ( 3, -500000.0, -100, -500000.0 ); // have sunk it to -100meters
dbSetObjectFog ( 3, 0 );
// make the sun
/*************************************************************************
* The transparent sun mesh must be created after the ghost water mesh
* so that it will be rendered after the ghost water mesh
* provided we give it the same priority setting as the ghost water mesh
* If done the other way around, then the sun corona will show the
* ocean floor through it rather than the transparent water.
* *** THIS NO LONGER APPLIES ***
*************************************************************************/
dbLoadObject ( "TerrainSun.x", 5 );
dbLoadImage ( "TerrainSun.png" , 10 );
dbTextureObject ( 5, 10 );
dbPositionObject ( 5, 0.0, 1.0, 0.0 );
dbZRotateObject ( 5, 180.0f ); // turn sun to face down
dbFixObjectPivot ( 5 ); // fix sun default rotation
dbSetObjectEmissive ( 5, dbRGB( 255, 255, 255 ) ); // make it glow by itself
dbSetObjectTransparency ( 5, 1);
dbSetObjectFog ( 5, 0 );
// make the land matrix
/**************************************
* MUST REPLACE WITH A FEW *.X OBJECTS *
**************************************/
dbMakeMatrix ( 2, 25500, 25500, WorldXSegments, WorldZSegments ); // land is 25.5 Km by 25.5Km size
// raise each node to its correct height
for (int x = 0; x < WorldXNodes; x++ )
{
for (int y = 0; y < WorldZNodes; y++ )
{
int z = (WorldZNodes-1) - y;// Picture and mesh go opposite direction in the y / z values
dbSetMatrixHeight ( 2, x, z, 3 * dbMemblockByte ( 7, 12 + (WorldColorDepth / 8)*(x + (WorldXNodes * y)))-100);// using only value from one color & sit on ocean floor (-100 Z value)
}
}
// skin each mesh square
dbPositionMatrix ( 2, 0, 0, 0 );
dbPrepareMatrixTexture ( 2, 4, WorldXSegments, WorldZSegments );
for (int x = 0; x < WorldXSegments; x++ )
{
for (int y = 0; y < WorldZSegments; y++ )
{
int z = (WorldZSegments - 1) - y;
dbSetMatrixTile ( 2, x, z, x+1 + ((WorldXSegments) * y) );
}
}
dbUpdateMatrix ( 2 );
}
As far as the cameras are concerned, here are the data structures:
struct CameraParamaters {
float fPosX; //map co-ordinates
float fPosZ; //map co-ordinates
float fPosY; //map co-ordinates
float fRotX; //rotate around X axis ////////////////////////////////////////
float fRotZ; //rotate around Z axis // this gives the vector for camera //
float fRotY; //rotate around Y axis ////////////////////////////////////////
float fCurrentSpeed; // actual ground speed of camera // this with the aircraft vectors is used for doppler shift calculations
};
extern CameraParamaters Camera;
The data structure gets its data from the position and angles of the players aircraft.
The relevant camera code is,
void SetupCamera( void )
{
// Camera variables
float fHorizontalPixels = 1024.0;
float fVerticalPixels = 768.0;
float fAspect = fHorizontalPixels / fVerticalPixels;
float fFov = 1;// in radians *******
float fNear = 0.3f;
float fMiddle = 300.0f; // change over point between the 2 cameras
float fFar = 300000.0f;
float fAircraftRadius = 20.0f; // default radius aircraft cockpit view fits into.
dbMakeCamera(2);// create the cockpit camera (closest camera).
dbMakeCamera(1);// create the second camera.
dbSetCameraRange ( 2, fAircraftRadius / 1000, fAircraftRadius );
dbSetCameraRange ( 1, fNear, fMiddle );
dbSetCameraRange ( 0, fMiddle, fFar );
dbSetCameraAspect ( 2, fAspect );
dbSetCameraAspect ( 1, fAspect );
dbSetCameraAspect ( 0, fAspect );
dbSetCameraFOV ( 2, 180/3.14 );
dbSetCameraFOV ( 1, 180/3.14 );
dbSetCameraFOV ( 0, 180/3.14 );
/**********************************************************************************************************************
* Disable the backdrop of the closest cameras so we can see the content of the furthest camera behind it.
* REMEMBER.. cameras create their picture starting from lowest number camera sequentially upto highest numbered camera.
***********************************************************************************************************************/
dbBackdropOff(2);
dbBackdropOff(1);
//dbBackdropOff(0);
}
void PositionCamera( void )
{
/**********************************************************************************
* This is where camera position gets moved depending upon where gamer is situated
* Temporarily we will lock camera to the players aircraft
* Later we will also include floating free camera mode
* hide aircraft model belonging to this machine
* as we are using 2D cockpit views
**********************************************************************************/
dbHideObject ( iThisMachinePlayerID + 10 );//Aircraft IDs are 10 higher
Camera.fPosZ = Aircraft[ iThisMachinePlayerID ].fPosZ;
Camera.fPosY = Aircraft[ iThisMachinePlayerID ].fPosY;
Camera.fPosX = Aircraft[ iThisMachinePlayerID ].fPosX;
Camera.fRotZ = Aircraft[ iThisMachinePlayerID ].fRotZ;
Camera.fRotY = Aircraft[ iThisMachinePlayerID ].fRotY;
Camera.fRotX = Aircraft[ iThisMachinePlayerID ].fRotX;
Camera.fCurrentSpeed = Aircraft[ iThisMachinePlayerID ].fCurrentSpeed;
dbPositionCamera ( 0, Camera.fPosX, Camera.fPosY , Camera.fPosZ);
dbPositionCamera ( 1, Camera.fPosX, Camera.fPosY , Camera.fPosZ);
dbPositionCamera ( 2, 0.0, -49.6 , 0.0); // cockpit camera always only pivets arounf world ZERO -50m depth position
dbRotateCamera ( 0, Camera.fRotX, Camera.fRotY, Camera.fRotZ );
dbRotateCamera ( 1, Camera.fRotX, Camera.fRotY, Camera.fRotZ );
dbRotateCamera ( 2, 0.0, 0.0, 0.0 ); // default camera view unless pilot changes head
/***********************************************************
* Also position sun above camera location 250 meter higher
***********************************************************/
dbPositionObject ( 5, Camera.fPosX , Camera.fPosY + 250 , Camera.fPosZ ); // sun object above
}
void CameraPilotView( int iViewDirection )
{
/********************************************************************************************************
* Decide upon what cockpit view to show depending upon joystick tophat
* Some drivers report the centered position of the POV indicator as 65,535.
* We will use the "default" setting for center finding so the actual value 0 or 0xFFFF does not matter.
*********************************************************************************************************/
switch ( iViewDirection )
{
case 0:
//dbPasteImage ( 909, 0, 0, 1);//update 2D cockpit to Up
// code here to repoint camera
dbPitchCameraUp (0, 50.0f );
dbPitchCameraUp (1, 50.0f );
dbPitchCameraUp (2, 50.0f );
break;
case 4500:
//dbPasteImage ( 904, 0, 0, 1);//update 2D cockpit to Right 45 Front
// code here to repoint camera
dbTurnCameraRight (0, 45.0f );
dbTurnCameraRight (1, 45.0f );
dbTurnCameraRight (2, 45.0f );
break;
case 9000:
//dbPasteImage ( 906, 0, 0, 1);//update 2D cockpit to Right
// code here to repoint camera
dbTurnCameraRight (0, 90.0f );
dbTurnCameraRight (1, 90.0f );
dbTurnCameraRight (2, 90.0f );
break;
case 13500:
//dbPasteImage ( 908, 0, 0, 1);//update 2D cockpit to Right 45 Back
// code here to repoint camera
dbTurnCameraRight (0, 135.0f );
dbTurnCameraRight (1, 135.0f );
dbTurnCameraRight (2, 135.0f );
break;
case 18000:
//dbPasteImage ( 901, 0, -330, 1);//update 2D cockpit to Front
// code here to repoint camera
dbPitchCameraUp (0, -27.0f );
dbPitchCameraUp (1, -27.0f );
dbPitchCameraUp (2, -27.0f );
break;
case 22500:
//dbPasteImage ( 907, 0, 0, 1);//update 2D cockpit to Left 45 Back
// code here to repoint camera
dbTurnCameraRight (0, -135.0f );
dbTurnCameraRight (1, -135.0f );
dbTurnCameraRight (2, -135.0f );
break;
case 27000:
//dbPasteImage ( 905, 0, 0, 1);//update 2D cockpit to Left
// code here to repoint camera
dbTurnCameraRight (0, -90.0f );
dbTurnCameraRight (1, -90.0f );
dbTurnCameraRight (2, -90.0f );
break;
case 31500:
//dbPasteImage ( 903, 0, 0, 1);//update 2D cockpit to Left 45 Front
// code here to repoint camera
dbTurnCameraRight (0, -45.0f );
dbTurnCameraRight (1, -45.0f );
dbTurnCameraRight (2, -45.0f );
break;
default:
;//dbPasteImage ( 901, 0, 0, 1);//update 2D cockpit to Front
// code here to repoint camera is not necessary as camera is already pointing in correct direction
}
}
void ScreenCapture(void)
{
char TempStr [ 128 ];
char TempStr2 [ 128 ];
int image_iID = 65535;
int static iPictureTaken;
//Control picture taking so it happens only once every key press.
if ((dbScanCode ( ) == DIK_SYSRQ) && (!iPictureTaken) )
{
// Build the Picture file name
strcpy( TempStr, "Pict");
strcpy( TempStr2, dbGetDate$( ));
TempStr2 [2] = TempStr2 [3];
TempStr2 [3] = TempStr2 [4];
TempStr2 [4] = TempStr2 [6];
TempStr2 [5] = TempStr2 [7];
TempStr2 [6] = TempStr2 [8];
strcat( TempStr, TempStr2);
strcpy( TempStr2, dbGetTime$( ));
TempStr2 [2] = TempStr2 [3];
TempStr2 [3] = TempStr2 [4];
TempStr2 [4] = TempStr2 [6];
TempStr2 [5] = TempStr2 [7];
TempStr2 [6] = TempStr2 [8];
strcat( TempStr, TempStr2);
strcat( TempStr, ".JPG");
//Get the picture, save it and clean up used resources
dbGetImage(image_iID,0,0,dbScreenWidth(),dbScreenHeight(),1);
dbSaveImage(TempStr,image_iID,0);
dbDeleteImage(image_iID);
//Set the picture taken flag
iPictureTaken = 1;
}
if ( (dbScanCode ( ) != DIK_SYSRQ) && (iPictureTaken) )
{
//Clear the picture taken flag
iPictureTaken = 0;
}
}
Camera 0 and 1 fly around the real world and view what the player eyes would be viewing.
Camera 2 sits at eye level over a cockpit model and these are currently at 0,0,-50 . this camera sits there and only rotates regarding how the pilots view changes with regard to the view of the cockpit.
The screen is made up from firstly the view that the long range camera displays, then it is overlaid by what the close range camera sees, and this is overlaid by the cockpit camera view.
I am looking into refining the terrain code a bit further by creating a very limited ocean mesh and ocean floor mesh and moving it around within the field of view of the camera (there is no point in having a huge ocean model where most of it is not being viewed at any given point in time). I am still having some troubles with my "void EulerToMatrix( struct Euler Rotation )" and the interpreting of its data to get the true aircraft "Pitch" irrelevant to the aircraft "Yaw" so that I can keep the mini ocean mesh within view. It may just be that I may have to use double precision calculations within my maths code as it may just be a problem of inaccuracies with single precision calculations. ..... will see soon enough.
Anyway hope this gives you something to think about
.