Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] TritEngine - Silnik Graficzny z wykorzystaniem matematyki niższej ( czyli jak ominąć macierze )

Ostatnio zmodyfikowano 2023-11-22 15:17
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
» 2023-09-10 07:53:40
No właśnie cos takiego robię, tylko na samym końcu sumuje te przesunięcia od rotacji. Skupmy się na razie na rotacji z i dlaczego ona nie działa.

C/C++
void model::rotatez()
{
   
for( trit * t = mesh; t != NULL; t = t->next )
   
{
       
len1 = sqrt( pow( cx - t->v1x, 2 ) + pow( cy - t->v1y, 2 ) + pow( cz - t->v1z, 2 ) );
       
len2 = sqrt( pow( cx - t->v2x, 2 ) + pow( cy - t->v2y, 2 ) + pow( cz - t->v2z, 2 ) );
       
len3 = sqrt( pow( cx - t->v3x, 2 ) + pow( cy - t->v3y, 2 ) + pow( cz - t->v3z, 2 ) );
       
       
// ROTATE Z ( adding vector of movement z )
        // get the current angle 0-360
       
deg1z =( atan2( cy - t->v1y, cx - t->v1x ) + M_PI ) * toDegrees;
       
deg2z =( atan2( cy - t->v2y, cx - t->v2x ) + M_PI ) * toDegrees;
       
deg3z =( atan2( cy - t->v3y, cx - t->v3x ) + M_PI ) * toDegrees;
       
       
if( testindex++ < 360 * 2 )
       
{
           
cout << deg1z << ", " << deg2z << ", " << deg3z << endl;
       
}
       
// get the sum angles (after rotate)
       
fullAnglez1 =( deg1z + anglez ) * toRads;
       
fullAnglez2 =( deg2z + anglez ) * toRads;
       
fullAnglez3 =( deg3z + anglez ) * toRads;
       
       
// get the vectors of movement rotate
       
t->rz1x = t->v1x -( cx + len1 * sin( fullAnglez1 ) );
       
t->rz1y = t->v1y -( cy + len1 * cos( fullAnglez1 ) );
       
t->rz1z = 0;
       
       
t->rz2x = t->v2x -( cx + len2 * sin( fullAnglez2 ) );
       
t->rz2y = t->v2y -( cy + len2 * cos( fullAnglez2 ) );
       
t->rz2z = 0;
       
       
t->rz3x = t->v3x -( cx + len3 * sin( fullAnglez3 ) );
       
t->rz3y = t->v3y -( cy + len3 * cos( fullAnglez3 ) );
       
t->rz3z = 0;
   
}
}
[ cpp ]

[
cpp ]
void model::rotateSum()
{
   
for( trit * t = mesh; t != NULL; t = t->next )
   
{
       
t->r1x = t->v1x + t->rz1x; // + t->ry1x + t->rx1x;
       
t->r1y = t->v1y + t->rz1y; // + t->ry1y + t->rx1y;
       
t->r1z = t->v1z + t->rz1z; // + t->ry1z + t->rx1z;
       
       
t->r2x = t->v2x + t->rz2x; // + t->ry2x + t->rx2x;
       
t->r2y = t->v2y + t->rz2y; // + t->ry2y + t->rx2y;
       
t->r2z = t->v2z + t->rz2z; // + t->ry2z + t->rx2z;
       
       
t->r3x = t->v3x + t->rz3x; // + t->ry3x + t->rx3x;
       
t->r3y = t->v3y + t->rz3y; // + t->ry3y + t->rx3y;
       
t->r3z = t->v3z + t->rz3z; // + t->ry3z + t->rx3z;
   
}
}
P-180370
pekfos
» 2023-09-10 12:56:34
No właśnie cos takiego robię
Nie robisz. Gdybyś robił, nie byłoby zmiennych v?? w tych metodach, a są.

tylko na samym końcu sumuje te przesunięcia od rotacji.
To nie ma sensu. Kontrprzykład: Narysuj sobie na kartce okrąg, środkiem jest C, a V jest punktem na okręgu. 2 obroty o kąt alfa powinny być równoznaczne z jednym obrotem o podwojony kąt. Jeśli obliczysz przesunięcie dla obrotu o np 30 stopni i zaaplikujesz ten wektor 2 razy, to wylecisz z okręgu. Drugi obrót ma wektor przesunięcia pod innym kątem.
P-180371
tBane
Temat założony przez niniejszego użytkownika
» 2023-09-10 15:40:40
Hmm.. Odezwę się niebawem, spróbuję całość jakoś przebudować i wtedy napiszę.
P-180372
tBane
Temat założony przez niniejszego użytkownika
» 2023-11-18 15:40:51
Poległem. Mój engine3D to kompletna porażka. Zostawiam video dla potomnych co by mojego błędu nie powtarzali :D

Ps. Kod działa na pojedynczym sześcianie o środku 0,0,0. W innych warunkach nie mam pojęcia dlaczego nie działa. Nie dostrzegam tu błędu logicznego...

https://drive.google.com/file/d/12chiOKPRP1HhgFwLpVEwE_pRhgDDvDxn/view?usp=drivesdk

Poniżej zamieszczam kody co użyłem

hpp
C/C++
#ifndef model3D_hpp
#define model3D_hpp

float deg1y, deg2y, deg3y; // used to rotateY
float fullAngley1, fullAngley2, fullAngley3; // used to rotateY
float len1, len2, len3;

float dist( float p1x, float p1y, float p1z, float p2x, float p2y, float p2z )
{
   
return sqrt( pow( p2x - p1x, 2 ) + pow( p2y - p1y, 2 ) + pow( p2z - p1z, 2 ) );
}

class trit
{
public:
   
float v1x, v1y, v1z, v2x, v2y, v2z, v3x, v3y, v3z; // vertices
   
float r1x, r1y, r1z, r2x, r2y, r2z, r3x, r3y, r3z; // rotated vertices
   
float cx, cy, cz; // center of triangle
   
float rx, ry, rz; // center of rotated triangle
   
float r, g, b, a; // colors
   
trit * next;
   
   
trit( float, float, float, float, float, float, float, float, float, float, float, float, float );
   
trit( trit * );
   
~trit();
   
void calcCenterOfTriangle();
   
void calcCenterOfRotatedTriangle();
   
void render();
   
void render_3to2D();
};

class model3D
{
public:
   
float cx, cy, cz; // center of model
   
float angley;
   
trit * mesh; // triangles
   
model3D * next;
   
   
model3D();
   
~model3D();
   
void setCenter( float, float, float );
   
void addTrit( trit * );
   
void addTritsFromModel( model3D * );
   
void rotateY();
   
void sortTrits();
   
void render();
   
void render_3to2D();
};

cpp
C/C++
#include "model3D.hpp"

float dist( float cx, float cy, float cz, trit * t )
{
   
return sqrt(
   
pow( cx - t->rx, 2 ) +
   
pow(( cy + 500 ) - t->ry, 2 ) +
   
pow(( cz - 1000 ) - t->rz, 2 )
    )
;
}

trit::trit( float v1x, float v1y, float v1z, float v2x, float v2y, float v2z, float v3x, float v3y, float v3z, float r = 128, float g = 128, float b = 128, float a = 256 )
{
   
this->v1x = v1x; this->v1y = v1y; this->v1z = v1z;
   
this->v2x = v2x; this->v2y = v2y; this->v2z = v2z;
   
this->v3x = v3x; this->v3y = v3y; this->v3z = v3z;
   
   
this->r = r; this->g = g; this->b = b; this->a = a;
   
   
calcCenterOfTriangle();
   
   
next = NULL;
}

trit::trit( trit * t )
{
   
this->v1x = t->v1x; this->v1y = t->v1y; this->v1z = t->v1z;
   
this->v2x = t->v2x; this->v2y = t->v2y; this->v2z = t->v2z;
   
this->v3x = t->v3x; this->v3y = t->v3y; this->v3z = t->v3z;
   
   
this->r = t->r; this->g = t->g; this->b = t->b; this->a = t->a;
   
   
calcCenterOfTriangle();
   
   
next = NULL;
}

trit::~trit()
{
   
}

void trit::calcCenterOfTriangle()
{
   
cx =( v1x + v2x + v3x ) / 3.0f;
   
cy =( v1y + v2y + v3y ) / 3.0f;
   
cz =( v1z + v2z + v3z ) / 3.0f;
}

void trit::calcCenterOfRotatedTriangle()
{
   
rx =( r1x + r2x + r3x ) / 3.0f;
   
ry =( r1y + r2y + r3y ) / 3.0f;
   
rz =( r1z + r2z + r3z ) / 3.0f;
}

void trit::render()
{
   
renderTritColor(
   
r1x, r1y,
   
r2x, r2y,
   
r3x, r3y,
   
r, g, b, a
    );
}

void trit::render_3to2D()
{
   
renderTritColor(
   
v1x + v1z / 2.f, v1y + v1z / 2.f,
   
v2x + v2z / 2.f, v2y + v2z / 2.f,
   
v3x + v3z / 2.f, v3y + v3z / 2.f,
   
r, g, b, a
    );
}

model3D::model3D()
{
   
mesh = NULL;
   
cz = cy = cx = 0.0f;
   
angley = 0.0f;
   
next = NULL;
}

model3D::~model3D()
{
   
}

void model3D::setCenter( float cx, float cy, float cz )
{
   
this->cx = cx;
   
this->cy = cy;
   
this->cz = cz;
}

void model3D::addTrit( trit * t )
{
   
if( mesh != NULL )
       
 t->next = mesh;
   
   
mesh = t;
}

void model3D::addTritsFromModel( model3D * m )
{
   
trit * t;
   
   
for( trit * t2 = m->mesh; t2 != NULL; t2 = t2->next )
   
{
       
t = new trit( t2 );
       
addTrit( t );
   
}
   
}

void model3D::rotateY()
{
   
for( trit * t = mesh; t != NULL; t = t->next )
   
{
       
deg1y = atan2( cz - t->v1z, cx - t->v1x ) * toDegrees;
       
deg2y = atan2( cz - t->v2z, cx - t->v2x ) * toDegrees;
       
deg3y = atan2( cz - t->v3z, cx - t->v3x ) * toDegrees;
       
       
fullAngley1 =( deg1y + angley ) * toRads;
       
fullAngley2 =( deg2y + angley ) * toRads;
       
fullAngley3 =( deg3y + angley ) * toRads;
       
       
len1 = sqrt( pow( cx - t->v1x, 2 ) + pow( cz - t->v1z, 2 ) );
       
len2 = sqrt( pow( cx - t->v2x, 2 ) + pow( cz - t->v2z, 2 ) );
       
len3 = sqrt( pow( cx - t->v3x, 2 ) + pow( cz - t->v3z, 2 ) );
       
       
t->r1x = t->v1x - len1 * cos( fullAngley1 );
       
t->r1y = t->v1y;
       
t->r1z = t->v1z + len1 * sin( fullAngley1 );
       
       
t->r2x = t->v2x - len2 * cos( fullAngley2 );
       
t->r2y = t->v2y;
       
t->r2z = t->v2z + len2 * sin( fullAngley2 );
       
       
t->r3x = t->v3x - len3 * cos( fullAngley3 );
       
t->r3y = t->v3y;
       
t->r3z = t->v3z + len3 * sin( fullAngley3 );
       
   
}
}

void model3D::sortTrits()
{
   
for( trit * t = mesh; t != NULL; t = t->next )
       
 t->calcCenterOfRotatedTriangle();
   
   
   
if( mesh != NULL && mesh->next != NULL )
   
{
       
trit * newMesh = mesh;
       
trit * current = mesh->next;
       
newMesh->next = NULL;
       
       
while( current != NULL )
       
{
           
trit * next = current->next;
           
           
if( dist( cx, cy, cz, current ) > dist( cx, cy, cz, newMesh ) )
           
{
               
current->next = newMesh;
               
newMesh = current;
           
} else
           
{
               
trit * search = newMesh;
               
while( search->next != NULL &&
               
dist( cx, cy, cz, search->next ) > dist( cx, cy, cz, current ) )
                   
 search = search->next;
               
               
current->next = search->next;
               
search->next = current;
           
};
           
           
current = next;
       
}
       
       
mesh = newMesh;
   
}
}

void model3D::render()
{
   
for( trit * t = mesh; t != NULL; t = t->next )
       
 t->render(); // trit(xy, xy, xy, rgba) po r ( rotated )
   
}

void model3D::render_3to2D()
{
   
for( trit * t = mesh; t != NULL; t = t->next )
       
 t->render_3to2D();
   
}
P-180449
pekfos
» 2023-11-18 21:26:13
Obrót dalej źle.
C/C++
deg1y = atan2( t->v1z - cz, t->v1x - cx ) * toDegrees; // Odejmowanie ODWROTNIE

t->r1x = cx + len1 * cos( fullAngley1 ); // CX
t->r1y = t->v1y;
t->r1z = cz + len1 * sin( fullAngley1 ); // CZ
P-180455
tBane
Temat założony przez niniejszego użytkownika
» 2023-11-19 15:41:41
Kurde Ty to potrafisz przywalić leżącemu :D zapomniałem o centrze. Atana nie ruszałem, obrót działa! Tylko mam glicze jakieś przy rysowaniu, a to pewnie przez sortowanie, na które nie mam pomysłu...

https://drive.google.com/file/d/1-2EbbEytC51R0dFSgqJknLOOZwYbBL6c/view?usp=drivesdk
P-180457
tBane
Temat założony przez niniejszego użytkownika
» 2023-11-19 15:49:00
Pekfos, a gdyby założyć że gra jest dwuwymiarowa (mapa 2d) tylko niektóre obiekty są trójwymiarowe (obracalne w osii y), można by uprościć sortowanie gdyż kamera miała by stały kierunek.

Moim kluczem w sortowaniu było
Distance( point.z+1000, point.y+500, point.xz ).

Masz pomysł jak to lepiej rozwiązać?

I czy Z-buffering bedzie dobrym rozwiązaniem?
P-180458
pekfos
» 2023-11-19 19:13:30
Kurde Ty to potrafisz przywalić leżącemu :D zapomniałem o centrze. Atana nie ruszałem, obrót działa!
Od razu leżącemu.. nawet nie wspomniałem że masz typo w nazwie pliku. Wprowadzaj wszystkie poprawki. Poprawny obrót o 0 stopni nie powinien zmieniać współrzędnych, a pewnie tego nie spełniasz.

Tylko mam glicze jakieś przy rysowaniu, a to pewnie przez sortowanie, na które nie mam pomysłu...
Na co ja w ogóle patrzę?

Pekfos, a gdyby założyć że gra jest dwuwymiarowa (mapa 2d) tylko niektóre obiekty są trójwymiarowe (obracalne w osii y), można by uprościć sortowanie gdyż kamera miała by stały kierunek.
Niczego to nie zmienia. Nawet pełne 3d jest na tym etapie dwuwymiarowe, bo obliczasz kolory pikseli na ekranie - który jest dwuwymiarowy. Możesz z modeli 3d wygenerować sprajty i robić całą grę w 2d, jeśli chcesz.

Moim kluczem w sortowaniu było
Distance( point.z+1000, point.y+500, point.xz ).
Sortuj po samym Z.

I czy Z-buffering bedzie dobrym rozwiązaniem?
To co robi karta graficzna? Tak, duh! Chociaż nie bez powodu robi to dedykowany sprzęt, możesz mieć problem z robieniem tego w realtime na telefonie.
P-180460
1 2 3 4 5 « 6 » 7 8
Poprzednia strona Strona 6 z 8 Następna strona