Public feed
#722600
<?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. //
///////////////////////////////////////////////////////////////////////////
?>