7 Replies - 1936 Views - Last Post: 26 January 2011 - 08:33 PM

#1 grimpirate   User is offline

  • Pirate King
  • member icon

Reputation: 149
  • View blog
  • Posts: 717
  • Joined: 03-August 06

3D Engine

Posted 15 November 2006 - 08:29 PM

Description: A 3D engine written in PHP which highlights you can do anything if you set your mind to it.
<?php
     // Creates a virtual cube composed of polygons
     $cube = new VirtualObject();
     // Viewable screen dimensions
     $width = 640;
     $height = 480;
     // Sets up the camera's orientation and its focal distance
     $x = sqrt(2) / 2;
     $focal = 500;
     $a =     array(
                    array(-$x, 0.5, -0.5, 0),
                    array($x, 0.5, -0.5, 0),
                    array(0, -$x, -$x, 0),
                    array(0, 0, 0, 1)
               );
     // The vector normal to the viewing plane and parallel to the viewing direction
     $n2[0][0] = $a[0][2];
     $n2[1][0] = $a[1][2];
     $n2[2][0] = $a[2][2];
     $n2[3][0] = 0;
     // Invert camera's plane to allow for change of basis
     $a = inverse($a);
     // Displace camera to its position in the world
     $a[0][3] = 150;
     $a[1][3] = 150;
     $a[2][3] = 300 * $x;

     // Create two images
     $image1 = imagecreate($width, $height);
     $image2 = imagecreate($width, $height);
     // Set the line thickness of each image
     imagesetthickness($image1, 1);
     imagesetthickness($image2, 1);
     // Set the background colors for each image
     $blue1 = imagecolorallocate($image1, 0, 0, 127);
     $blue2 = imagecolorallocate($image2, 0, 0, 127);
     // Define some colors for each image
     $white = imagecolorallocate($image1, 255, 255, 255);
     $gray = imagecolorallocate($image2, 127, 127, 127);

     // Draw each polygon
     for($i = 0; $i < $cube->getPolyCount(); $i++){
          // Retrieve the polygons from the cube object
          $points = $cube->getPolygon($i);
          // Modify each point of the polygon so that its now distanced to the camera's center point
          for($j = 0; $j < 3; $j++){
               $points[0][$j][0] -= $a[$j][3];
               $points[1][$j][0] -= $a[$j][3];
               $points[2][$j][0] -= $a[$j][3];
          }
          // Determine the normal vector for each polygon
          $n1 = crossProduct(addition($points[0], scale(-1, $points[1])), addition($points[2], scale(-1, $points[1])));
          // Write each vector in terms of the camera's orientation (change of basis)
          $points[0] = multiply($a, $points[0]);
          $points[1] = multiply($a, $points[1]);
          $points[2] = multiply($a, $points[2]);
          // Determine the distortion due to perspective
          $focus[0] = $focal / magnitude($points[0]);
          $focus[1] = $focal / magnitude($points[1]);
          $focus[2] = $focal / magnitude($points[2]);
          // Transform the 3d points into 2d coordinates for drawing
          $x0 = $width / 2 + ($points[0][0][0] * $focus[0]);
          $x1 = $width / 2 + ($points[1][0][0] * $focus[1]);
          $x2 = $width / 2 + ($points[2][0][0] * $focus[2]);
          $y0 = $height / 2 + ($points[0][1][0] * $focus[0]);
          $y1 = $height / 2 + ($points[1][1][0] * $focus[1]);
          $y2 = $height / 2 + ($points[2][1][0] * $focus[2]);
          // Determine the cosine of the angle between the viewing plane and the polygonal plane
          $cosTheta = dotProduct($n1, $n2) / (magnitude($n1) * magnitude($n2));
          if($cosTheta <= 0){
               // White lines because these are the planes at the front of the object
               imageline($image1, $x0, $y0, $x1, $y1, $white);
               imageline($image1, $x1, $y1, $x2, $y2, $white);
//               imageline($image1, $x2, $y2, $x0, $y0, $white);     // Draws the final polygon line
          }else{
               // Gray lines because these are the planes at the reare of the object
               imageline($image2, $x0, $y0, $x1, $y1, $gray);
               imageline($image2, $x1, $y1, $x2, $y2, $gray);
//               imageline($image2, $x2, $y2, $x0, $y0, $gray);     // Draws the final polygon line
          }
     }

     // Make transparent the background of the viewable polygon drawing
     imagecolortransparent($image1, $blue1);
     // Layer it over the non-viewable polygon drawing
     imagecopymerge($image2, $image1, 0, 0, 0, 0, 640, 480, 100);
     // Output the finished image
     imagepng($image2);
     // Destroy the images
     imagedestroy($image1);
     imagedestroy($image2);

     // Computes the cross product of two vectors
     // $a: a row or column vector
     // $b: a row or column vector
     function crossProduct($a, $b){
          if(sizeof($a) == 1){     // Cross product of row vectors
               return     array(     // Return the cross product of row vectors as a row vector
                              array(     $a[0][1] * $b[0][2] - $a[0][2] * $b[0][1],
                                        -1 * ($a[0][0] * $b[0][2] - $a[0][2] * $b[0][0]),
                                        $a[0][0] * $b[0][1] - $a[0][1] * $b[0][0],
                                        0
                              )
                         );
          }else{     // Cross product of column vectors
               return     array(     // Return the cross product of column vectors as a column vector
                              array($a[1][0] * $b[2][0] - $a[2][0] * $b[1][0]),
                              array(-1 * ($a[0][0] * $b[2][0] - $a[2][0] * $b[0][0])),
                              array($a[0][0] * $b[1][0] - $a[1][0] * $b[0][0]),
                              array(0)
                         );
          }
     }

     // Computes the addition of two matrices
     // $A: an m x n matrix
     // $B: an m x n matrix
     function addition($A, $B){
          $M;     // The added matrix

          // Add the two matrices together
          for($i = 0; $i < sizeof($A); $i++){
               for($j = 0; $j < sizeof($A[0]); $j++){
                    $M[$i][$j] = $A[$i][$j] + $B[$i][$j];
               }
          }

          return $M;     // Return the added matrix
     }

     // Computes a random matrix
     // $m: the row dimension
     // $n: the column dimension
     // $lower: the lower bound of random numbers
     // $upper: the upper bound of random numbers
     function randMatrix($m, $n, $lower, $upper){
          $M;     // A random matrix

          // Generate the random matrix
          for($i = 0; $i < $m; $i++){
               for($j = 0; $j < $n; $j++){
                    $M[$i][$j] = rand($lower, $upper);
               }
          }

          return $M;     // Return the random matrix
     }

     // Computes the magnitude of a vector
     // $a: a row or column vector
     function magnitude($a){
          $result = 0;     // The magnitude of the vector

          // Use the Pythagorean theorem to determine the vector's magnitude
          for($i = 0; $i < sizeof($a); $i++){
               for($j = 0; $j < sizeof($a[0]); $j++){
                    $result += pow($a[$i][$j], 2);
               }
          }

          return sqrt($result);     // Return the magnitude of the vector
     }

     // Computes the adjoint of a matrix
     // $A: a square matrix
     function adjoint($A){
          return scale(determinant($A), inverse($A));     // Returns the adjoint of a matrix
     }

     // Computes a scaled matrix
     // $k: a scalar number
     // $A: an m x n matrix
     function scale($k, $A){

          // Scale the matrix by multiplying each entry by k
          for($i = 0; $i < sizeof($A); $i++){
               for($j = 0; $j < sizeof($A[0]); $j++){
                    $A[$i][$j] *= $k;
               }
          }

          return $A;     // Returns the scaled matrix
     }

     // Computes the determinant of a matrix
     // $A: a square matrix
     function determinant($A){
          $determinant = 1;     // The determinant of the matrix
          $n = sizeof($A);     // Dimension of the square matrix
          $E = identity($n);     // An elementary matrix

          // Find the determinant of a matrix by performing elementary matrix operations
          // on an augmented matrix through the use of elementary matrices in order
          // to convert the matrix into upper triangular form
          // Multiply the diagonals of the upper triangular matrix to arrive at the
          // determinant, only elementary operations I and III are allowed on the matrix.
          // If operation I is performed at any time, multiply the determinant by a -1.
          for($j = 0; $j < $n; $j++){
               for($i = $j; $i < $n; $i++){
                    if($i == $j){
                         if($A[$i][$j] == 0){
                              for($k = $j + 1; $k < $n; $k++){
                                   if($A[$k][$j] != 0){
                                        $swap = $A[$i];
                                        $A[$i] = $A[$k];
                                        $A[$k] = $swap;
                                        $determinant *= -1;
                                        $k = $n;
                                   }
                              }
                         }
                         $determinant *= $A[$i][$j];
                    }else{
                         $E[$i][$j] = -$A[$i][$j] / $A[$j][$j];
                    }
                    $A = multiply($E, $A);
                    $E = identity($n);
               }
          }

          return $determinant;     // Return the determinant of the matrix
     }

     // Computes the inverse of a matrix
     // $A: a square matrix
     function inverse($A){
          $n = sizeof($A);     // Dimension of the square matrix
          $V = identity($n);     // The inverse of the matrix
          $E = identity($n);     // An elementary matrix

          // Find the inverse matrix by performing elementary matrix operations
          // on an augmented matrix through the use of elementary matrices
          for($j = 0; $j < $n; $j++){
               for($i = $j; $i < $n; $i++){
                    if($i == $j){
                         if($A[$i][$j] == 0){
                              for($k = $j + 1; $k < $n; $k++){
                                   if($A[$k][$j] != 0){
                                        $swap = $A[$i];
                                        $A[$i] = $A[$k];
                                        $A[$k] = $swap;
                                        $swap = $V[$i];
                                        $V[$i] = $V[$k];
                                        $V[$k] = $swap;
                                        $k = $n;
                                   }
                              }
                         }
                         $E[$i][$j] = 1 / $A[$i][$j];
                    }else{
                         $E[$i][$j] = -$A[$i][$j];
                    }
                    $A = multiply($E, $A);
                    $V = multiply($E, $V);
                    $E = identity($n);
               }
          }
          for($j = $n - 1; $j > 0; $j--){
               for($i = $j - 1; $i > -1; $i--){
                    $E[$i][$j] = -$A[$i][$j];
                    $A = multiply($E, $A);
                    $V = multiply($E, $V);
                    $E = identity($n);
               }
          }

          return $V;     // Return the inverse matrix
     }

     // Computes the product of a matrix multiplication
     // $A: An m x n matrix
     // $B: An n x o matrix
     function multiply($A, $B){
          $M;     // The product of the multiplication
          $B = transpose($B);     // Transpose the second matrix

          // Do the multiplication by making use of the dot product
          for($i = 0; $i < sizeof($A); $i++){
               for($j = 0; $j < sizeof($B); $j++){
                    $M[$i][$j] = dotProduct(array($A[$i]), array($B[$j]));
               }
          }

          return $M;     // Return the product
     }

     // Computes the dot product of two vectors
     // $a: a row or column vector
     // $b; a row or column vector
     function dotProduct($a, $b){
          $result = 0;     // The result of the dot product

          // The dot product
          for($i = 0; $i < sizeof($a); $i++){
               for($j = 0; $j < sizeof($a[0]); $j++){
                    $result += $a[$i][$j] * $b[$i][$j];
               }
          }

          return $result;     // Return the dot product
     }

     // Computes the transpose of a matrix
     // $A: the matrix to be transposed
     function transpose($A){
          $T;          // Transpose matrix

          // Switch the i,jth entry to the j,ith entry
          for($i = 0; $i < sizeof($A); $i++){
               for($j = 0; $j < sizeof($A[0]); $j++){
                    $T[$j][$i] = $A[$i][$j];
               }
          }

          return $T;     // Return the transpose matrix
     }

     // Computes an identity matrix of size n x n
     // $n: size of the matrix wanted
     function identity($n){
          $I;          // Identity matrix

          // Fill the matrices diagonal with 1's and everything else with 0's
          for($i = 0; $i < $n; $i++){
               for($j = 0; $j < $n; $j++){
                    if($i == $j){
                         $I[$i][$j] = 1;
                    }else{
                         $I[$i][$j] = 0;
                    }
               }
          }

          return $I;     // Return the identity matrix
     }

     class VirtualObject{
          // Member declarations
          private $polyObject;

          // Constructor
          function __construct(){
               $this->polyObject =
               array(     // object
                    array(     // polygon
                         array(     // vector
                              array(50),
                              array(-50),
                              array(50),
                              array(0)
                         ),
                         array(     // vector
                              array(-50),
                              array(-50),
                              array(50),
                              array(0)
                         ),
                         array(     // vector
                              array(-50),
                              array(50),
                              array(50),
                              array(0)
                         )
                    ),
                    array(     // polygon
                         array(     // vector
                              array(-50),
                              array(50),
                              array(50),
                              array(0)
                         ),
                         array(     // vector
                              array(50),
                              array(50),
                              array(50),
                              array(0)
                         ),
                         array(     // vector
                              array(50),
                              array(-50),
                              array(50),
                              array(0)
                         )
                    ),
                    array(     // polygon
                         array(     // vector
                              array(50),
                              array(-50),
                              array(-50),
                              array(0)
                         ),
                         array(     // vector
                              array(50),
                              array(-50),
                              array(50),
                              array(0)
                         ),
                         array(     // vector
                              array(50),
                              array(50),
                              array(50),
                              array(0)
                         )
                    ),
                    array(     // polygon
                         array(     // vector
                              array(50),
                              array(50),
                              array(50),
                              array(0)
                         ),
                         array(     // vector
                              array(50),
                              array(50),
                              array(-50),
                              array(0)
                         ),
                         array(     // vector
                              array(50),
                              array(-50),
                              array(-50),
                              array(0)
                         )
                    ),
                    array(     // polygon
                         array(     // vector
                              array(50),
                              array(50),
                              array(-50),
                              array(0)
                         ),
                         array(     // vector
                              array(50),
                              array(50),
                              array(50),
                              array(0)
                         ),
                         array(     // vector
                              array(-50),
                              array(50),
                              array(50),
                              array(0)
                         )
                    ),
                    array(     // polygon
                         array(     // vector
                              array(-50),
                              array(50),
                              array(50),
                              array(0)
                         ),
                         array(     // vector
                              array(-50),
                              array(50),
                              array(-50),
                              array(0)
                         ),
                         array(     // vector
                              array(50),
                              array(50),
                              array(-50),
                              array(0)
                         )
                    ),
                    array(     // polygon
                         array(     // vector
                              array(-50),
                              array(-50),
                              array(-50),
                              array(0)
                         ),
                         array(     // vector
                              array(50),
                              array(-50),
                              array(-50),
                              array(0)
                         ),
                         array(     // vector
                              array(50),
                              array(50),
                              array(-50),
                              array(0)
                         )
                    ),
                    array(     // polygon
                         array(     // vector
                              array(50),
                              array(50),
                              array(-50),
                              array(0)
                         ),
                         array(     // vector
                              array(-50),
                              array(50),
                              array(-50),
                              array(0)
                         ),
                         array(     // vector
                              array(-50),
                              array(-50),
                              array(-50),
                              array(0)
                         )
                    ),
                    array(     // polygon
                         array(     // vector
                              array(-50),
                              array(50),
                              array(-50),
                              array(0)
                         ),
                         array(     // vector
                              array(-50),
                              array(50),
                              array(50),
                              array(0)
                         ),
                         array(     // vector
                              array(-50),
                              array(-50),
                              array(50),
                              array(0)
                         )
                    ),
                    array(     // polygon
                         array(     // vector
                              array(-50),
                              array(-50),
                              array(50),
                              array(0)
                         ),
                         array(     // vector
                              array(-50),
                              array(-50),
                              array(-50),
                              array(0)
                         ),
                         array(     // vector
                              array(-50),
                              array(50),
                              array(-50),
                              array(0)
                         )
                    ),
                    array(     // polygon
                         array(     // vector
                              array(-50),
                              array(-50),
                              array(-50),
                              array(0)
                         ),
                         array(     // vector
                              array(-50),
                              array(-50),
                              array(50),
                              array(0)
                         ),
                         array(     // vector
                              array(50),
                              array(-50),
                              array(50),
                              array(0)
                         )
                    ),
                    array(     // polygon
                         array(     // vector
                              array(50),
                              array(-50),
                              array(50),
                              array(0)
                         ),
                         array(     // vector
                              array(50),
                              array(-50),
                              array(-50),
                              array(0)
                         ),
                         array(     // vector
                              array(-50),
                              array(-50),
                              array(-50),
                              array(0)
                         )
                    )
               );
          }

          // Method declarations

          // Returns the polygon count of the object
          public function getPolyCount(){
               return sizeof($this->polyObject);
          }

          // Returns a particular polygon of the object
          public function getPolygon($n){
               return $this->polyObject[$n];
          }
     }
?>


Is This A Good Question/Topic? 0
  • +

Replies To: 3D Engine

#2 Aurel300   User is offline

  • D.I.C Head

Reputation: 13
  • View blog
  • Posts: 230
  • Joined: 10-November 07

Re: 3D Engine

Posted 14 November 2007 - 08:22 AM

Hm... Little bit hard to use, but good.
Was This Post Helpful? 0
  • +
  • -

#3 Rohtie   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 44
  • Joined: 07-March 07

Re: 3D Engine

Posted 04 February 2009 - 11:04 AM

This is really cool :3 I combined this with javascript and the cube can now be controlled and moved around ^^
Was This Post Helpful? 0
  • +
  • -

#4 grimpirate   User is offline

  • Pirate King
  • member icon

Reputation: 149
  • View blog
  • Posts: 717
  • Joined: 03-August 06

Re: 3D Engine

Posted 04 February 2009 - 04:43 PM

Sweet, I'd love to see that code in action. Mind sharing, or uploading so we can check it out live?
Was This Post Helpful? 0
  • +
  • -

#5 DingleNutZ   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 121
  • Joined: 02-May 09

Re: 3D Engine

Posted 05 May 2009 - 02:13 PM

bloody hell, must have taken ages
Was This Post Helpful? 0
  • +
  • -

#6 Xtron   User is offline

  • New D.I.C Head

Reputation: 9
  • View blog
  • Posts: 28
  • Joined: 20-May 09

Re: 3D Engine

Posted 20 May 2009 - 09:54 PM

Oh my php! Diddn't know you can do that. Nice work.
Was This Post Helpful? 0
  • +
  • -

#7 SinisterIndieGaming   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 02-September 09

Re: 3D Engine

Posted 03 September 2009 - 05:18 AM

This answered my question that I had for a very long time!
Was This Post Helpful? 0
  • +
  • -

#8 borninlyoko   User is offline

  • D.I.C Regular
  • member icon

Reputation: 7
  • View blog
  • Posts: 350
  • Joined: 03-December 09

Re: 3D Engine

Posted 26 January 2011 - 08:33 PM

*Twitches in awe*
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1