Public feed #722600

drawInfo Machine 0.4

public text v1 · immutable
Raw Edit
·published 2007-10-02 03:59 UTC
rendered paste body
<?php
		
		////////////////////////////////////////////////////////////
		//              PHP DrawInfo-Machine v. 0.4               //
		//                      by Ted Smoker (Tedius)            //
		//       Use this exporter to convert a .obj file         //
		//       into BZFlag DrawInfo format.  This allows        //
		//       you to use LODs (Levels of Detail) to make       //
		//       numerous meshes render efficiently, as well      //
		//       as the ability to rotate or revolve objects      //
		//       with the angvel setting.                         //
		//                                                        //
		//       Procedures:                                      //
		//       1. You must have PHP 5.2 or later installed      //
		//          (http://www.php.net/downloads.php#v5)         //
		//       2. Create copies of your model with less         //
		//          resolution. (Polygon-reduction, Dec-          //
		//          imation)                                      //
		//       3. At the command-line, type:                    //
		//     	    php drawinfomachine.php /path/to/object.obj   //
		//       4. Copy and paste or pipe the result into a      //
		//          BZFlag map                                    //
		//                                                        //
		//                                                        //
		//        For more information about DrawInfo, see:       //
		//            http://my.bzflag.org/w/DrawInfo			  //
		////////////////////////////////////////////////////////////

$file = file($argv[1]);
$min_loddistance = 0;		//when the object becomes visible
$max_loddistance = 1;		//change this to .1 or .2 to make the object disappear
$flipverts=0;

//Randomizer
$randomizer=0;
$worldsize=400;
$objects=25;

//Variable initializing
$corner_def=array();
$corner_index=array();
$tricorner=array();
$vertex=array();
$normal=array();
$texcoord=array();
$quadcorner=array();
$tristrip_count=0;
$tristrip=array();
$matref="default";
$material=array();
$poly_count=0;

foreach ($file as $i => $value) {
	if (substr($value, 0, 2) == "v ") {		//Create an array of the vertices
		list($junk, $x, $y, $z) = split(" ", $value);  
		$z = trim($z);						//get rid of the line break
		$xverts[]=$x;
		$yverts[]=$y;
		$zverts[]=$z;
		if ($flipverts){
			$vertex[]="$x $z $y";
		} else {
			$vertex[]="$x $y $z";
		}
		
	} elseif (substr($value, 0, 3) == "vn ") {			//create vertex normals
		list($junk, $x, $y, $z) = split(" ", $value);
		$z = trim($z);
 		$dist = sqrt(($x*$x)+($y*$y)+($z*$z)); // normalize the normals
		if ($dist != 0) {
			$x = $x / $dist;
			$y = $y / $dist;
			$z = $z / $dist;
		}
		if($flipverts){
			$normal[]="$x $z $y";
		} else {
			$normal[]="$x $y $z";
		}
	} elseif (substr($value, 0, 3) == "vt ") {					//create texcoords
		list($junk, $x, $y) = split(" ", $value);
		$y = trim($y);						
			$texcoord[]="$x $y";

		//Corner Definitions, put into an array, and reference them later
	} elseif (substr($value, 0, 2) == "f "|| substr($value, 0, 2) == "t " || substr($value, 0, 2) =="q ") {
			$cornerinit = split(" ", trim($value));
			foreach ($cornerinit as $cornerraw) {
				if ($cornerraw =="f" || $cornerraw == "t" || $cornerraw =="q") { //ignore
					continue;
				} elseif (in_array($cornerraw, $corner_def)) { //dup check, do nothing
					continue;
				} else {
					$corner_def[]=$cornerraw;
				}//cornerraw if
			}//cornerinit foreach
	}//finding face data
	
} unset($value);	//end foreach line parser
if(!isset($normal[0])) $normal[0]="0 0 0";		//creates a single dummy normal/texcoord, for when there is none
if(!isset($texcoord[0])) $texcoord[0]="0 0 0";

//Create the Polygons
foreach ($file as $i=> $value) {
	if (substr($value, 0, 6) =="usemtl") {
		$matref = trim(substr($value, 7));
	}
	//Tris
	if (substr($value, 0, 2) == "f " && substr_count($value, " ") == 3) {   	//only tris faces
		$cornerinit = split(" ", trim($value));
		foreach ($cornerinit as $cornerraw) {
			if ($cornerraw == "f") {			//ignore
				continue;
			} else {
				$material[$matref]["tris"][]=array_search($cornerraw, $corner_def);
			}//defined corners, they can be all in one big strip, so we're done with tris				
		}//foreach cornerraws
	}
	//Quads
	if (substr($value, 0, 2) == "f " && substr_count($value, " ") == 4) {		//only quads
		$cornerinit = split(" ", trim($value));
		foreach ($cornerinit as $cornerraw) {
			if ($cornerraw == "f") {			//ignore
				continue;
			} else {
				$cornerraw=trim($cornerraw);
				$material[$matref]["quads"][]=array_search($cornerraw, $corner_def);
			}//end quadcorners				
		}//foreach cornerraws
	}	//end quadfaces
	if(substr($value, 0, 2) == "f " && substr_count($value, " ") > 4){		//only polygons
		$cornerinit = split(" ", trim($value));
		foreach($cornerinit as $cornerraw){
			if($cornerraw == "f"){			//ignore
				$poly_count++;
				}else{
					$cornerraw=trim($cornerraw);
					$material[$matref]["polygon"][$poly_count][]=array_search($cornerraw, $corner_def);
				}//end polygoncorners				
			}//foreach cornerraw
		}	//end polyfaces
	//tristrips
	if (substr($value, 0, 2) == "t " || substr($value, 0, 2) == "q ") {		//only tristrips
		if (substr($value, 0, 2) == "t ") {
			$tristrip_count++;
			$cornerinit = split(" ", trim($value));
			foreach ($cornerinit as $cornerraw) {
				if ($cornerraw == "t") {			//ignore
					continue;
				} else {
					$cornerraw=trim($cornerraw);
					$tristrip[$tristrip_count][]=array_search($cornerraw, $corner_def);
				} //end cornerraw if
			} //end cornerinit foreach
		} elseif(substr($value, 0, 2) == "q ") {							//continuation of tristrip
			$cornerinit = split(" ", trim($value));
			foreach ($cornerinit as $cornerraw) {
				if ($cornerraw == "q") {			//ignore
					continue;
				} else {
					$cornerraw=trim($cornerraw);
					$tristrip[$tristrip_count][]=array_search($cornerraw, $corner_def);
				} //cornerraw if
			}unset($value); //cornerinit foreach
		} //continuation elseif
	}
}

if(!isset($vertex[0])){						//Kill
	echo "Error! No vertex information present.";
	exit();;
}
echo "#######################################\n";
echo "# Created with PHP DrawInfo-Machine   #\n";
echo "#     (c)2007 Ted Smoker (Tedius)     #\n";
echo "#######################################\n\n\n";
echo "material\n\tname $matref\n\taddtexture mesh\nend\n\n";
echo "define object\n";
echo "#### copy from this point on if you are inserting multiple lods\n";
echo "\tmesh\n";
$k = count($vertex);
echo "\t\t# vertices: $k\n";
$k = count($normal);
echo "\t\t# normals: $k\n";
$k = count($texcoord);
echo "\t\t# texcoords: $k\n";

//Print the vertex data
foreach ($vertex as $i => $value) {
	echo "\t\tvertex $value\t\t# $i\n";
	} unset($value);
foreach ($normal as $i => $value) {
	echo "\t\tnormal $value\t\t# $i\n";
	} unset($value);
foreach ($texcoord as $i => $value) {
	echo "\t\ttexcoord $value\t\t# $i\n";
	} unset($value);

echo "\t\tdrawInfo\n";
echo"\t\tdlist\n";
echo "\t\t\t#angvel 120\t# uncomment this line to cause the object to spin at 120 degrees/second\n";
echo "\t\t\textents ".min($xverts)." ".min($yverts)." ".min($zverts)." ".max($xverts)." ".max($yverts)." ".max($zverts)."\n";
//Print out the corners	
foreach ($corner_def as $key => $value) {
	@list($v, $t, $n)=split("/",$value);
	if (!$n)$n=1; //using the .obj index to refer to dummy vert								
	if (!$t)$t=1;									
	$v = $v - 1;				// the corner indexes are unit offset in obj file and 
	$n = $n - 1;					// need to be zero offset in bzw file
	$t = $t - 1;
	echo "\t\t\tcorner $v $n $t\t\t# $key\n";
} unset($value);		//foreach corner

echo "\t\t\tlod\n";
echo "\t\t\t\tlengthPerPixel $min_loddistance\t#the distance from which the object appears (default 0)\n";
foreach ($material as $matkey => $matvalue){
	echo "\n\t\t\t\tmatref $matkey";
	foreach($matvalue as $key => $poly){
		if($key == "polygon"){
			foreach($poly as $polygon){
				echo "\n\t\t\t\t\t$key ";
				foreach ($polygon as $value){
					echo "$value ";
				}
			}unset($value);
		}else{
			echo "\n\t\t\t\t\t$key ";		//$key here is quads, or tris, etc.. 
			foreach($poly as $value){
				 echo "$value ";
			}
		}
	}unset($value);
	echo "\n\t\t\t\tend\t# matref\n";
}
if ($tristrip) {
	foreach ($tristrip as $tristrip_index) {
		echo "\n\t\t\t\ttristrip ";
		foreach ($tristrip_index as $value) {
			echo "$value ";
		}
	} unset($value);
}
echo "\t\t\tend\t# lod\n\n";
echo "\t\t\tlod\n";
echo "\t\t\t\tlengthPerPixel $max_loddistance\t# the distance from which the object ceases to be seen (default 1)\n";
echo "\t\t\tend\t# lod\n";
echo "\t\tend\t# drawInfo\n";
echo "\tend\t#mesh\n";
echo "###### end copy for multiple lods here\n";
echo "enddef\t#object definition\n";
echo "group object\n\tscale 1 1 1\n\tshift 0 0 10\nend\n";

//Bonus track: the Randomizer, enable by changing $randomizer variable to 1
if ($randomizer) {
	for ($i = 0; $i <= $objects; $i++) {
		$x = (RAND(-$worldsize*10,$worldsize*10)/10);
		$y = (RAND(-$worldsize*10,$worldsize*10)/10);
		$spin = RAND(10,1800)/10;
		echo "group object # $i\n\tshift $x $y 0\n\tspin $spin 0 0 1\nend\n";
	}
}
//var_dump ($material);

     ////////////////////////////////////////////////////////////////////////////
    //    This work is licensed under the Creative Commons Attribution 3.0    //
   //    Unported License. To view a copy of this license, visit             //
  //    http://creativecommons.org/licenses/by/3.0/ or send a letter        // 
 //    to Creative Commons, 171 Second Street, Suite 300, San Francisco,   //
//    California, 94105, USA.                                             //
///////////////////////////////////////////////////////////////////////////
?>