May 02, 2024, 06:09:28 AM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


3D starfield

Started by Ionic Wind Support Team, August 08, 2006, 04:26:37 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Ionic Wind Support Team

Someone asked if it was possible to use point lists with the engine in it's current starte.  And the answer is yes. 

This bit of code creates randomly colored points in 3D space, and a planet to give it a bit of a flair.


//An example using a point list to draw a starfield.
//Arrow keys to move camera.
//PgUp/PgDn to pan up and down.
//Z and X to rotate on Z axis.

declare import,timeGetTime(),int;

//Our FVF structure for points
struct point_vertex{
VECTOR3 pos;
DWORD color;        // The vertex colour.
};

#define point_fvf D3DFVF_XYZ|D3DFVF_DIFFUSE
#define num_points 5000
global sub main()
{
C3DScreen s;
C3DCamera c;
C3DMesh m;
C3DMesh planet;
C3DObject scene;
C3DLight light;
CDirectInput di;
float fadjust,fTarget;
//target 60FPS for camera movement
fTarget = 1.0f / /*FPS*/60.0f * 1000.0f;
fAdjust = 1.0f;

s.CreateWindowed(0,0,640,480,AWS_CAPTION|AWS_VISIBLE|AWS_SIZE|AWS_CENTERED,0,"3D Points - ESC exits",NULL,false);
di.Init(s);
c.Create(s);
c.Position(0,0,-50);
c.Orient(0,0,1,0,1,0);
c.SetBackPlane(1000);

s.Clear(RGBA(0,0,0,255));
s.BeginScene(c);
s.RenderText(0,10,"Loading objects...",RGBA(255,255,0,255));
s.RenderScene();

//create a point mesh with 'num_points' points.
m.CreateMeshEx(s,D3DPT_POINTLIST,num_points,num_points,num_points,point_fvf);
//Lock the vertex and index buffers so we can write to them.
point_vertex *v = m.LockVertexBuffer();
word *idx = m.LockIndexBuffer();
for(int x=0;x < num_points;x++)
{
*idx = x;
v->pos.x = rnd(-100,100);
v->pos.y = rnd(-100,100);
v->pos.z = rnd(-100,100);
v->color = RGBA(rnd(100,255),rnd(100,255),rnd(100,255),255);
v+=len(point_vertex);
idx+=len(word);
}
m.UnlockVertexBuffer();
m.UnlockIndexBuffer();
m.EnableLighting(false);
m.UseVertexColor(true);
m.SetVisible(true);

planet.CreateSphere(s,25,5.0,false);
planet.LoadTexture(0,GetStartPath()+"media\\tile3.tga",0);

light.Create(s,LIGHT_POINT,1);
light.Position(-80,20,-150);
light.SetAttenuation(0,1/200.0,0);
light.SetSpecular(.5,.5,.5,1);
light.SetAmbient(.4,.4,.4,1);

scene.CreateScene(s);
scene.AddChild(light);
scene.AddChild(m);
scene.AddChild(planet);
int fps = 0;
int startTime;
do
{
startTime = timeGetTime();
//check for keys and move camera accordingly
IF di.KeyDown(DIK_UP)
c.Move(0.0f,.25f * fAdjust);
IF di.KeyDown(DIK_DOWN)
c.Move(0.0f,-.25f * fAdjust);
IF di.KeyDown(DIK_RIGHT)
c.Rotate(1*.01745 * fAdjust,0,0);
IF di.KeyDown(DIK_LEFT)
c.Rotate(-1*.01745 * fAdjust,0,0);
IF di.KeyDown(DIK_Z)
c.Rotate(0,0,-1 *.01745 * fAdjust);
IF di.KeyDown(DIK_X)
c.Rotate(0,0,1 *.01745 * fAdjust);
IF di.KeyDown(DIK_PRIOR)
c.Rotate(0,-1 *.01745 * fAdjust,0);
IF di.KeyDown(DIK_NEXT)
c.Rotate(0,1 *.01745 * fAdjust,0);
IF di.KeyDown(DIK_R)
c.LookAt(0,0,0);

planet.Rotate(0,startTime / 2000.0f,0);

s.Clear(RGBA(0,0,0,255));
s.BeginScene(c);
scene.Draw();
s.RenderText(0,10,"FPS:"+NumToStr(fps),RGBA(255,255,0,255));
s.RenderText(0,30,"Use arrow keys,PgUp,PgDn to move around",RGBA(255,255,0,255));
fps = s.RenderScene();
fAdjust = (timeGetTime() - startTime) / fTarget;
}until di.KeyDown(DIK_ESCAPE);
Scene.Free();
}
Ionic Wind Support Team

kryton9

August 08, 2006, 04:56:13 PM #1 Last Edit: August 08, 2006, 04:59:32 PM by kryton9
Keep them coming Paul, that is nice. Will definitly come in very handy!! Just by bumping the random from 100 to 1000, the points are farther away and so far I haven't had any near the planet.

I like how you positioned the light so it really lights up the planet nicely and gives a very nice look from many different angles too!!

Ionic Wind Support Team

Wanted just a hint of a shadow on the planet, so moved the light down the X axis a bit.
Ionic Wind Support Team

Ionic Wind Support Team

And using a +/- 1000 does make it a bit more realistic ;)
Ionic Wind Support Team

kryton9

Well, with all the goodies so far, I got enough to keep me busy for awhile. The sprites are going to allow some cool things to happen. I am eager to start, but trying to get a handle on pointers and classes before I start :)

John S

August 08, 2006, 07:13:19 PM #5 Last Edit: August 08, 2006, 07:43:50 PM by John S
Paul, that's a neat example.

when you drag the window's edge to stretch it bigger,  the planet and space warps/stretches.
can you scale the image and remaining borders to suit the dragging of the border?

Also, how do you return the global xyz position and global xyz looking direction of the camera?  I want to add that so I can find my way back to the planet easier.
John Siino, Advanced Engineering Services and Software

Ionic Wind Support Team

Just press the R key.  That resets the lookat point to 0,0,0 and you'll be facing the planet.

You can get all of the camera's paramters.  See Aurora 3D Users Guide->Classes->C3DCamera->Methods.

GetPosition
GetDirection
GetUpVector
GetLookAt

Quote
can you scale the image and remaining borders to suit the dragging of the border?

Not currently.   The final version will have an option to change the backbuffer size in response to an OnSize message.

Ionic Wind Support Team

John S

August 08, 2006, 08:13:58 PM #7 Last Edit: August 08, 2006, 10:31:17 PM by John S
Thanks,
I'm playing around with it.  I found the X, Z and R controls and I added A and S.
I'm tweaking the starfield size ("fieldwidth"), color and backdrop and I'm adding position and heading info:

1st edit:   editted to add functions and output position and heading (still need to tweak heading output)
2nd edit:  editted to modify heading output to read degrees, repositioned the light source to shine from the y-axis
              and made planet rotate about z-axit.  I slowed the planets rotation abit and sped up the camera movement in and out.
3rd edit:   fixed heading to reflect correct heading unit vector


// starfield.src
// An example using a point list to draw a starfield.
// Arrow keys to move camera.
// PgUp/PgDn to pan up and down.
// Z and X to rotate on Z axis.

declare import,timeGetTime(),int;

//Our FVF structure for points
struct point_vertex{
   VECTOR3 pos;
   DWORD color;        // The vertex colour.
};

VECTOR3 c_ps, c_hd, c_up;      // camera position & heading

#define point_fvf D3DFVF_XYZ|D3DFVF_DIFFUSE
#define num_points 20000
#define fieldwidth 1000

global sub main()
{
C3DScreen s;
C3DCamera c;
C3DMesh m;
C3DMesh planet;
C3DObject scene;
C3DLight light;
CDirectInput di;

float fadjust,fTarget;

//target 60FPS for camera movement
fTarget = 1.0f / /*FPS*/60.0f * 1000.0f;
fAdjust = 1.0f;

s.CreateWindowed(0,0,640,480,AWS_CAPTION|AWS_VISIBLE|AWS_SIZE|AWS_CENTERED,0,"3D Points - ESC exits",NULL,false);
di.Init(s);

c.Create(s);
c.Position(0,0,-50);
c.Orient(0,0,1,0,1,0);
c.SetBackPlane(1.75*fieldwidth);

s.Clear(RGBA(0,0,0,255));
s.BeginScene(c);
s.RenderText(0,10,"Loading objects...",RGBA(255,255,0,255));
s.RenderScene();

//create a point mesh with 'num_points' points.
m.CreateMeshEx(s,D3DPT_POINTLIST,num_points,num_points,num_points,point_fvf);

//Lock the vertex and index buffers so we can write to them.
point_vertex *v = m.LockVertexBuffer();
word *idx = m.LockIndexBuffer();
for(int x=0;x < num_points;x++)
{
   *idx = x;
   v->pos.x = rnd(-fieldwidth,fieldwidth);
   v->pos.y = rnd(-fieldwidth,fieldwidth);
   v->pos.z = rnd(-fieldwidth,fieldwidth);
   v->color = RGBA(rnd(140,255),rnd(140,255),rnd(140,255),255);
   v+=len(point_vertex);
   idx+=len(word);
}

m.UnlockVertexBuffer();
m.UnlockIndexBuffer();
m.EnableLighting(false);
m.UseVertexColor(true);
m.SetVisible(true);

planet.CreateSphere(s,25,5.0,false);
planet.LoadTexture(0,GetStartPath()+"media\\tile3.tga",0);

light.Create(s,LIGHT_POINT,1);
light.Position(950,0,0);
light.SetAttenuation(0,1/2000.0,0);
light.SetSpecular(.5,.5,.5,1);
light.SetAmbient(.15,.15,.15,1);

scene.CreateScene(s);
scene.AddChild(light);
scene.AddChild(m);
scene.AddChild(planet);

int fps = 0;
int startTime;

do
{
   startTime = timeGetTime();
   
//  Position, Heading & Up Vectors of Camera
   c_ps = c.GetPosition();
   c_up = c.GetUpVector();
   c_hd = c.GetDirection();

//check for keys and move camera accordingly
   IF di.KeyDown(DIK_UP)
   c.Move(0.0f,.75f * fAdjust);
   IF di.KeyDown(DIK_DOWN)
   c.Move(0.0f,-.75f * fAdjust);
   IF di.KeyDown(DIK_RIGHT)
   c.Rotate(1*.0174533 * fAdjust,0,0);
   IF di.KeyDown(DIK_LEFT)
   c.Rotate(-1*.0174533 * fAdjust,0,0);
   IF di.KeyDown(DIK_Z)
   c.Rotate(0,0,-1 *.0174533 * fAdjust);
   IF di.KeyDown(DIK_X)
   c.Rotate(0,0,1 *.0174533 * fAdjust);
   IF di.KeyDown(DIK_PRIOR)
   c.Rotate(0,-1 *.0174533 * fAdjust,0);
   IF di.KeyDown(DIK_NEXT)
   c.Rotate(0,1 *.0174533 * fAdjust,0);
   IF di.KeyDown(DIK_R)
   c.LookAt(0,0,0);

   IF di.KeyDown(DIK_A)
   c.Move(-.5f * fAdjust, 0.0f);

   IF di.KeyDown(DIK_S)
   c.Move( .5f * fAdjust, 0.0f);

   planet.Rotate(0,0,startTime / 6000.0f);

   s.Clear(RGBA(0,0,0,255));
   s.BeginScene(c);
   scene.Draw();

   s.RenderText(10,10,"FPS: "+NumToStr(fps),RGBA(255,255,0,255));

   s.RenderText(85,10,"Position:  "+NumToStr(c_ps.x)+",  "+NumToStr(c_ps.y)+",  "+NumToStr(c_ps.z),RGBA(255,255,0,255));
   s.RenderText(230,10,"Heading:  "+NumToStr(c_hd.x, 3)+",  "+NumToStr(c_hd.y, 3)+",  "+NumToStr(c_hd.z, 3),RGBA(255,255,0,255));

   s.RenderText(450,10,"Up:",RGBA(255,255,0,255));
   s.RenderText(500,10,NumToStr(c_up.x, 2)+",  "+NumToStr(c_up.y, 2)+",  "+NumToStr(c_up.z, 2),RGBA(255,255,0,255));

   s.RenderText(10,425,"Use arrow keys, PgUp, PgDn, A, S, Z, X, R to move around",RGBA(255,255,0,255));

   fps = s.RenderScene();
   fAdjust = (timeGetTime() - startTime) / fTarget;
   }until di.KeyDown(DIK_ESCAPE);

Scene.Free();
}
John Siino, Advanced Engineering Services and Software

kryton9

Cool, some more interested in this stuff and playing and sharing, thanks.

John S

I editted it again just before or after your reply.  The heading output isn't working yet
John Siino, Advanced Engineering Services and Software

kryton9

Yep, got the new one. I had the same problem, you have to use USING to display floating numbers correctly.

This:
s.RenderText(450,10,"Heading:  "+NumToStr(c_hd.x)+" ,  "+NumToStr(c_hd.y)+" ,  "+NumToStr(c_hd.z),RGBA(255,255,0,255));

Will need to be something like this:
headingText = USING("& x:%f###.##  y:%f###.##  z:%f###.##","Heading ",c_hd.x,c_hd.y,c_hd.z);
s.RenderText(450,10,headingText);

Ionic Wind Support Team

No you don't.  Just use the optional parameter of NumToStr.

NumToStr(c_hd.x, 3)

Which specifies the number of decimal places.
Ionic Wind Support Team

J B Wood (Zumwalt)

Beat me to the punch on that. The second parameter is number of places, look at the tank demo. I am using the place holder.

John S

that gives the direction in unit vector doesn't it?
I'm now using GetDirection and converting to degrees.
I have also changed the rotation of the planet about the z axis and put the light source on the y-axis.
John Siino, Advanced Engineering Services and Software

kryton9

Paul you told me to use using when I had a similar question, wow it is lots easier with that optional parameter :)

John S

Kryton9

check out the last edit
John Siino, Advanced Engineering Services and Software

kryton9

August 08, 2006, 09:08:31 PM #16 Last Edit: August 08, 2006, 09:11:16 PM by kryton9
Got it and playing, here is a goodie to say thanks for joining in on the fun, you can go wild with this stuff, enjoy, can't wait to see.

http://www.cortland.edu/flteach/civ/DavidWeb/resources.htm

Click on the planets to get the files from this site:
http://planetpixelemporium.com/earth.html

John S

Paul,
I was looking at the GetUpVector method.  Can I use that to determine the cameras rotation? 
When using the X & Z controls, I still want A & S to slide the camera in the right and left direction.
John Siino, Advanced Engineering Services and Software

Ionic Wind Support Team

The UP and Direction vector describe a 3D objects orientation in space.  You can determine the X axis vextor by using the Vec3Cross function. 

vxaxis = Vec3Cross(up, direction);

Ionic Wind Support Team

John S

Paul,
I fixed the heading to reflect the unit vector output.

When I use the A & S controls to move the camera left or right after I rotate (using the Z & X controls) the camera does not slide left or right, but goes off in the global x and -x directions.  Is this a bug?

here is the code snippet:

   IF di.KeyDown(DIK_A)
   c.Move(-.5f * fAdjust, 0.0f);

   IF di.KeyDown(DIK_S)
   c.Move( .5f * fAdjust, 0.0f);

I'm going to have to pull out my Linear Algebra books to refresh my vector math  ;)
I take it that all of the methods are floating point?  Can they be cast to double precision?
John Siino, Advanced Engineering Services and Software

Ionic Wind Support Team

DirectX only uses floats. 
Ionic Wind Support Team

Ionic Wind Support Team

And it might be a bug.  Have to look into my original intentions ;)
Ionic Wind Support Team

kryton9

August 08, 2006, 10:54:22 PM #22 Last Edit: August 08, 2006, 10:57:30 PM by kryton9
This is sort of working, but not putting out the values constantly, my brain is fried at this point, will sleep on it, but maybe fresh eyes can catch what I am missing.

But it is giving it seems correct readings in 360 degrees when it does report :)

Forgot to mention I am just giving the calculation by using 0,0,0 as the other point, so I just need the one point to test it out

Also, I was lazy and just put the orientation where the x direction would be printed, so don't let that fool you.

// starfield.src
// An example using a point list to draw a starfield.
// Arrow keys to move camera.
// PgUp/PgDn to pan up and down.
// Z and X to rotate on Z axis.

declare import,timeGetTime(),int;

//Our FVF structure for points
struct point_vertex{
VECTOR3 pos;
DWORD color; ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ, // The vertex colour.
};

VECTOR3 c_ps, c_hd; // camera position & heading

#define point_fvf D3DFVF_XYZ|D3DFVF_DIFFUSE
#define num_points 20000
#define fieldwidth 1000
point pt;
global sub main()
{
C3DScreen s;
C3DCamera c;
C3DMesh m;
C3DMesh planet;
C3DObject scene;
C3DLight light;
CDirectInput di;

float fadjust,fTarget;

//target 60FPS for camera movement
fTarget = 1.0f / /*FPS*/60.0f * 1000.0f;
fAdjust = 1.0f;

s.CreateWindowed(0,0,640,480,AWS_CAPTION|AWS_VISIBLE|AWS_SIZE|AWS_CENTERED,0,"3D Points - ESC exits",NULL,false);
di.Init(s);

c.Create(s);
c.Position(0,0,-50);
c.Orient(0,0,1,0,1,0);
c.SetBackPlane(1.75*fieldwidth);

s.Clear(RGBA(0,0,0,255));
s.BeginScene(c);
s.RenderText(0,10,"Loading objects...",RGBA(255,255,0,255));
s.RenderScene();

//create a point mesh with 'num_points' points.
m.CreateMeshEx(s,D3DPT_POINTLIST,num_points,num_points,num_points,point_fvf);

//Lock the vertex and index buffers so we can write to them.
point_vertex *v = m.LockVertexBuffer();
word *idx = m.LockIndexBuffer();
for(int x=0;x < num_points;x++)
{
*idx = x;
v->pos.x = rnd(-fieldwidth,fieldwidth);
v->pos.y = rnd(-fieldwidth,fieldwidth);
v->pos.z = rnd(-fieldwidth,fieldwidth);
v->color = RGBA(rnd(140,255),rnd(140,255),rnd(140,255),255);
v+=len(point_vertex);
idx+=len(word);
}

m.UnlockVertexBuffer();
m.UnlockIndexBuffer();
m.EnableLighting(false);
m.UseVertexColor(true);
m.SetVisible(true);

planet.CreateSphere(s,25,5.0,false);
planet.LoadTexture(0,GetStartPath()+"media\\tile3.tga",0);

light.Create(s,LIGHT_POINT,1);
light.Position(100,0,0);
light.SetAttenuation(0,1/200.0,0);
light.SetSpecular(.5,.5,.5,1);
light.SetAmbient(.15,.15,.15,1);

scene.CreateScene(s);
scene.AddChild(light);
scene.AddChild(m);
scene.AddChild(planet);

int fps = 0;
int startTime;

do
{
startTime = timeGetTime();
//check for keys and move camera accordingly
IF di.KeyDown(DIK_UP)
c.Move(0.0f,.75f * fAdjust);
IF di.KeyDown(DIK_DOWN)
c.Move(0.0f,-.75f * fAdjust);
IF di.KeyDown(DIK_RIGHT)
c.Rotate(1*.01745 * fAdjust,0,0);
IF di.KeyDown(DIK_LEFT)
c.Rotate(-1*.01745 * fAdjust,0,0);
IF di.KeyDown(DIK_Z)
c.Rotate(0,0,-1 *.01745 * fAdjust);
IF di.KeyDown(DIK_X)
c.Rotate(0,0,1 *.01745 * fAdjust);
IF di.KeyDown(DIK_PRIOR)
c.Rotate(0,-1 *.01745 * fAdjust,0);
IF di.KeyDown(DIK_NEXT)
c.Rotate(0,1 *.01745 * fAdjust,0);
IF di.KeyDown(DIK_R)
c.LookAt(0,0,0);

IF di.KeyDown(DIK_A)
c.Move(-.5f * fAdjust,0.0f);
IF di.KeyDown(DIK_S)
c.Move( .5f * fAdjust,0.0f);

planet.Rotate(0,0,startTime / 6000.0f);

s.Clear(RGBA(0,0,0,255));
s.BeginScene(c);
scene.Draw();

s.RenderText(10,10,"FPS: "+NumToStr(fps),RGBA(255,255,0,255));

// ÂÃ, Position & Heading Vectors of Camera
c_ps = c.GetPosition();
c_hd ÂÃ, = c.GetDirection();
pt.x=c_hd.x;pt.y=c_hd.z;
c_hd.x= c_hd.y;
c_hd.y = c_hd.y;
c_hd.z = c_hd.z;

s.RenderText(200,10,"Position: ÂÃ, "+NumToStr(c_ps.x)+" , ÂÃ, "+NumToStr(c_ps.y)+" , ÂÃ, "+NumToStr(c_ps.z),RGBA(255,255,0,255));
s.RenderText(450,10,"Heading: ÂÃ, "+NumToStr(AngleOfPt(Pt))+" , ÂÃ, "+NumToStr(c_hd.y)+" , ÂÃ, "+NumToStr(c_hd.z),RGBA(255,255,0,255));

s.RenderText(10,425,"Use arrow keys, PgUp, PgDn, A, S, Z, X, R to move around",RGBA(255,255,0,255));

fps = s.RenderScene();
fAdjust = (timeGetTime() - startTime) / fTarget;
}until di.KeyDown(DIK_ESCAPE);

Scene.Free();
}



sub AngleOfPt(point Pt),double
{
const RADTODEG = 180 / 3.125;
Result = 0;
if ((Pt.x = 0) and (Pt.y < 0))
ÂÃ, {
Result = 270;
ÂÃ, }
ÂÃ, else if ((Pt.x = 0) and (Pt.y > 0))
ÂÃ, {
Result = 90;
ÂÃ, }
ÂÃ, else if ((Pt.x > 0) and (Pt.y >= 0))
ÂÃ, {
ÂÃ,  ÂÃ, Result = ATan(Pt.y / Pt.x) * RADTODEG;
ÂÃ, }
ÂÃ, else if ((Pt.x < 0) And (Pt.y > 0))
ÂÃ, {
ÂÃ, Result = 180 - (ATan(Pt.y / Abs(Pt.x))* RADTODEG);
ÂÃ, }
ÂÃ, else if ((Pt.x < 0) And (Pt.y <= 0))
ÂÃ, {
ÂÃ,  ÂÃ, Result = 180 + (ATan(Pt.y / Pt.x) * RADTODEG);
ÂÃ, }
ÂÃ, else if ((Pt.x > 0) and (Pt.y < 0))
ÂÃ, {
ÂÃ,  ÂÃ, Result = 360 - (ATan(Abs(Pt.y) / Pt.x) * RADTODEG);
ÂÃ, }
else
{
Result=0;
}
return Result;
}

John S

Paul,
can I scalar multiple a vector?   Such as:   5.0 * VECTOR3


What does   Vec3Lerp(VECTOR3 v1, VECTOR3 v2, FLOAT s);   do?
John Siino, Advanced Engineering Services and Software

Ionic Wind Support Team

Vec3Lerp: This function performs the linear interpolation based on the following formula: V1 + s(V2-V1).

No you can' t multiply a constant by a structure.  We don't have overloaded operators ;)

Here's a function you can use:

sub Vec3Scale(VECTOR3 v, float s),VECTOR3
{
      VECTOR3 ret = v;
       v.x *= s;
       v.y *= s;
       v.z *= s;
       return ret;
}

Ionic Wind Support Team