GP2X Anim8or + Zeengine3d


TKF15H

Member
Joined
Jan 27, 2006
Messages
212
Being quite prone to programmer's art, I've found that Anim8or is merciful to my
modelling skills. Knowing that there may be others out there like me in this aspect,
I figured the following code could be of use. Both are modifications of code
available elsewhere.
I do not garantee both are bug-free, especially the C code as the ZeEngine features
uncountable mysteries (some wierd, such as assigning a 24 bit value to a 16 bit variable,
and others even more so, such as calling sin/cos in run-time when a fixed point sines table
already exists. o_O I'm sure there may be a reason for it, I haven't tried to understand 100%
of the code yet.) :p

Anim8or export plugin (WIP, does not export UVs and other stuff.)
Code:
/* export_ZeEngineC_plugin.a8s - based on the original Anim8or C exporter script.*/

#plugin("object", "export", "ZeEngine source", ".c");
#file($output, "text");
#return($result);

file $output;
int $result;

object $curObject;

$curObject = project.curObject;
$output.print("\n");

shape $shape, $shapes[1], $childShapes[1];
tridata $tdata;
int $numPoints, $numNormals, $numTexCoords, $numTriangles, $numMaterials;
int $ii, $jj, $curLineID;
point3 $point, $normal;
point2 $uv;
float4x4 $transformMat, $normalTransformMat;
material $material;
string $names[0];
texture $tex[7];
string $name[7];
int $Lines[0], $LinesA[0], $LinesB[0];

/* The shapes in $shapes are processed in reverse order so */
/* reverse the array of values that GetShapes returns:	 */

$curObject.GetShapes($childShapes);
$shapes.size = 0;
while ($childShapes.size > 0)
	$shapes.push($childShapes.pop());

while ($shapes.size > 0) {
	$shape = $shapes.pop();

	/* If $shape is a group push child shapes onto stack: */

	if ($shape.GetKind() == SHAPE_KIND_GROUP) {
		$shape.GetShapes($childShapes);
		$output.print("# Group \"%s\" has %d children:\n",
					  $shape.name, $childShapes.size);
		while ($childShapes.size > 0) {
			$shapes.push($childShapes.pop());
		}
	} else if ($shape.GetKind() == SHAPE_KIND_PATH ||
			   $shape.GetKind() == SHAPE_KIND_MODIFIER ||
			   $shape.GetKind() == SHAPE_KIND_TEXT)
	{
		/* No 3D mesh to output. */
	} else {
		$tdata = $shape.GetTriangleData();
		$transformMat = $shape.GetGlobalTransform();
		$normalTransformMat = $shape.GetGlobalNormalTransform();
		$numPoints = $tdata.GetNumPoints();
	$Lines.size = $numPoints * $numPoints;
	$LinesA.size = $Lines.size;
	$LinesB.size = $Lines.size;


	/* Reset Lines */
	for $ii = 0 to $Lines.size - 1 do{
	  $Lines[ $ii ] = -1;
	}


	/* Process lines */

		$numTriangles = $tdata.GetNumTriangles();
	$curLineID = -1;
	for $ii = 0 to $numTriangles - 1 do{
		if( $Lines[ $tdata.GetIndex($ii*3) * $numPoints + $tdata.GetIndex($ii*3+1) ] == -1 ) $curLineID = $curLineID+1;
		$Lines[ $tdata.GetIndex($ii*3) * $numPoints + $tdata.GetIndex($ii*3+1) ] = $curLineID;
		$LinesA[ $tdata.GetIndex($ii*3) * $numPoints + $tdata.GetIndex($ii*3+1) ] = $tdata.GetIndex($ii*3);
		$LinesB[ $tdata.GetIndex($ii*3) * $numPoints + $tdata.GetIndex($ii*3+1) ] = $tdata.GetIndex($ii*3+1);

		if( $Lines[ $tdata.GetIndex($ii*3) * $numPoints + $tdata.GetIndex($ii*3+2) ] == -1 ) $curLineID = $curLineID+1;
		$Lines[ $tdata.GetIndex($ii*3) * $numPoints + $tdata.GetIndex($ii*3+2) ] = $curLineID;
		$LinesA[ $tdata.GetIndex($ii*3) * $numPoints + $tdata.GetIndex($ii*3+2) ] = $tdata.GetIndex($ii*3);
		$LinesB[ $tdata.GetIndex($ii*3) * $numPoints + $tdata.GetIndex($ii*3+2) ] = $tdata.GetIndex($ii*3+2);

		if( $Lines[ $tdata.GetIndex($ii*3+1) * $numPoints + $tdata.GetIndex($ii*3+2) ] == -1 ) $curLineID = $curLineID+1;
		$Lines[ $tdata.GetIndex($ii*3+1) * $numPoints + $tdata.GetIndex($ii*3+2) ] = $curLineID;
		$LinesA[ $tdata.GetIndex($ii*3+1) * $numPoints + $tdata.GetIndex($ii*3+2) ] = $tdata.GetIndex($ii*3+1);
		$LinesB[ $tdata.GetIndex($ii*3+1) * $numPoints + $tdata.GetIndex($ii*3+2) ] = $tdata.GetIndex($ii*3+2);
	}


	/* Output header and Point data */
  point3 $MinP, $MaxP, $CurP;
  float $ld, $offs;
  $MinP = $tdata.GetPoint(0);
  $MaxP = $MinP;
  for $ii = 0 to $numPoints - 1 do{
	$CurP = $tdata.GetPoint($ii);
	if( $MinP.x > $CurP.x ) $MinP.x = $CurP.x;
	if( $MinP.y > $CurP.y ) $MinP.y = $CurP.y;
	if( $MinP.z > $CurP.z ) $MinP.z = $CurP.z;

	if( $MaxP.x < $CurP.x ) $MaxP.x = $CurP.x;
	if( $MaxP.y < $CurP.y ) $MaxP.y = $CurP.y;
	if( $MaxP.z < $CurP.z ) $MaxP.z = $CurP.z;
  }
  $ld = $MaxP.x - $MinP.x;
  $output.print("// Debug: $ld = %f.\n", $ld );
  if( $MaxP.y - $MinP.y > $ld ) $ld = $MaxP.y - $MinP.y;
  if( $MaxP.z - $MinP.z > $ld ) $ld = $MaxP.z - $MinP.z;
  $ld = 0xFF / $ld;
	$jj = 0;
		$output.print( "short %s[] = { %d, %d, %d,\n ",  $shape.name, $numPoints, $curLineID+1, $tdata.GetNumTriangles() );
  for $ii = 0 to $numPoints - 1 do{
			$point = $tdata.GetPoint($ii);
			$point = $transformMat.Project($point);
			$point.x = $point.x*$ld;
			$point.y = $point.y*$ld;
			$point.z = $point.z*$ld;
		int $x, $y, $z;
		/* $x = ($point.x+0xFFFF)*1024;  $y = ($point.y+0xFFFF)*1024;  $z = ($point.z+0xFFFF)*1024; */
		$x = $point.x;  $y = $point.y;  $z = $point.z;
			$output.print(" %d, %d, %d, 0,", $x, $y, $z );
		$jj = $jj + 1;
		if( $jj == 4 ){
		$output.print("\n ");
	   	$jj = 0;
		}
		}

	/* Output Line list */
	$jj = 0;
	$output.print("\n// Lines\n  ");
	for $ii = 0 to $Lines.size - 1 do{
 		if( $Lines[$ii] != -1 ){
			$output.print( " %d, %d, 0,", $LinesA[$ii], $LinesB[$ii] );
			$jj = $jj + 1;
			if( $jj == 4 ){
		  $output.print("\n ");
	   	  $jj = 0;
			}
		}
	}


	/* Output polygon index list */

	$jj = 0;
	$output.print("\n// Indices\n  ");
		for $ii = 0 to $numTriangles - 1 do{
			$output.print(" %d, %d, %d",
						  $tdata.GetIndex($ii*3),
						  $tdata.GetIndex($ii*3 + 1),
						  $tdata.GetIndex($ii*3 + 2));
	  if( $ii != $numTriangles - 1 ) $output.print(",");
		$jj = $jj + 1;
		if( $jj == 4 ){
		  $output.print("\n ");
	   	$jj = 0;
		}
		}
		$output.print("\n};\n");
		$output.print("\n");

	}
}

$output.print("\n");

$output.print("// End of file \"%s\"\n", $output.GetName());

$result = 1;		/* Report success. */

ZeEngine3D Loader (based loosely on the original 16 bit one):
Code:
void Load16bit3do(object3d *obj, short* objdata, int neg){
	obj->npts = *objdata++;
	obj->nlns = *objdata++;
	obj->npls = *objdata++;

	obj->point = (point3d*) malloc(obj->npts * sizeof(point3d));
	obj->line = (line2d*)   malloc(obj->nlns * sizeof(line2d));
	obj->poly = (poly2d*)   malloc(obj->npls * sizeof(poly2d));

	int i;
	for (i=0; i<obj->npts; i++)
	{
		obj->point[i].x = *objdata++ >> 1;
		obj->point[i].y = *objdata++ >> 1;
		obj->point[i].z = *objdata++ >> 1;
		obj->point[i].c = *objdata++;
	}

	for (i=0; i<obj->nlns; i++)
	{
		obj->line[i].p0 = *objdata++;
		obj->line[i].p1 = *objdata++;
		objdata++;
		obj->line[i].c = 0xFFFF;
	}

	for (i=0; i<obj->npls; i++)
	{
		obj->poly[i].p0 = *objdata++;
		obj->poly[i].p1 = *objdata++;
		obj->poly[i].p2 = *objdata++;
	}

	ReversePolygonOrder(obj);
	CalcNorms(obj, neg);
	CalcPtNorms(obj);
}
 
Well, not really...
The Anim8or plugin interface is still under development and so it has various limitations.
1) Text export only (so the binary 3do object is currently impossible to use).
2) Anim8or can't export animations.

I hope the next version fixes these issues, I'd really like to use anim8or for character animation.
 
Back
Top