Zend - The PHP Company




3-D

Add Code


Back to the Mazes  

Type: application
Added by: codewalkers
Entered: 23/06/2002
Last modified: 09/12/2001
Rating: **** (3 votes)
Views: 14603
This is a winner of the Codewalkers.com PHP Coding Contest. This script will take a text file as input and generate a 3D maze. Makes beautiful use of the GD library. Features real diffuse+specular+ambient lightning, semi-real light refraction+transparency, fake shadows, wall outlining, anti-aliasing and results caching. More details on the contest and to see output from this script at http://codewalkers.com/


<?
/*

Written and copyrighted (2002) by Mitja Slenc
E-mail: <removed>

I wanted to create a kind of ray-tracish look...

Features real diffuse+specular+ambient lightning,
semi-real light refraction+transparency, fake
shadows, wall outlining, anti-aliasing and results 
caching.

*/

// ------- START CONFIGURATION -------
// approximate width of image that is wanted
$conf_reqwidth=600;

// should cache results?
$conf_cache=1;

// direction toward light
// x and y must be negative, z must be positive!
// Will get normalized below.
// Won't work properly, if shadowoffset>tilesize,
// so be careful with relatively small z
$conf_light=array(-1, -1.61);
// -------- END CONFIGURATION --------





set_time_limit(0);
//error_reporting(E_ALL);


// should anti-alias? (4x slower)
$conf_aalias=0;

// should apply shading?
$conf_shade=0;

// override via form
if (isset($_GET["shade"]) && $_GET["shade"]) $conf_shade=1;
if (isset(
$_GET["alias"]) && $_GET["alias"]) $conf_aalias=1;

// normalize light vector
$len=$conf_light[0]*$conf_light[0]+$conf_light[1]*$conf_light[1]+$conf_light[2]*$conf_light[2];
$len=1.0/sqrt($len);
$conf_light[0]*=$len;
$conf_light[1]*=$len;
$conf_light[2]*=$len;


// read mazes
$lines=file("mazes.txt");

$mazes=array();
$thismaze=array();

$ditherr=array();

for (
$a=0$a<sizeof($lines); $a++) {
    
$tmp=trim($lines[$a]);
    if (!
strlen($tmp)) {
        if (
sizeof($thismaze)) {
            
$mazes[]=$thismaze;
            
$thismaze=array();
        }
    } else {
        
$tmp=explode("!"$tmp);
        for (
$b=0$b<sizeof($tmp); $b++) {
            
$thismaze[]=ExplodeMazeLine($tmp[$b]);
        }
    }
}

if (
sizeof($thismaze))
    
$mazes[]=$thismaze;

if (isset(
$_GET["getmaze"])) {
    
OutMaze($mazes[(int)$_GET["getmaze"]]);
    exit();
}

if (isset(
$_GET["makeall"])) {
    echo 
"<html><head><style type="text/css">
    body, td {
        font-family: "
verdana", sans-serif;
    }
    </style>
    </head><body>"
;
    echo 
"<center>";
    echo 
"<a href="$PHP_SELF?">Back</a><br><br>";
    
touch("/tmp/mitjasmaze_createdall.txt");
    
$made=0;
    for (
$alias=0$alias<2$alias++) {
        for (
$shade=0$shade<2$shade++) {
            for (
$maze=0$maze<sizeof($mazes); $maze++) {
                
$conf_shade=$shade;
                
$conf_aalias=$alias;
                
$has_generated=0;
                
$tiles_total=0;
                
$tiles_copied=0;

                
ob_start();
                list(
$a,$b)=explode(" "microtime());
                
$starttime=(float)$a+(float)$b;
                
OutMaze($mazes[$maze]);
                list(
$a,$b)=explode(" "microtime());
                
$endtime=(float)$a+(float)$b;
                
ob_end_clean();

                if (
$has_generated) {
                    echo 
"Maze ".($maze+1)." (shade=$shade, alias=$alias)<br>Generated in ".sprintf("%.2f"$endtime-$starttime)." seconds<br>$tiles_total tiles of which $tiles_copied were cached<br><img src="$PHP_SELF?getmaze=$maze&amp;shade=$shade&amp;alias=$alias"><br><hr><br>";
                    
$made=1;
                    
flush();
                }
            }
        }
    }
    if (
$made) {
        echo 
"<br><br><a href="$PHP_SELF?">Back</a>";
    } else {
        echo 
"<br><br>All mazes were already generated.";
    }
    echo 
"</center></body></html>";
} else {
    echo 
"<html><head><style type="text/css">
    body, td {
        font-family: "
verdana", sans-serif;
    }
    </style>
    </head><body>"
;
    echo 
"<center>";
    echo 
"<form method=get action="$PHP_SELF">";
    echo 
"<input type=hidden name=formsubmitted value=1>";
    echo 
"<table><tr><td align=right><b>Shading:</b></td><td><input type=checkbox name=shade value=1";
    if (
$conf_shade)
        echo 
" checked=1";
    echo 
"></td></tr>";
    echo 
"<tr><td align=right><b>Anti-aliasing:</b></td><td><input type=checkbox name=alias value=1";
    if (
$conf_aalias)
        echo 
" checked=1";
    echo 
"></td></tr>";
    echo 
"<tr><td align=center><input type=submit value="Redraw"></td></tr>";
    echo 
"</table></form>";
    if (
$conf_cache && (!isset($_GET["formsubmitted"])) && (!file_exists("/tmp/mitjasmaze_createdall.txt") || filemtime("/tmp/mitjasmaze_createdall.txt")<filemtime("mazes.txt"))) {
        echo 
"or<br><br><a href="$PHP_SELF?makeall=1">Create all images</a><br><br>";
    }
    if (isset(
$_GET["formsubmitted"])) {
        for(
$a=0$a<sizeof($mazes); $a++) {
            echo 
"<img src="$PHP_SELF?getmaze=$a&amp;shade=".$conf_shade."&amp;alias=".$conf_aalias.""><br><br><br>";
        }
    }
    echo 
"</center></body></html>";
}


function 
OutMaze($maze)
{
    
$starttime=time();

    global 
$tilesize$bw$colors$ww;
    global 
$conf_reqwidth;
    global 
$conf_cache$conf_aalias$conf_shade;
    global 
$conf_light;
    global 
$tiles_total$tiles_copied;

    
// double the size for antialiasing
    
if ($conf_aalias)
        
$reqwidth=$conf_reqwidth<<1;
    else
        
$reqwidth=$conf_reqwidth;

    
$w=strlen($maze[0]);
    
$h=sizeof($maze);

    
// pad with spaces
    
$tmp=array();
    
$tmp[]=str_repeat(" "$w+2);
    foreach(
$maze as $line)
        
$tmp[]=" ".$line." ";
    
$tmp[]=str_repeat(" "$w+2);

    
$maxlen=0;
    for (
$a=0$a<sizeof($tmp); $a++)
        if (
strlen($tmp[$a])>$maxlen)
            
$maxlen=strlen($tmp[$a]);
    for (
$a=0$a<sizeof($tmp); $a++) {
        if (
strlen($tmp[$a])<$maxlen)
            
$tmp[$a].=str_repeat(" "$maxlen-strlen($tmp[$a]));
    }

    
$maze=$tmp;

    
$w=$maxlen;
    
$h=sizeof($maze);

    
// compute tile size

    
$tilesize=(int)($reqwidth/$w);
    if (
$tilesize 1)
        
$tilesize++;
    if (
$conf_aalias) {
        if (
$tilesize>128)
            
$tilesize=128;
        if (
$tilesize<32)
            
$tilesize=32;
    } else {
        if (
$tilesize>64)
            
$tilesize=64;
        if (
$tilesize<16)
            
$tilesize=16;
    }

    
// check for cached copy
    
if ($conf_cache) {
        
$md5=md5($tilesize."_".implode("_"$conf_light)."_".$conf_shade."_".$conf_aalias."_".implode("_"$maze));
        if (
file_exists("/tmp/mitjasmaze_$md5.png")) {
            
header("Content-type: image/png");
            
readfile("/tmp/mitjasmaze_$md5.png");
            return;
        }
    }

    
// for makeall
    
global $has_generated;
    
$has_generated=1;


    
$ww=$w*$tilesize+1;
    
$hh=$h*$tilesize+1;

    
$im=imagecreatetruecolor($ww$hh);
    
imagealphablending($imtrue);


    
// ALLOCATE COLORS
    
$mycols=array(
        array(
0,0,0), // " " gets this one always
        
array(0,0,0),
        array(
128,255,0),
        array(
0,128,255),
        array(
128,0,255),
        array(
255,128,0),
        array(
0,0,128),
        array(
0,0,255),
        array(
0,128,0),
        array(
0,128,128),
        array(
0,255,0),
        array(
0,255,128),
        array(
0,255,255),
        array(
128,0,0),
        array(
128,0,128),
        array(
128,128,0),
        array(
128,128,128),
        array(
128,128,255),
        array(
128,255,128),
        array(
128,255,255),
        array(
255,0,128),
        array(
255,0,255),
        array(
255,128,128),
        array(
255,128,255),
        array(
255,255,0),
        array(
255,255,128),
        array(
255,255,255)
    );

    
$tmp=implode(""$maze);
    
$colpointer=0;
    
$colors=array();
    for (
$a=0$a<strlen($tmp); $a++) {
        
$c=substr($tmp$a1);
        if (!isset(
$colors[$c])) {
            if (
$c=="*") {
                
$colors[$c]=array(255,64,64);
            } else {
                if (isset(
$mycols[$colpointer])) {
                    
$colors[$c]=$mycols[$colpointer];
                    
$colpointer++;
                } else {
                    
$colors[$c]=array(mt_rand(64,192), mt_rand(64,192), mt_rand(64,192));
                }
            }
        }
    }

    
// pre-calc various sizes
    
$half=$tilesize>>1;
    
$d=0.2/$conf_light[2];
    
$soffsetx=(int)(-$conf_light[0]*$d*$tilesize);
    
$soffsety=(int)(-$conf_light[1]*$d*$tilesize);

    
$bw=(int)(5*$tilesize/10);
    if (!(
$bw 1))
        
$bw++;
    
$bw=(($bw-1)>>1)+1;
    
$diff=$half-$bw;

    
$already=array();


    
// pre-calc shapes and normals
    
$precalc=array();
    
$normals=array();
    for (
$ox=0$ox<=$half$ox++)
    for (
$oy=0$oy<=$half$oy++) {
        
// FULL
        
$precalc[0][$ox][$oy]=1;
        
$normals[0][$ox][$oy]=array(0,0,1);

        
// VERTICAL TUBE
        
if ($ox<$bw) {
            
$precalc[1][$ox][$oy]=1;
            
$normals[1][$ox][$oy]=array($ox/$bw0sqrt(1-(($ox/$bw)*($ox/$bw))));
        } else {
            
$precalc[1][$ox][$oy]=0;
        }

        
// HORIZONTAL TUBE
        
if ($oy<$bw) {
            
$precalc[2][$ox][$oy]=1;
            
$normals[2][$ox][$oy]=array(0$oy/$bwsqrt(1-(($oy/$bw)*($oy/$bw))));
        } else {
            
$precalc[2][$ox][$oy]=0;
        }

        
// OUTER ROUND
        
if (($ox*$ox+$oy*$oy)<($bw*$bw)) {
            
$precalc[3][$ox][$oy]=1;
            
$nx=$ox/$bw;
            
$ny=$oy/$bw;
            
$nz=sqrt(1-$nx*$nx-$ny*$ny);
            
$normals[3][$ox][$oy]=array($nx$ny$nz);
        } else {
            
$precalc[3][$ox][$oy]=0;
        }

        
// CROSS (*)

        
$found1=0;
        
$found2=0;

        
$nx=$ox/$half;
        
$ny=$oy/$half;
        
$dist=sqrt($nx*$nx+$ny*$ny);


        if ((
$nx+$ny)<1.1 && (abs($nx-$ny)<0.4)) {
            
$precalc[5][$ox][$oy]=1;
            
$found2=1;
            if (
$ny>$nx) {
                
$vx=-0.6314;
                
$vy=0.6314;
                
$vz=0.45;
            } else {
                
$vx=0.66666;
                
$vy=-0.66666;
                
$vz=0.45;
            }
            if (
abs($nx-$ny)>0.33 || (($nx+$ny)>1.03)) {
                
// force outline
                
$normals[5][$ox][$oy]=array(0,0,0.3);
            } else {
                
$normals[5][$ox][$oy]=array($vx$vy$vz);
            }
        } else {
            
$precalc[5][$ox][$oy]=0;
        }


        
// INNER ROUND
        
$vx=$half-$ox;
        
$vy=$half-$oy;
        
$sdist=$vx*$vx+$vy*$vy;
        if (
$sdist>($diff*$diff)) {
            
$precalc[4][$ox][$oy]=1;
            
$dist=sqrt($sdist);
            if (
$dist<$half) {
                
$tdist=$dist-$diff;
                
$off=$bw-$tdist;
                
$vx*=$off/$bw/$dist;
                
$vy*=$off/$bw/$dist;
                
$vz=sqrt(1.0-$vx*$vx-$vy*$vy);
                
$normals[4][$ox][$oy]=array($vx$vy$vz);
            } else {
                
$normals[4][$ox][$oy]=array(0,0,1);
            }
        } else {
            
$precalc[4][$ox][$oy]=0;
        }

        
// DIAGONAL 
        
if (abs($oy-$ox)/sqrt(2)<$bw) {
            
$precalc[6][$ox][$oy]=1;
            
$d=($oy-$ox)/sqrt(2)/$bw;
            
$vz=sqrt(1-$d*$d);
            
$vx=-$d/sqrt(2);
            
$vy=$d/sqrt(2);
            
$normals[6][$ox][$oy]=array($vx$vy$vz);
        } else {
            
$precalc[6][$ox][$oy]=0;
        }

        if ((
$oy+$ox)/sqrt(2)<$bw && $oy>$ox) {
            
$precalc[7][$ox][$oy]=1;
            
$d=($oy+$ox)/sqrt(2)/$bw;
            
$vz=sqrt(1-$d*$d);
            
$vx=$d/sqrt(2);
            
$vy=$d/sqrt(2);
            
$normals[7][$ox][$oy]=array($vx,$vy,$vz);
        } else {
            if (
$precalc[3][$ox][$oy]) {
                
$precalc[7][$ox][$oy]=1;
                
$normals[7][$ox][$oy]=$normals[3][$ox][$oy];
            } else {
                
$precalc[7][$ox][$oy]=0;
            }
        }

        if ((
$oy+$ox)/sqrt(2)<$bw && $oy<$ox) {
            
$precalc[8][$ox][$oy]=1;
            
$d=($oy+$ox)/sqrt(2)/$bw;
            
$vz=sqrt(1-$d*$d);
            
$vx=$d/sqrt(2);
            
$vy=$d/sqrt(2);
            
$normals[8][$ox][$oy]=array($vx,$vy,$vz);
        } else {
            if (
$precalc[3][$ox][$oy]) {
                
$precalc[8][$ox][$oy]=1;
                
$normals[8][$ox][$oy]=$normals[3][$ox][$oy];
            } else {
                
$precalc[8][$ox][$oy]=0;
            }
        }

        if ((
$oy+$ox)/sqrt(2)<$bw) {
            
$precalc[9][$ox][$oy]=1;
            
$d=($oy+$ox)/sqrt(2)/$bw;
            
$vz=sqrt(1-$d*$d);
            
$vx=$d/sqrt(2);
            
$vy=$d/sqrt(2);
            if (
$precalc[2][$ox][$oy]) {
                if (
$normals[2][$ox][$oy][2]>$vz)
                    list(
$vx,$vy,$vz)=$normals[2][$ox][$oy];
            }
            
$normals[9][$ox][$oy]=array($vx,$vy,$vz);
        } else {
            if (
$precalc[2][$ox][$oy]) {
                
$precalc[9][$ox][$oy]=1;
                
$normals[9][$ox][$oy]=$normals[2][$ox][$oy];
            } else {
                
$precalc[9][$ox][$oy]=0;
            }
        }

        if ((
$oy+$ox)/sqrt(2)<$bw) {
            
$precalc[10][$ox][$oy]=1;
            
$precalc[12][$ox][$oy]=1;
            
$d=($oy+$ox)/sqrt(2)/$bw;
            
$vz=sqrt(1-$d*$d);
            
$vx=$d/sqrt(2);
            
$vy=$d/sqrt(2);
            
$normals[12][$ox][$oy]=array($vx,$vy,$vz);
            if (
$precalc[1][$ox][$oy]) {
                if (
$normals[1][$ox][$oy][2]>$vz)
                    list(
$vx,$vy,$vz)=$normals[1][$ox][$oy];
            }
            
$normals[10][$ox][$oy]=array($vx,$vy,$vz);
        } else {
            
$precalc[12][$ox][$oy]=0;
            if (
$precalc[1][$ox][$oy]) {
                
$precalc[10][$ox][$oy]=1;
                
$normals[10][$ox][$oy]=$normals[1][$ox][$oy];
            } else {
                
$precalc[10][$ox][$oy]=0;
            }
        }

        if (((
$half-$ox)+($half-$oy))/sqrt(2)<$bw) {
            
$d=(($half-$ox)+($half-$oy))/sqrt(2)/$bw;
            
$vz=sqrt(1-$d*$d);
            
$vx=-$d/sqrt(2);
            
$vy=-$d/sqrt(2);
            
$precalc[11][$ox][$oy]=1;
            
$normals[11][$ox][$oy]=array($vx$vy$vz);
        } else {
            
$precalc[11][$ox][$oy]=0;
        }
    }

    
// fill background
    
$ts=$tilesize;
    for (
$x=0$x<$tilesize$x++)
        for (
$y=0$y<$tilesize$y++)
            
MyImageSetPixel($im$x$yBackColor($x$y));

    for (
$x=0$x<=$w$x++) {
        for (
$y=0$y<=$h$y++) {
            if (!
$x && !$y)
                continue;
            
imagecopy($im$im$x*$tilesize$y*$tilesize00$tilesize$tilesize);
        }
    }

    
// finally, render the maze
    
for ($y=0$y<$h$y++) {
        for (
$x=0$x<$w$x++) {
            
$tiles_total++;

            if ((
$c=$maze[$y][$x])==" ")  {
                if (!
$x || !$y || ($x==($w-1)) || ($y==($h-1))) {
                    continue;
                }
            }

            
$sm=(($x+$y)&1).substr($maze[$y-1], $x-13).substr($maze[$y],$x-1,3).substr($maze[$y+1],$x-1,3);
            if (isset(
$already[$sm])) {
                list(
$sx$sy)=$already[$sm];
                
imagecopy($im$im$x*$tilesize$y*$tilesize$sx*$tilesize$sy*$tilesize$tilesize+$soffsetx+1$tilesize+$soffsety+1);
                
$tiles_copied++;
                continue;
            }

            
$already[$sm]=array($x$y);
            
$sm=array(
                array(
0,0,0),
                array(
0,0,0),
                array(
0,0,0)
            );
        
            if (
$maze[$y-1][$x]==$c$sm[1][0]=1;
            if (
$maze[$y+1][$x]==$c$sm[1][2]=1;
            if (
$maze[$y][$x+1]==$c$sm[2][1]=1;
            if (
$maze[$y][$x-1]==$c$sm[0][1]=1;
        
            if (
$maze[$y-1][$x-1]==$c$sm[0][0]=1;
            if (
$maze[$y+1][$x-1]==$c$sm[0][2]=1;
            if (
$maze[$y-1][$x+1]==$c$sm[2][0]=1;
            if (
$maze[$y+1][$x+1]==$c$sm[2][2]=1;
        
            
$bx=$x*$tilesize+$half;
            
$by=$y*$tilesize+$half;

            for (
$qx=-1$qx<2$qx+=2) {
                for (
$qy=-1$qy<2$qy+=2) {
                    
$c=$maze[$y][$x];

                    if (
$sm[$qx+1][1] && $sm[$qx+1][$qy+1] && $sm[1][$qy+1]) { // whole quadrant
                        
$mode=0;
                    } else
                    if (
$sm[$qx+1][1] && $sm[1][$qy+1]) { // inner round
                        
$mode=4;
                    } else
                    if (
$sm[$qx+1][1]) { // horizontal tube
                        
if ($sm[1-$qx][1+$qy] && (!$sm[1-$qx][1])) {
                            
$mode=9;
                        } else {
                            
$mode=2;
                        }
                    } else
                    if (
$sm[1][$qy+1]) { // vertical tube
                        
if ($sm[1+$qx][1-$qy] && (!$sm[1][1-$qy])) {
                            
$mode=10;
                        } else {
                            
$mode=1;
                        }
                    } else
                    if (
$sm[$qx+1][$qy+1]) { // diagonal
                        
$mode=6;
                    } else { 
// outer round
                        
if ($sm[1-$qx][$qy+1] && !$sm[1-$qx][1]) {
                            if (
$sm[$qx+1][1-$qy] && !$sm[1][1-$qy]) {
                                
$mode=12;
                            } else {
                                
$mode=7;
                            }
                        } else {
                            if (
$sm[$qx+1][1-$qy] && !$sm[1][1-$qy]) {
                                
$mode=8;
                            } else {
                                
$mode=3;
                            }
                        }
                    } 

                    if (
$c=="*")
                        
$mode=5;
                    if (
$c==" ")
                        
$mode=-1;

                    if (
$mode>=0) {
                        
$todo=array(array($c$mode));
                    } else {
                        
$todo=array();
                    }

                    
$blendit=0;
                    if (
$maze[$y+$qy][$x]!=" " && $maze[$y+$qy][$x]!="*") {
                        if (
$maze[$y+$qy][$x]==$maze[$y][$x+$qx]) {
                            if (
$maze[$y+$qy][$x]!=$maze[$y+$qy][$x+$qx]) {
                                if (
$maze[$y+$qy][$x]!=$c) {
                                    
$todo[]=array($maze[$y][$x+$qx], 11);
                                    if (
$c==" " || (!$sm[$qx+1][$qy+1])) {
                                        
$blendit=0;
                                    } else {
                                        
$blendit=1;
                                    }
                                }
                            }
                        }
                    }

                    if (!
sizeof($todo)) {
                        continue;
                    }

                    if (
sizeof($todo)>1) {
                        
$flip=0;
                        if (
$qx<&& $qy<0) {
                            
$flip=1;
                        } else
                        if (
$qx<0) {
                            if (
$soffsetx>$soffsety)
                                
$flip=1;
                        } else
                        if (
$qy<0) {
                            if (
$soffsetx<$soffsety)
                                
$flip=1;
                        }
                        if (
$flip) {
                            
$todo=array_reverse($todo);
                        }
                    } else {
                        
$blendit=0;
                    }

                    if (
$qx<0) {
                        
$startox=$half;
                        
$incox=-1;
                    } else {
                        
$startox=0;
                        
$incox=1;
                    }
                    if (
$qy<0) {
                        
$startoy=$half;
                        
$incoy=-1;
                    } else {
                        
$startoy=0;
                        
$incoy=1;
                    }

                    for (
$showshadows=$conf_shade$showshadows>=0$showshadows--) {
                        for (
$todocounter=0$todocounter<sizeof($todo); $todocounter++) {
                            
$c=$todo[$todocounter][0];
                            
$mode=$todo[$todocounter][1];
    
                            for (
$ox=$startox$ox>=&& $ox<=$half$ox+=$incox) {
                                
$pcalc=&$precalc[$mode][$ox];
                                
$norms=&$normals[$mode][$ox];
                                for (
$oy=$startoy$oy>=&& $oy<=$half$oy+=$incoy) {
                                    
$tarx=$bx+$ox*$qx;
                                    
$tary=$by+$oy*$qy;
                                    if (
$pcalc[$oy]) {
                                        
$n=$norms[$oy];
                                        
$n[0]*=$qx;
                                        
$n[1]*=$qy;
    
                                        if (
$conf_shade) {
                                            if (
$showshadows) {
                                                
$tmp1=BackColor($tarx+$soffsetx$tary+$soffsety);
                                                
$tmp2=$colors[$c];
        
                                                
$s=$n[2];
                                                if (
$s<0.9) {
                                                    
$s=0.5;
                                                } else {
                                                    if (
$s<0.97) {
                                                        
$s=0.5+0.5*(($s-0.9)/0.07);
                                                    } else {
                                                        
$s=3.0
                                                    }
                                                }
                                                
$s*=0.295;
        
                                                
$tmp2[0]=160+$s*(64+$tmp2[0]);
                                                
$tmp2[1]=160+$s*(64+$tmp2[1]);
                                                
$tmp2[2]=160+$s*(64+$tmp2[2]);
            
                                                
$col=array();
                                                
$col[0]=(int)(($tmp1[0]*$tmp2[0])/255);
                                                
$col[1]=(int)(($tmp1[1]*$tmp2[1])/255);
                                                
$col[2]=(int)(($tmp1[2]*$tmp2[2])/255);
                                                if (
$col[0]>255$col[0]=255;
                                                if (
$col[1]>255$col[1]=255;
                                                if (
$col[2]>255$col[2]=255;
                                                if (
$blendit) {
                                                    if (
$qx*$qy>0) {
                                                        if (
$mode==11)
                                                            
MyImageSetPixel($im$tarx+$soffsetx$tary+$soffsety$col);
                                                        else {
                                                            if (
$todocounter) {
                                                                if ((
$half+$half-$ox-$oy)/sqrt(2)>$bw)
                                                                    
MyImageSetPixel($im$tarx+$soffsetx$tary+$soffsety$col);
                                                            } else {
                                                                
MyImageSetPixel($im$tarx+$soffsetx$tary+$soffsety$col);
                                                            }
                                                        }
                                                    } else {
                                                        if (
$mode!=11)
                                                            
MyImageSetPixel($im$tarx+$soffsetx$tary+$soffsety$col);
                                                    }
                                                } else {
                                                    
MyImageSetPixel($im$tarx+$soffsetx$tary+$soffsety$col);
                                                }
                                            } else {
                                                
$col=ShadePixel($im$tarx$tary$c$n);
                                                if (
$blendit) {
                                                    if (
$qx*$qy>0) {
                                                        if (
$mode==11)
                                                            
MyImageSetPixel($im$tarx$tary$col);
                                                        else {
                                                            if (
$todocounter) {
                                                                if ((
$half+$half-$ox-$oy)/sqrt(2)>$bw)
                                                                    
MyImageSetPixel($im$tarx$tary$col);
                                                            } else {
                                                                
MyImageSetPixel($im$tarx$tary$col);
                                                            }
                                                        }
                                                    } else {
                                                        if (
$mode!=11)
                                                            
MyImageSetPixel($im$tarx$tary$col);
                                                    }
                                                } else {
                                                    
MyImageSetPixel($im$tarx$tary$col);
                                                }
                                            }
                                        } else {
                                            if (
$n[2]<0.4) {
                                                
$col=array(0,0,0);
                                            } else {
                                                
$col=$colors[$c];
                                            }
                                            if (
$blendit) {
                                                if (
$qx*$qy>0) {
                                                    if (
$mode==11)
                                                        
MyImageSetPixel($im$tarx$tary$col);
                                                    else {
                                                        if (
$todocounter) {
                                                            if ((
$half+$half-$ox-$oy)/sqrt(2)>$bw)
                                                                
MyImageSetPixel($im$tarx$tary$col);
                                                        } else {
                                                            
MyImageSetPixel($im$tarx$tary$col);
                                                        }
                                                    }
                                                } else {
                                                    if (
$mode!=11)
                                                        
MyImageSetPixel($im$tarx$tary$col);
                                                }
                                            } else {
                                                
MyImageSetPixel($im$tarx$tary$col);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    
// create a stupid frame around the image
    
$col=imagecolorresolve($im255255255);
    for (
$a=0$a<$half$a++) {
        if (
$a==($half-1)) {
            
$col=imagecolorresolve($im128,128,128);
        }
        
imageline($im00$ww$a$col);
        
imageline($im$ww-10$ww-1-$a$hh-1$col);
        
imageline($im$ww-1$hh-10$hh-1-$a$col);
        
imageline($im0$hh-1$a0$col);
    }

    if (
$conf_cache) {
        
header("Content-type: image/png");
        
MyImagePng($im"/tmp/mitjasmaze_$md5.png");
        
readfile("/tmp/mitjasmaze_$md5.png");
    } else {
        
header("Content-type: image/png");
        
MyImagePng($im);
    }
}

function 
MyImagePng($im$filename="")
{
    
// outputs the image, resizing if neccesary

    
global $conf_aalias;

    if (
$conf_aalias) {
        
$sx=imagesx($im);
        
$sy=imagesy($im);

        
$nx=($sx>>1)+1;
        
$ny=($sy>>1)+1;

        
$out=imagecreatetruecolor($nx$ny);

        
imagecopyresampled($out$im0000$nx$ny$sx$sy);

        if (
$filename) {
            
imagepng($out$filename);
        } else {
            
imagepng($out);
        }
    } else {
        if (
$filename) {
            
imagepng($im$filename);
        } else {
            
imagepng($im);
        }
    }
}



function 
ShadePixel($im$x$y$c$normal)
{
    
// applies shading to a pixel

    // black outline
    
if ($normal[2]<0.4) return array(0,0,0);

    global 
$bw$colors$tilesize$ww;
    global 
$conf_light;

    list(
$r,$g,$b)=$colors[$c];

    
$bright=$conf_light[0]*$normal[0]+$conf_light[1]*$normal[1]+$conf_light[2]*$normal[2];
    
$coslightnormal=$bright;
    if (
$bright<0) {
        
$bright=0;
    }

    
// ambient/diffuse
    
if ($c=="*") {
        
// make * really bright
        
$bright=1.0+2.0*$bright;
    } else {
        
$bright=0.1+0.7*$bright;
    }

    
$r=$bright*$r;
    
$g=$bright*$g;
    
$b=$bright*$b;

    if (
$c!="*") {
        
// specular (white light)
        
$cosa=2.0*$normal[2]*$coslightnormal-$conf_light[2];
        if (
$cosa>0) {
            
$spec=(255.0*pow($cosa10));
            
$r+=$spec;
            
$g+=$spec;
            
$b+=$spec;
        }

        
// refraction

        
$n1x=sqrt($normal[0]*$normal[0]+$normal[1]*$normal[1]);
        
$n1z=$normal[2];
    
        
$cosalfa=$n1z;
        
$alfa=acos($cosalfa);
        
$sinalfa=sin($alfa);
        
$sinbeta=$sinalfa/1.4;
        
$beta=asin($sinbeta);
        
$singama=$sinbeta*1.4;
        if (
abs($singama)<=1.0) {
            
$gama=asin($singama);
            
$totalangle=$alfa+$gama-$beta-$beta;

            
$innerx=-sin($alfa-$beta);
            
$innerz=-cos($alfa-$beta);

            
$p1x=$n1x;
            
$p1z=$n1z;

            
$d=2.0*((-$p1x*$innerx)+(-$p1z*$innerz));

            
$p2x=$p1x+$d*$innerx;
            
$p2z=$p1z+$d*$innerz;

            
$outx=-sin($totalangle);
            
$outz=-cos($totalangle);

            
$gotheretimes=(2.2+$p2z)/$outz;

            
$hitx=-(int)($gotheretimes*$normal[0]*$tilesize/0.6);
            
$hity=-(int)($gotheretimes*$normal[1]*$tilesize/0.6);

            list(
$rr$rg$rb)=BackColor($x+$hitx$y+$hity);
            list(
$r1$g1$b1)=$colors[$c];
            
$r+=$rr*(128+$r1)*0.002;
            
$g+=$rg*(128+$g1)*0.002;
            
$b+=$rb*(128+$b1)*0.002;
        }
    }

    
$r=(int)$r; if ($r>255$r=255;
    
$g=(int)$g; if ($g>255$g=255;
    
$b=(int)$b; if ($b>255$b=255;

    return array(
$r$g$b);
}

function 
MyImageSetPixel($im$x$y$color)
{
    
$col=imagecolorresolve($im$color[0], $color[1], $color[2]);
    
imagesetpixel($im$x$y$col);
}

function 
BackColor($x$y)
{
    
// returns the color of a background pixel

    
global $tilesize;
    global 
$c_odd$c_even$c_edge$bw;

    
$x=abs($x)%$tilesize;
    
$y=abs($y)%$tilesize;

    
$x-=$tilesize>>1;
    
$y-=$tilesize>>1;

    if (
$x*$x+$y*$y<$bw*$bw) {
        return array(
255,255,255);
    } else {
        return array(
224,224,224);
    }
}


function 
ExplodeMazeLine($s)
{
    
// explodes a line of a maze

    
$result="";
    
$count=0;
    while (
strlen($s)) {
        
$c=substr($s01);
        
$s=substr($s1);
        if (
$c>="0" && $c<="9") {
            
$count+=(int)$c;
        } else {
            if (
$c=="b" || $c=="."// . can also be used for space
                
$c=" ";
            if (
$count<1// shortcut notation, for easier testing
                
$count=1;
            
$result.=str_repeat($c$count);
            
$count=0;
        }
    }
    return 
$result;
}

?>


Usage Example




Rate This Script





Search



This Category All Categories