Moteur 3D

hallardc Messages postés 3 Date d'inscription jeudi 23 janvier 2003 Statut Membre Dernière intervention 8 janvier 2004 - 8 janv. 2004 à 10:20
cs_neodante Messages postés 2835 Date d'inscription lundi 11 août 2003 Statut Modérateur Dernière intervention 16 décembre 2006 - 8 janv. 2004 à 15:21
Je cherche a amélirorer un petit moteur 3D, pour gérer la profondeur des faces de ma pyramides.
Ces faces s'affichent n'importe comment.
Faut-il faire un tablo collectant les Z des ces polygones ??

import java.awt.*;

class Model3D
{
    	float vert[];
    	int tvert[];
    	int nvert, maxvert;
    	int con[];
    	int poly[];
    	int ncon, maxcon, npoly, maxpoly;
    	boolean transformed;
    	Cube3D c;
    	Matrix3D mat;
    	Polygon polygon;

    	float xmin, xmax, ymin, ymax, zmin, zmax;

    	Model3D ()
    		{
mat = new Matrix3D();
mat.xrot(20);
mat.yrot(30);
    		}

    	Model3D (float s, float d)	/** Create a 3D model**/
    		{
    		this();

    		}

    	//void Cube (float x, float y, float z, float d)	/** Create a 3D cube **/
    	//	{
//int i = nvert;

// create the eigth points
//addVert(x, y, z);
//addVert(x + d, y, z);
//addVert(x + d, y + d, z);
//addVert(x, y + d, z);
//addVert(x, y, z + d);
//addVert(x + d, y, z + d);
//addVert(x + d, y + d, z + d);
//addVert(x, y + d, z + d);

// join the points to form the cube
//add (i, i + 1);
//add (i + 1, i + 2);
//add (i + 2, i + 3);
//add (i + 3, i);
//add (i + 4, i + 5);
//add (i + 5, i + 6);
//add (i + 6, i + 7);
//add (i + 7, i + 4);
//add (i, i + 4);
//add (i + 1, i + 5);
//add (i + 2, i + 6);
//add (i + 3, i + 7);
    	//	}

    	int addVert (float x, float y, float z)	/** Add a vertex to this model **/
    		{
int i = nvert;
if (i >= maxvert)
    	if (vert == null)
    		{
maxvert = 100;
vert = new float[maxvert * 3];
    		}
    	else
    		{
maxvert *= 2;
float nv[] = new float[maxvert * 3];
System.arraycopy(vert, 0, nv, 0, vert.length);
vert = nv;
    		}
i *= 3;
vert[i] = x;
vert[i + 1] = y;
vert[i + 2] = z;
return nvert++;
    		}

    	void add (int p1, int p2)	/** Add a line from vertex p1 to vertex p2 **/
    		{
int i = ncon;
if (p1 >= nvert || p2 >= nvert)
    	return;
if (i >= maxcon)
    	if (con == null)
    		{
maxcon = 100;
con = new int[maxcon];
    		}
    	else
    		{
maxcon *= 2;
int nv[] = new int[maxcon];
System.arraycopy(con, 0, nv, 0, con.length);
con = nv;
    		}
if (p1 > p2)
{
    		int t = p1;
    		p1 = p2;
    		p2 = t;
}
con[i] = (p1 << 16) | p2;
ncon = i + 1;
    		}

void addpoly(int v1, int v2, int v3)
    		{
int i = npoly;
if (v1 >= nvert || v2 >= nvert || v3 >= nvert)
    	return;
if (i >= maxpoly)
    	if (poly == null)
    		{
maxpoly = 100;
poly = new int[maxpoly*3];
    		}
    	else
    		{
maxpoly *= 2;
int nvt[] = new int[maxpoly*3];
System.arraycopy(poly, 0, nvt, 0, poly.length);
poly = nvt;
    		}
i *=3;
poly[i] = v1;
poly[i+1] = v2;
poly[i+2] = v3;
npoly++;
}

    	void transform ()	/** Transform all the points in this model **/
    		{
if (transformed || nvert <= 0)
    	return;
if (tvert == null || tvert.length < nvert * 3)
    	tvert = new int[nvert*3];
mat.transform(vert, tvert, nvert);
transformed = true;
}

private void quickSort (int a[], int left, int right)	/** Quick Sort implementation **/
   		{
int leftIndex = left;
int rightIndex = right;
int partionElement;
if ( right > left)
      		{
// Arbitrarily establishing partition element as the midpoint of the array
         		partionElement = a[ ( left + right ) / 2 ];

// loop through the array until indices cross
while( leftIndex <= rightIndex )
{
// find the first element that is greater than or equal to
// the partionElement starting from the leftIndex.
while( ( leftIndex < right ) && ( a[leftIndex] < partionElement ) )
++leftIndex;

// find an element that is smaller than or equal to
// the partionElement starting from the rightIndex.
while( ( rightIndex > left ) && ( a[rightIndex] > partionElement ) )
--rightIndex;

// if the indexes have not crossed, swap
if( leftIndex <= rightIndex )
{
swap(a, leftIndex, rightIndex);
++leftIndex;
--rightIndex;
}
}

// If the right index has not reached the left side of array
// must now sort the left partition.
if( left < rightIndex )
quickSort( a, left, rightIndex );

// If the left index has not reached the right side of array
// must now sort the right partition.
if( leftIndex < right )
quickSort( a, leftIndex, right );
}
}

private void swap (int a[], int i, int j)
{
int T;
T = a[i];
a[i] = a[j];
a[j] = T;
}

void compress ()	/** Eliminate duplicate lines **/
{
int limit = ncon;
int c[] = con;
quickSort(con, 0, ncon - 1);
int d = 0;
int pp1 = -1;
for (int i = 0; i < limit; i++)
{
int p1 = c[i];
if (pp1 != p1)
{
c[d] = p1;
d++;
}
pp1 = p1;
}
ncon = d;
}

    static Color gr[];

    void paint (Graphics g)		/** Paint this model to a graphics context **/
    		{
if (vert == null || nvert <= 0)
return;
transform();
if (gr == null)
{
gr = new Color[16];
for (int i = 0; i < 16; i++)
{
int grey = (int) (170*(1-Math.pow(i/15.0, 2.3)));
gr[i] = new Color(grey, grey, grey);
}
}
int lg = 0;
int lim = ncon;
int ext = npoly;
int c[] = con;
int v[] = tvert;
if (lim <= 0 || nvert <= 0)
return;
for (int i = 0; i < lim; i++)
{
int T = c[i];
int p1 = ((T >> 16) & 0xFFFF) * 3;
int p2 = (T & 0xFFFF) * 3;
int grey = v[p1 + 2] + v[p2 + 2];
if (grey < 0)
grey = 0;
if (grey > 15)
grey = 15;
if (grey != lg)
{
lg = grey;
g.setColor(gr[grey]);
}
g.drawLine(v[p1], v[p1 + 1], v[p2], v[p2 + 1]);
int x[] = {23, 12, 14, 16};
}

for (int i = 0; i < ext; i++)
{
int j=i*3;
int v1 = poly[j];
int v2 = poly[j+1];
int v3 = poly[j+2];
int k1 = v1*3;
int k2 = v2*3;
int k3 = v3*3;
polygon = new Polygon();
polygon.addPoint(v[k1],v[k1+1]);
polygon.addPoint(v[k2],v[k2+1]);
polygon.addPoint(v[k3],v[k3+1]);
switch(i)
{
case 0:
g.setColor(Color.blue);
break;

case 1:
g.setColor(Color.pink);
break;

case 2:
g.setColor(Color.red);
break;

case 3:
g.setColor(Color.yellow);
break;

case 4:
g.setColor(Color.green);
break;

case 5:
g.setColor(Color.orange);
break;

case 6:
g.setColor(Color.gray);
break;

case 7:
g.setColor(Color.pink);
break;

case 8:
g.setColor(Color.black);
break;

case 9:
g.setColor(Color.yellow);
break;

case 10:
g.setColor(Color.blue);
break;

case 11:
g.setColor(Color.red);
break;

default:
break;
}
g.fillPolygon(polygon);
}
}

void findBB ()	/** Find the bounding box of this model **/
{
if (nvert <= 0)
return;
float v[] = vert;float xmin v[0], xmax xmin;float ymin v[1], ymax ymin;float zmin v[2], zmax zmin;
for (int i = nvert * 3; (i -= 3) > 0;)
{
float x = v[i];
if (x < xmin)
xmin = x;
if (x > xmax)
xmax = x;
float y = v[i + 1];
if (y < ymin)
ymin = y;
if (y > ymax)
ymax = y;
float z = v[i + 2];
if (z < zmin)
zmin = z;
if (z > zmax)
zmax = z;
}
this.xmax = xmax;
this.xmin = xmin;
this.ymax = ymax;
this.ymin = ymin;
this.zmax = zmax;
this.zmin = zmin;
}
}



import java.awt.*;

class Matrix3D
{
    	float xx, xy, xz, xo;
    	float yx, yy, yz, yo;
    	float zx, zy, zz, zo;
    	static final double pi = 3.14159265;

Matrix3D ()		/** Create a new unit matrix **/
{
xx = 1.0f;
yy = 1.0f;
zz = 1.0f;
    		}

    	void scale (float f)	/** Scale by f in all dimensions **/
    		{
xx *= f;
xy *= f;
xz *= f;
xo *= f;
yx *= f;
yy *= f;
yz *= f;
yo *= f;
zx *= f;
zy *= f;
zz *= f;
zo *= f;
}

    	void scale (float xf, float yf, float zf)	/** Scale along each axis independently **/
    		{
xx *= xf;
xy *= xf;
xz *= xf;
xo *= xf;
yx *= yf;
yy *= yf;
yz *= yf;
yo *= yf;
zx *= zf;
zy *= zf;
zz *= zf;
zo *= zf;
    		}

    	void translate (float x, float y, float z)	/** Translate the origin **/
    		{
xo += x;
yo += y;
zo += z;
    		}

    	void yrot (double theta)	/** rotate theta degrees about the y axis **/
    		{
theta *= (pi / 180);
double ct = Math.cos(theta);
double st = Math.sin(theta);

float Nxx = (float) (xx * ct + zx * st);
float Nxy = (float) (xy * ct + zy * st);
float Nxz = (float) (xz * ct + zz * st);
float Nxo = (float) (xo * ct + zo * st);

float Nzx = (float) (zx * ct - xx * st);
float Nzy = (float) (zy * ct - xy * st);
float Nzz = (float) (zz * ct - xz * st);
float Nzo = (float) (zo * ct - xo * st);

xo = Nxo;
xx = Nxx;
xy = Nxy;
xz = Nxz;
zo = Nzo;
zx = Nzx;
zy = Nzy;
zz = Nzz;
    		}

    	void xrot (double theta)	/** rotate theta degrees about the x axis **/
    		{
theta *= (pi / 180);
double ct = Math.cos(theta);
double st = Math.sin(theta);

float Nyx = (float) (yx * ct + zx * st);
float Nyy = (float) (yy * ct + zy * st);
float Nyz = (float) (yz * ct + zz * st);
float Nyo = (float) (yo * ct + zo * st);

float Nzx = (float) (zx * ct - yx * st);
float Nzy = (float) (zy * ct - yy * st);
float Nzz = (float) (zz * ct - yz * st);
float Nzo = (float) (zo * ct - yo * st);

yo = Nyo;
yx = Nyx;
yy = Nyy;
yz = Nyz;
zo = Nzo;
zx = Nzx;
zy = Nzy;
zz = Nzz;
    		}

    	void zrot (double theta)	/** rotate theta degrees about the z axis */
    		{
theta *= (pi / 180);
double ct = Math.cos(theta);
double st = Math.sin(theta);

float Nyx = (float) (yx * ct + xx * st);
float Nyy = (float) (yy * ct + xy * st);
float Nyz = (float) (yz * ct + xz * st);
float Nyo = (float) (yo * ct + xo * st);

float Nxx = (float) (xx * ct - yx * st);
float Nxy = (float) (xy * ct - yy * st);
float Nxz = (float) (xz * ct - yz * st);
float Nxo = (float) (xo * ct - yo * st);

yo = Nyo;
yx = Nyx;
yy = Nyy;
yz = Nyz;
xo = Nxo;
xx = Nxx;
xy = Nxy;
xz = Nxz;
}

   	 void mult (Matrix3D rhs)	/** Multiply this matrix by a second: M = M*R */
    		{
float lxx = xx * rhs.xx + yx * rhs.xy + zx * rhs.xz;
float lxy = xy * rhs.xx + yy * rhs.xy + zy * rhs.xz;
float lxz = xz * rhs.xx + yz * rhs.xy + zz * rhs.xz;
float lxo = xo * rhs.xx + yo * rhs.xy + zo * rhs.xz + rhs.xo;

float lyx = xx * rhs.yx + yx * rhs.yy + zx * rhs.yz;
float lyy = xy * rhs.yx + yy * rhs.yy + zy * rhs.yz;
float lyz = xz * rhs.yx + yz * rhs.yy + zz * rhs.yz;
float lyo = xo * rhs.yx + yo * rhs.yy + zo * rhs.yz + rhs.yo;

float lzx = xx * rhs.zx + yx * rhs.zy + zx * rhs.zz;
float lzy = xy * rhs.zx + yy * rhs.zy + zy * rhs.zz;
float lzz = xz * rhs.zx + yz * rhs.zy + zz * rhs.zz;
float lzo = xo * rhs.zx + yo * rhs.zy + zo * rhs.zz + rhs.zo;

xx = lxx;
xy = lxy;
xz = lxz;
xo = lxo;

yx = lyx;
yy = lyy;
yz = lyz;
yo = lyo;

zx = lzx;
zy = lzy;
zz = lzz;
zo = lzo;
    		}

    	void unit ()	/** Reinitialize to the unit matrix **/
    		{
xo = 0;
xx = 1;
xy = 0;
xz = 0;
yo = 0;
yx = 0;
yy = 1;
yz = 0;
zo = 0;
zx = 0;
zy = 0;
zz = 1;
}

    	void transform (float v[], int tv[], int nvert)	/** Transform nvert points from v into tv **/
    		{
    	 	// v contains the input coordinates in floating point.
    	 	// Three successive entries in the array constitute a point.
    	 	// tv ends up holding the transformed points as integers;
    	 	// three successive entries per point.
float lxx xx, lxy xy, lxz = xz, lxo = xo;float lyx yx, lyy yy, lyz = yz, lyo = yo;float lzx zx, lzy zy, lzz = zz, lzo = zo;
for (int i = nvert * 3; (i -= 3) >= 0;)
{
    		float x = v[i];
    		float y = v[i + 1];
    		float z = v[i + 2];
    		tv[i    ] = (int) (x * lxx + y * lxy + z * lxz + lxo);
    		tv[i + 1] = (int) (x * lyx + y * lyy + z * lyz + lyo);
    		tv[i + 2] = (int) (x * lzx + y * lzy + z * lzz + lzo);
}
    		}

    	public String toString ()
    		{
return ("[" + xo + "," + xx + "," + xy + "," + xz + ";"
+ yo + "," + yx + "," + yy + "," + yz + ";"
+ zo + "," + zx + "," + zy + "," + zz + "]");
}
}



import java.applet.Applet;
import java.awt.*;
import java.awt.Event;
/* An applet to put a 3D model into a page */

public class Engine3D extends Applet implements Runnable
{
Model3D md;
boolean painted = true;
    	float xfac;
    	int prevx, prevy;
    	float xtheta, ytheta;
    	float scalefudge = 1;    	Matrix3D amat new Matrix3D(), tmat new Matrix3D();
String message = null;

public void init ()
{
// init first view
amat.yrot(20);
amat.xrot(20);
resize(size().width <= 20 ? 400 : size().width,
size().height <= 20 ? 400 : size().height);
}

    public void run ()
    		{
try
{
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
Model3D m = new Pyramide3D((float) 1,(float) 1,(float) 1, (float) 0.8);
computeModel(m);
resizeModel(m);
}
catch (Exception e)
{
md = null;
message = e.toString();
}
repaint();
}

    public void start ()
    		{if (md null && message null)
new Thread(this).start();
}

    public void stop ()
    		{
}

    public boolean mouseDown (Event e, int x, int y)
    		{
prevx = x;
prevy = y;
return true;
}

    public boolean mouseDrag (Event e, int x, int y)
    		{
tmat.unit();
float xtheta = (prevy - y) * 360.0f / size().width;
float ytheta = (x - prevx) * 360.0f / size().height;
tmat.xrot(xtheta);
tmat.yrot(ytheta);
amat.mult(tmat);
if (painted)
{
painted = false;
repaint();
}
prevx = x;
prevy = y;
return true;
}

    public void paint (Graphics g)
    		{
    		setBackground (Color.white);

if (md != null)
{
md.mat.unit();
md.mat.translate(-(md.xmin + md.xmax) / 2,
-(md.ymin + md.ymax) / 2,
-(md.zmin + md.zmax) / 2);
md.mat.mult(amat);
md.mat.scale(xfac, -xfac, 16 * xfac / size().width);
md.mat.translate(size().width / 2, size().height / 2, 8);
md.transformed = false;
md.paint(g);
setPainted();
}
else if (message != null)
{
g.drawString("Error in model:", 3, 20);
g.drawString(message, 10, 40);
}
}

    private synchronized void setPainted ()
    		{
painted = true;
notifyAll();
}

private void computeModel (Model3D m)
{
md = m;
m.findBB();
m.compress();
}

private void resizeModel (Model3D m)
{
float xw = m.xmax - m.xmin;
float yw = m.ymax - m.ymin;
float zw = m.zmax - m.zmin;
if (yw > xw)
xw = yw;
if (zw > xw)
xw = zw;
float f1 = size().width / xw;
float f2 = size().height / xw;
xfac = 0.7f * (f1 < f2 ? f1 : f2) * scalefudge;
}
}



import java.awt.*;

class Pyramide3D extends Model3D
{

    	public Pyramide3D (float x, float y, float z, float d)	/** Create a 3D cube **/
    		{
int i = nvert;

// create the eigth points
addVert(x, y, z);
addVert(x + d, y, z);
addVert(x + d, y + d, z);
addVert(x, y + d, z);
addVert((x + (d/2)), (y + (d/2)), z + d);

// join the points to form the cube
addpoly (i, i + 1, i + 4);
addpoly (i + 1, i + 2, i + 4);
addpoly (i + 2, i + 3, i + 4);
addpoly (i + 3, i, i + 4);
addpoly (i, i + 1, i + 2);
addpoly (i, i + 1, i + 3);
add (i, i + 1);
add (i + 1, i + 2);
add (i + 2, i + 3);
add (i + 3, i);
add (i, i + 4);
add (i + 1, i + 4);
add (i + 2, i + 4);
add (i + 3, i + 4);

    		}

}


Merci d avance

3 réponses

cs_neodante Messages postés 2835 Date d'inscription lundi 11 août 2003 Statut Modérateur Dernière intervention 16 décembre 2006 11
8 janv. 2004 à 14:01
:big) Neodante :big)

Je suis en train d'écrire un programme qui devrait être un moteur 3D complet pour un autre de mes projets et je trouve que tu n'as pas assez fait d'objet tel que Vector3D, Face (Triangle, ...), Renderer, Transformable, ... c'est pour ça que j'ai un peu de mal à savoir où ton code ne va pas ! Cela ressemble à un peu à du C 'objetisé' !
Ce que j'ai fait c'est effectivement un tableau avec les profondeurs des polygones avant de les afficher ainsi que 2 ou 3 astuces. Mais à l'arrivée cela marche plutôt très bien !
@+
0
hallardc Messages postés 3 Date d'inscription jeudi 23 janvier 2003 Statut Membre Dernière intervention 8 janvier 2004
8 janv. 2004 à 14:03
justement je n'arrive pas a faire ce tableau, tu pourrais pas m expliquer ou me montrer ?
0
cs_neodante Messages postés 2835 Date d'inscription lundi 11 août 2003 Statut Modérateur Dernière intervention 16 décembre 2006 11
8 janv. 2004 à 15:21
:big) Neodante :big)

Je vais essayer de te trouver ça ce soir ! Rappel le moi par un petit message sinon je vais oublié ...
@+ :big)
0
Rejoignez-nous