Ali imam veeeliki problem. Tutorial je za Visual Studio, a ja radim u Delphi-u. Imam problem kod collision-a. Naime, u world sam ubacio neki teren, nebitno, i ucitao objekat stolica, iz fajla chair.wld (iz 3ds konvertora - chair1.3ds), i onda ga kopirao funkcijom... evo koda:
//ucitavamo "svet"
STATE_engine_load_world('teren.wld','','bitmaps',USER_DEFINED_BEHAVIOR);
//dodajemo stolicu...
stolica:=STATE_object_create_from_file('chair.wld');
stolica2:=STATE_object_duplicate(stolica,YES); //dupliramo
skin:=STATE_bitmap_load('bitmaps\zburn.bmp',100); //ucitavamo bitmapu
STATE_object_set_bitmap(stolica2,skin); //primenjujemo skin na objekat
STATE_object_move(stolica2,OBJECT_SPACE,-500,0,0); //pomeramo stolicu...
E sad: namestio sam da se na taster ' stolica pomeri za -100, sto mu dodje da se za 5 pomeraja poklopi sa stolicom br. 2:
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
var x,y,z:double;
dir_x,dir_y,dir_z:double;
pozicija_start,pozicija_end: array[0..2] of Double;
poligon,objekat:dword;
pozicija_preseka:array[0..2] of double;
begin
//odavde sam delimicno iz helpa prepisao, samo modifikovao sintaksu za delphi
STATE_object_get_location(stolica,x,y,z);
STATE_object_get_direction(stolica,dir_x,dir_y,dir_z);
pozicija_start[0]:=x+dir_x*100;
pozicija_start[1]:=x+dir_x*100;
pozicija_start[2]:=x+dir_x*100;
pozicija_end[0]:=pozicija_start[0]+dir_x*200;
pozicija_end[1]:=pozicija_start[1]+dir_y*200;
pozicija_end[2]:=pozicija_start[2]+dir_z*200;
//dovde....
if key=#39 then begin //#39 je taster '
if (STATE_object_is_movement_possible(stolica,pozicija_start,pozicija_end,poligon,pozicija_preseka,objekat)=YES) then STATE_object_move(stolica,OBJECT_SPACE,-100,0,0)
else ShowMessage('Nemoguca lokacija, doci ce do sudara!');
end;
end;
Medjutim, ovako napisana funkcija uvek dozvoljava pomeraj. U helpu sam gledao, i tamo se prvo cita bounding box, pa onda ovo... Ipak sam mislio, posto su stolice u ravni, da ce ovo biti dovoljno... Ali ocigledno nije.
Evo iz help-a:
Collision Detection
Collision detection is often very important when designing a 3D game. 3DSTATE makes it very easy to detect collisions with the STATE_object_is_movement_possible() function. This function is used as follows: you provide the starting point and ending point of a line. The function returns true if any another object (or polygon) is intersected by that line. If an intersection is found, the function also returns the coordinates of the intersecting point, a handle to the polygon that was intersected, and a handle to the object that the polygon belongs to. The syntax of the function is as follows:
int STATE_object_is_movement_possible(DWORD object_handle ,double start_location[3], double end_location[3], DWORD *intersected_polygon, double intersection[3], DWORD *blocking_object);
The function returns YES if movement is possible and NO if it is not. If it returns NO, and blocking_object is NULL, then the collision was with a static part of the world.
You may want some objects to be non-collisional. For example, you may want an airplane to be able to pass through a cloud. You can accomplish this with the following function:
STATE_object_make_non_collisional(DWORD object_handle);
Related functions include:
STATE_object_make_collisional(DWORD object_handle);
int STATE_object_is_collisional(DWORD object_handle);
Let’s look at an example to see collision detection at work. Use the World Builder to create a new world based on the BlankFloor template. Add a few buildings to the world, then add a car. Name the car “mycar” and make it a dynamic object. Create a camera that will give you a good view of the world, and save the world as “collision.wld” in the Worlds directory.
In Visual Studio, create a new Console Application. Set it up like the previous examples (set the working directory, add the library, etc.).
We will use the following method to implement collision detection. We will draw a line from the front of the car straight ahead speed units. If there is no collision detected, we will move the car forward. Note that this is a simplified method. For example, it will allow the corner of the car to pass through objects, as long as there is nothing located directly in front of the center of the car. To solve this, we could test for collisions in multiple places in front of the car, but our method will be sufficient to illustrate the concept of collision detection.
When you use the STATE_object_get_location() function, you will get the coordinates of the center of the truck. To get the coordinates of the front of the truck, we will use the following, where [x y z] is location of the center of the car and [dir_x, dir_y, dir_z] is a unit vector that gives the direction of the car:
front_of_car[0]=x + dir_x * half_car_length;
front_of_car[1]=y + dir_y * half_car_length;
front_of_car[2]=z + dir_z * half_car_length;
A point speed units in front of the car can be calculated in the same way:
ahead_of_car[0]=front_of_car[0] + dir_x *speed;
ahead_of_car[1]=front_of_car[1] + dir_y * speed;
ahead_of_car[2]=front_of_car[2] + dir_z * speed;
We can then check for a collision, and move forward if possible:
DWORD intersecting_polygon;
DWORD intersecting_object;
double intersection_point[3];
if (STATE_object_is_movement_possible(car_handle, front_of_car, ahead_of_car, &intersecting_polygon, intersection_point, &intersecting_object))
STATE_object_move(car_handle,OBJECT_SPACE,-speed,0,0);
That’s all that is required. Here is a complete listing of the program. Note that in the main function we get the bounding box to calculate the length of the car (see the section on Tracks, above, for a description of this function).
#include "..\\..\\..\\..\\Include\\3DSTATE.H"
#include <iostream.h>
void main(void)
{
void MoveCar(DWORD car_handle,double half_car_length);
int rc=STATE_engine_load_world("collision.wld",".","Bitmaps",USER_DEFINED_BEHAVIOR);
if(rc==VR_ERROR) {
cout << "Failed to load world, aborting\n";
cout << "look at error.log to see why\n";
return;
}
STATE_engine_set_default_rendering_window_title("Object movement demo <esc> to exit");
STATE_engine_maximize_default_rendering_window();
ShowCursor(FALSE); // Hide the cursor
DWORD camera=STATE_camera_get_default_camera();
DWORD car=STATE_object_get_object_using_name("mycar");
STATE_object_set_direction(car,-1,0,0);
double box[2][3];
STATE_object_get_bounding_box(car, box);
double half_car_length=(box[1][0]-box[0][0])/2;
while( (GetAsyncKeyState(VK_ESCAPE)&1) ==0 ) {
MoveCar(car,half_car_length);
STATE_engine_render(NULL,camera);
}
}
void MoveCar(DWORD car_handle, double half_car_length)
{
if ((GetAsyncKeyState(VK_LEFT)<0) ==1 )
{
STATE_object_rotate_z(car_handle,10,OBJECT_SPACE);
}
if ((GetAsyncKeyState(VK_RIGHT)<0) ==1 )
{
STATE_object_rotate_z(car_handle,-10,OBJECT_SPACE);
}
if ((GetAsyncKeyState(VK_SPACE)<0) ==1 )
{
const int speed = 20;
double x,y,z;
double dir_x,dir_y,dir_z;
double front_of_car[3];
double ahead_of_car[3];
STATE_object_get_location(car_handle,&x,&y,&z);
STATE_object_get_direction(car_handle,&dir_x,&dir_y,&dir_z);
front_of_car[0]=x+half_car_length*dir_x;
front_of_car[1]=y+half_car_length*dir_y;
front_of_car[2]=z+half_car_length*dir_z;
ahead_of_car[0]=front_of_car[0]+speed*dir_x;
ahead_of_car[1]=front_of_car[1]+speed*dir_y;
ahead_of_car[2]=front_of_car[2]+speed*dir_z;
DWORD intersecting_polygon;
DWORD intersecting_object;
double intersection_point[3];
if (STATE_object_is_movement_possible(car_handle, front_of_car,ahead_of_car,&intersecting_polygon,intersection_point,&intersecting_object))
STATE_object_move(car_handle,OBJECT_SPACE,-speed,0,0);
}
return;
}
P.S. STATE engine je ver 6, malo stariji...
http://www.eyesburn.co.sr/