Ruch czworościanu w OpenGL

0

Witam, mam do napisania program w C++ z użyciem OpenGL, który tworzy czworościany z trójkątów oraz wprawia je w ruch po dowolnym wektorze, a gdy napotkają przeszkodę, ścianę lub innego czworościana, mają poruszać się w przeciwną stronę. Napisałem już tworzenie czworościanów, ale mam problem z ich ruchem. Napisałem coś takiego:

   
pol_x += quadro_direction * 0.05;
if(pol_x <= -20 || pol_x >= 20) quadro_direction *= -1;
glPushMatrix();
glTranslatef(pol_x, 0, 0);
rysuj();
glPopMatrix();

to wszystko mam w pętli, ale to po prostu rysuje po kolei wszystkie czworościany w jednej linii(uproszczenie na początek), nie wiem za bardzo jak zrobić z tego ruch. Z góry dzięki za pomoc.

0

Pomiędzy kolejnymi rysowaniami klatek musisz oczywiście czyścić bufor koloru (i ew inne bufory, np głębi). Robisz to?

0

Dzięki, jestem jeszcze trochę zielony z OpenGl ;) spróbuję to poprawić.

0

wektor x,y,z to twoj kierunek oczywiscie musi byc znormalizowany

do tego ustaklamy czas ruchu t

pozniej co klatke sprawdzamy aktualnyczas-t = fc

i mnozymy wektor x,y,z * fc * szybkosc_ruchu = nowa pozycja czworoscianu

a tutaj oto taki kodzik:

 //---------------------------------------------------------------------------


#pragma hdrstop

#include "WEAPON_FLAMETHROWER.h"
//#include "FC_OPENGL.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

void __fastcall  drawbillboardF(float cx, float cy, float cz, float size)
{
double m_PickInfo_ModelView[16];// of ;

  t3dpoint Pos;
glGetDoublev(GL_MODELVIEW_MATRIX, m_PickInfo_ModelView);

BillboardX.x = m_PickInfo_ModelView[0];
BillboardX.y = m_PickInfo_ModelView[4];
BillboardX.z = m_PickInfo_ModelView[8];


BillboardY.x =	m_PickInfo_ModelView[1];
BillboardY.y =	m_PickInfo_ModelView[5];
BillboardY.z =	m_PickInfo_ModelView[9];



glBegin(GL_QUADS);

glTexCoord2f(0.0, 1.0);

Pos.x = cx-BillboardX.x*size+BillboardY.x*size;
Pos.y = cy-BillboardX.y*size+BillboardY.y*size;
Pos.z = cz-BillboardX.z*size+BillboardY.z*size;

glVertex3f(Pos.x,Pos.y,Pos.z);
glTexCoord2f(1.0, 1.0);

Pos.x = cx+BillboardX.x*size+BillboardY.x*size;
Pos.y = cy+BillboardX.y*size+BillboardY.y*size;
Pos.z = cz+BillboardX.z*size+BillboardY.z*size;

glVertex3f(Pos.x,Pos.y,Pos.z);

glTexCoord2f(1.0, 0.0);
Pos.x = cx+BillboardX.x*size-BillboardY.x*size;
Pos.y = cy+BillboardX.y*size-BillboardY.y*size;
Pos.z = cz+BillboardX.z*size-BillboardY.z*size;
glVertex3f(Pos.x,Pos.y,Pos.z);

glTexCoord2f(0.0, 0.0);
Pos.x = cx-BillboardX.x*size-BillboardY.x*size;
Pos.y = cy-BillboardX.y*size-BillboardY.y*size;
Pos.z = cz-BillboardX.z*size-BillboardY.z*size;
glVertex3f(Pos.x,Pos.y,Pos.z);

glEnd();

}



void __fastcall  tflamethrower::DRAW()
{
int i;
float d; t3dpoint v;


make_next_frame();
//glpushmatrix();
glColor4f(1,1,1,0.7);
glDepthMask(GL_FALSE);

glEnable(GL_BLEND);

glBlendFunc(GL_DST_ALPHA,GL_ONE);
glEnable(GL_TEXTURE_2D);
for (i = 0; i < 129; i++)
if (particles[i].draw == true)
{
//	                                                                 glbindtexture(GL_TEXTURE_2D,sprite.animtextures[particles[i].frame]);
 d =n3ddistance(particles[i].startpos,particles[i].pos);
if (n3ddistance(particles[i].hitpos,particles[i].pos) < 50){
//v := VectoraB(particles[i].startpos,particles[i].pos); v:=normalize(v);
   particles[i].stan = -1;

}

 particles[i].size = 300.0f;
drawbillboardF(particles[i].pos.x,particles[i].pos.y,particles[i].pos.z,particles[i].size);
 //glrotate(-angle,1,0,0);
//  glmatrixmode(GL_TEXTURE);glrotate(-angle,0,1,0); glmatrixmode(GL_MODELVIEW);
//glpopmatrix();

}


glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
}


  __fastcall tflamethrower::tflamethrower()
  {
   sprite = new tglanimtexture;
  }
  __fastcall tflamethrower::~tflamethrower()
  {
   sprite->free();
   delete sprite;
  }

void __fastcall  tflamethrower::load(AnsiString filename)
{
 sprite->loadtex(filename);
}


void __fastcall  tflamethrower::make_next_frame()
{
int i;
t3dpoint k;

for (i = 0; i < 129; i++)
if (particles[i].draw == true)
{

k.x = 100000000.0f*(sin(particles[i].glop*imopi)*cos(particles[i].heading*imopi));
k.z = 100000000.0f*(cos(particles[i].glop*imopi)*cos(particles[i].heading*imopi));
k.y = 100000000.0f*(sin(particles[i].heading*imopi));
 //particles[i].size        := (gettickcount()-particles[i].time)/10;
  k=Normalize(k);
  if (particles[i].stan < 0) {

	if (!(particles[i].stanC)){
//particles[i].odbity_wektor = odbij_od_sciany(Normalize(vectorAB(particles[i].startpos,particles[i].startpos)),terrain.face_normal[particles[i].hitindex]); ODKOMENTOWAC
// particles[i].startpos := particles[i].pos; ODKOMENTOWAC
//      particles[i].stanC := true;                       ODKOMENTOWAC
}
}

//  if particles[i].stan > 0 then begin
  // particles[i].stanC := false;
   if (NORMAL_TIME == 0) {        //czyli jak false
       particles[i].pos = vectors_frontadd(particles[i].startpos,vector_multiple(k,power*(GetTickCount()-particles[i].time)/1000.0f));
   } else {

 particles[i].pos = vectors_frontadd(particles[i].pos,vector_multiple(k,2.00*power*(GetTickCount()-particles[i].time)/1000.0f)); //end else
		   }
particles[i].time = GetTickCount();
//					 particles[i].rotate = particles[i].rotate +1;
/*if (GetTickCount()-particles[i].frametime >= sprite.speed ) {
	  particles[i].frametime = GetTickCount();

//particles[i].frame = particles[i].frame + 1;       odkomentowac
//if (particles[i].frame > high(sprite.animtextures)  )then begin particles[i].frame := 0; particles[i].draw := false; end; odkomenotwac

}

  */

checkparticle(i);
}
}
                                     //tutaj jak wielkosc przekracza maks wielkosc to usuwamy z rysowania particle
void __fastcall tflamethrower::checkparticle(int index)
{
//if ( particles[index].size >=  5000.0f ) particles[index].draw = false;

if (n3ddistance(particles[index].startpos,particles[index].pos) > 7000.0f)       
                               particles[index].draw = false;

}

void __fastcall tflamethrower::throw_next_free(t3dpoint pos, float  glop, float heading)
{
int i;
bool found;

if ( (GetTickCount()-shot_time) < SHOT_SPEED ) return;
shot_time = GetTickCount();
already_shot = true;
found = false;
for (i = 0; i < 129; i++)
if (particles[i].draw == false)
{
found = true;
last_fired_particle = i; break;
}

if (found == false){ last_fired_particle = 0; }

 particles[last_fired_particle].draw = true;
 particles[last_fired_particle].size        = 300;
 particles[last_fired_particle].startpos    = pos;
 particles[last_fired_particle].pos    = pos;
 particles[last_fired_particle].frame       = 0;
 particles[last_fired_particle].time        = GetTickCount();
 particles[last_fired_particle].glop        = glop;
 particles[last_fired_particle].heading     = heading;
 particles[last_fired_particle].frametime   = GetTickCount();
// particles[last_fired_particle].hitpos      = shot_pos;
// particles[last_fired_particle].hitindex    = shot_index;
 particles[last_fired_particle].rotate      = random(359);
 particles[last_fired_particle].rot_time    = GetTickCount();
 particles[last_fired_particle].stan = 1;


}

void __fastcall tflamethrower::reset()
{
	int i;
//RYSOWALEM_swiatlo[0] = false;
//RYSOWALEM_swiatlo[1] = false;
//RYSOWALEM_swiatlo[2] = false;
for (i = 0; i < 129; i++) particles[i].draw = false;
}

void __fastcall tflamethrower::setallinpos(t3dpoint pos)
{
int i;
for (i = 0; i < 129; i++) particles[i].startpos = pos;



}

gdzie


t3dpoint __fastcall Normalize(t3dpoint v)
{
float magni;
 t3dpoint result;
magni = magnitude(v);
// = 1.0;
//if (IsNan(magni) == true)  magni = 1.0;
result.x = v.x/magni;
result.y = v.y/magni;
result.z = v.z/magni;
// = v;
return result;
}



float __fastcall magnitude(t3dpoint Vector)
{
	   //	 if ( ( IsNan(Vector.x) == true) || (IsNan(Vector.y) == true) || (IsNan(Vector.z) == true) ) return 1.0f;

//float result;
return sqrt(
(Vector.x*Vector.x) +
(Vector.y*Vector.y) +
(Vector.z*Vector.z));
//if (result == 0.0f) result = 1.0f;
//return result;
}






 
0

A jak można wykrywać kolizji?

0

Mam taką klasę:

0

Mam taką klasę

class quadro
{
 private:
    float punkt[4][3];
    float pol_x,pol_y,pol_z;
    float dl_boku;
    bool zderzenie;
 public:
    quadro(float x, float y, float z,float bok);
    void rysuj(void);
    void ruch(float dirx,float diry,float dirz);
    void rysuj(float x, float y,float z);
    bool kolizja(void);
    bool operator==(quadro ob);
}; 

mam konstruktor, itd, czworościany się tworzą i ruszają w zadanym kierunku, metoda ruch:

void quadro::ruch(float dirx,float diry,float dirz){

float dir_y=diry;
float dir_z=dirz;
float dir_x=dirx;
float speed=0.04;

if (this->kolizja()==true){
dir_y*=-1;
dir_z*=-1;
dir_x*=-1;
}

this->pol_x+= dir_x*speed;
this->pol_y+= dir_y*speed;
this->pol_z+= dir_z*speed;
glTranslatef(pol_x,pol_y,pol_z);
rysuj(this->pol_x,this->pol_y,this->pol_z);


} 

Natomiast nie działa wykrywanie zderzeń, które jest realizowane tą metodą:

bool quadro::kolizja(void){
float odl,x,y,z;

    for(int j=0;j<SIZE;j++){
    if (*this==tablica[j]) {continue;}
    x = fabs(pol_x - tablica[j].pol_x);
    y = fabs(pol_y - tablica[j].pol_y);
    z = fabs(pol_z - tablica[j].pol_z);
    odl = sqrt(x * x + y * y + z * z);
    if (odl<(dl_boku+tablica[j].dl_boku)) return true;
    }
return false;
} 

Czy ktoś widzi błąd? Ja nie mam już pomysłu, z góry dzięki za pomoc.

0

Proszę o pomoc, z powyższym. Dzięki

1 użytkowników online, w tym zalogowanych: 0, gości: 1