Chat LIVE With Programming Experts! There Are 23 Online Right Now...

 

Code Snippets

  

PHP Source Code


Welcome to Dream.In.Code
Become a PHP Expert!

Join 244,207 PHP Programmers for FREE! Get instant access to thousands of PHP experts, tutorials, code snippets, and more! There are 1,438 people online right now. Registration is fast and FREE... Join Now!





3D Engine

A 3D engine written in PHP which highlights you can do anything if you set your mind to it.

Submitted By: grimpirate
Actions:
Rating:
Views: 3,524

Language: PHP

Last Modified: November 15, 2006

Snippet


  1. <?php
  2.      // Creates a virtual cube composed of polygons
  3.      $cube = new VirtualObject();
  4.      // Viewable screen dimensions
  5.      $width = 640;
  6.      $height = 480;
  7.      // Sets up the camera's orientation and its focal distance
  8.      $x = sqrt(2) / 2;
  9.      $focal = 500;
  10.      $a =     array(
  11.                     array(-$x, 0.5, -0.5, 0),
  12.                     array($x, 0.5, -0.5, 0),
  13.                     array(0, -$x, -$x, 0),
  14.                     array(0, 0, 0, 1)
  15.                );
  16.      // The vector normal to the viewing plane and parallel to the viewing direction
  17.      $n2[0][0] = $a[0][2];
  18.      $n2[1][0] = $a[1][2];
  19.      $n2[2][0] = $a[2][2];
  20.      $n2[3][0] = 0;
  21.      // Invert camera's plane to allow for change of basis
  22.      $a = inverse($a);
  23.      // Displace camera to its position in the world
  24.      $a[0][3] = 150;
  25.      $a[1][3] = 150;
  26.      $a[2][3] = 300 * $x;
  27.  
  28.      // Create two images
  29.      $image1 = imagecreate($width, $height);
  30.      $image2 = imagecreate($width, $height);
  31.      // Set the line thickness of each image
  32.      imagesetthickness($image1, 1);
  33.      imagesetthickness($image2, 1);
  34.      // Set the background colors for each image
  35.      $blue1 = imagecolorallocate($image1, 0, 0, 127);
  36.      $blue2 = imagecolorallocate($image2, 0, 0, 127);
  37.      // Define some colors for each image
  38.      $white = imagecolorallocate($image1, 255, 255, 255);
  39.      $gray = imagecolorallocate($image2, 127, 127, 127);
  40.  
  41.      // Draw each polygon
  42.      for($i = 0; $i < $cube->getPolyCount(); $i++){
  43.           // Retrieve the polygons from the cube object
  44.           $points = $cube->getPolygon($i);
  45.           // Modify each point of the polygon so that its now distanced to the camera's center point
  46.           for($j = 0; $j < 3; $j++){
  47.                $points[0][$j][0] -= $a[$j][3];
  48.                $points[1][$j][0] -= $a[$j][3];
  49.                $points[2][$j][0] -= $a[$j][3];
  50.           }
  51.           // Determine the normal vector for each polygon
  52.           $n1 = crossProduct(addition($points[0], scale(-1, $points[1])), addition($points[2], scale(-1, $points[1])));
  53.           // Write each vector in terms of the camera's orientation (change of basis)
  54.           $points[0] = multiply($a, $points[0]);
  55.           $points[1] = multiply($a, $points[1]);
  56.           $points[2] = multiply($a, $points[2]);
  57.           // Determine the distortion due to perspective
  58.           $focus[0] = $focal / magnitude($points[0]);
  59.           $focus[1] = $focal / magnitude($points[1]);
  60.           $focus[2] = $focal / magnitude($points[2]);
  61.           // Transform the 3d points into 2d coordinates for drawing
  62.           $x0 = $width / 2 + ($points[0][0][0] * $focus[0]);
  63.           $x1 = $width / 2 + ($points[1][0][0] * $focus[1]);
  64.           $x2 = $width / 2 + ($points[2][0][0] * $focus[2]);
  65.           $y0 = $height / 2 + ($points[0][1][0] * $focus[0]);
  66.           $y1 = $height / 2 + ($points[1][1][0] * $focus[1]);
  67.           $y2 = $height / 2 + ($points[2][1][0] * $focus[2]);
  68.           // Determine the cosine of the angle between the viewing plane and the polygonal plane
  69.           $cosTheta = dotProduct($n1, $n2) / (magnitude($n1) * magnitude($n2));
  70.           if($cosTheta <= 0){
  71.                // White lines because these are the planes at the front of the object
  72.                imageline($image1, $x0, $y0, $x1, $y1, $white);
  73.                imageline($image1, $x1, $y1, $x2, $y2, $white);
  74. //               imageline($image1, $x2, $y2, $x0, $y0, $white);     // Draws the final polygon line
  75.           }else{
  76.                // Gray lines because these are the planes at the reare of the object
  77.                imageline($image2, $x0, $y0, $x1, $y1, $gray);
  78.                imageline($image2, $x1, $y1, $x2, $y2, $gray);
  79. //               imageline($image2, $x2, $y2, $x0, $y0, $gray);     // Draws the final polygon line
  80.           }
  81.      }
  82.  
  83.      // Make transparent the background of the viewable polygon drawing
  84.      imagecolortransparent($image1, $blue1);
  85.      // Layer it over the non-viewable polygon drawing
  86.      imagecopymerge($image2, $image1, 0, 0, 0, 0, 640, 480, 100);
  87.      // Output the finished image
  88.      imagepng($image2);
  89.      // Destroy the images
  90.      imagedestroy($image1);
  91.      imagedestroy($image2);
  92.  
  93.      // Computes the cross product of two vectors
  94.      // $a: a row or column vector
  95.      // $b: a row or column vector
  96.      function crossProduct($a, $b){
  97.           if(sizeof($a) == 1){     // Cross product of row vectors
  98.                return     array(     // Return the cross product of row vectors as a row vector
  99.                               array(     $a[0][1] * $b[0][2] - $a[0][2] * $b[0][1],
  100.                                         -1 * ($a[0][0] * $b[0][2] - $a[0][2] * $b[0][0]),
  101.                                         $a[0][0] * $b[0][1] - $a[0][1] * $b[0][0],
  102.                                         0
  103.                               )
  104.                          );
  105.           }else{     // Cross product of column vectors
  106.                return     array(     // Return the cross product of column vectors as a column vector
  107.                               array($a[1][0] * $b[2][0] - $a[2][0] * $b[1][0]),
  108.                               array(-1 * ($a[0][0] * $b[2][0] - $a[2][0] * $b[0][0])),
  109.                               array($a[0][0] * $b[1][0] - $a[1][0] * $b[0][0]),
  110.                               array(0)
  111.                          );
  112.           }
  113.      }
  114.  
  115.      // Computes the addition of two matrices
  116.      // $A: an m x n matrix
  117.      // $B: an m x n matrix
  118.      function addition($A, $B){
  119.           $M;     // The added matrix
  120.  
  121.           // Add the two matrices together
  122.           for($i = 0; $i < sizeof($A); $i++){
  123.                for($j = 0; $j < sizeof($A[0]); $j++){
  124.                     $M[$i][$j] = $A[$i][$j] + $B[$i][$j];
  125.                }
  126.           }
  127.  
  128.           return $M;     // Return the added matrix
  129.      }
  130.  
  131.      // Computes a random matrix
  132.      // $m: the row dimension
  133.      // $n: the column dimension
  134.      // $lower: the lower bound of random numbers
  135.      // $upper: the upper bound of random numbers
  136.      function randMatrix($m, $n, $lower, $upper){
  137.           $M;     // A random matrix
  138.  
  139.           // Generate the random matrix
  140.           for($i = 0; $i < $m; $i++){
  141.                for($j = 0; $j < $n; $j++){
  142.                     $M[$i][$j] = rand($lower, $upper);
  143.                }
  144.           }
  145.  
  146.           return $M;     // Return the random matrix
  147.      }
  148.  
  149.      // Computes the magnitude of a vector
  150.      // $a: a row or column vector
  151.      function magnitude($a){
  152.           $result = 0;     // The magnitude of the vector
  153.  
  154.           // Use the Pythagorean theorem to determine the vector's magnitude
  155.           for($i = 0; $i < sizeof($a); $i++){
  156.                for($j = 0; $j < sizeof($a[0]); $j++){
  157.                     $result += pow($a[$i][$j], 2);
  158.                }
  159.           }
  160.  
  161.           return sqrt($result);     // Return the magnitude of the vector
  162.      }
  163.  
  164.      // Computes the adjoint of a matrix
  165.      // $A: a square matrix
  166.      function adjoint($A){
  167.           return scale(determinant($A), inverse($A));     // Returns the adjoint of a matrix
  168.      }
  169.  
  170.      // Computes a scaled matrix
  171.      // $k: a scalar number
  172.      // $A: an m x n matrix
  173.      function scale($k, $A){
  174.  
  175.           // Scale the matrix by multiplying each entry by k
  176.           for($i = 0; $i < sizeof($A); $i++){
  177.                for($j = 0; $j < sizeof($A[0]); $j++){
  178.                     $A[$i][$j] *= $k;
  179.                }
  180.           }
  181.  
  182.           return $A;     // Returns the scaled matrix
  183.      }
  184.  
  185.      // Computes the determinant of a matrix
  186.      // $A: a square matrix
  187.      function determinant($A){
  188.           $determinant = 1;     // The determinant of the matrix
  189.           $n = sizeof($A);     // Dimension of the square matrix
  190.           $E = identity($n);     // An elementary matrix
  191.  
  192.           // Find the determinant of a matrix by performing elementary matrix operations
  193.           // on an augmented matrix through the use of elementary matrices in order
  194.           // to convert the matrix into upper triangular form
  195.           // Multiply the diagonals of the upper triangular matrix to arrive at the
  196.           // determinant, only elementary operations I and III are allowed on the matrix.
  197.           // If operation I is performed at any time, multiply the determinant by a -1.
  198.           for($j = 0; $j < $n; $j++){
  199.                for($i = $j; $i < $n; $i++){
  200.                     if($i == $j){
  201.                          if($A[$i][$j] == 0){
  202.                               for($k = $j + 1; $k < $n; $k++){
  203.                                    if($A[$k][$j] != 0){
  204.                                         $swap = $A[$i];
  205.                                         $A[$i] = $A[$k];
  206.                                         $A[$k] = $swap;
  207.                                         $determinant *= -1;
  208.                                         $k = $n;
  209.                                    }
  210.                               }
  211.                          }
  212.                          $determinant *= $A[$i][$j];
  213.                     }else{
  214.                          $E[$i][$j] = -$A[$i][$j] / $A[$j][$j];
  215.                     }
  216.                     $A = multiply($E, $A);
  217.                     $E = identity($n);
  218.                }
  219.           }
  220.  
  221.           return $determinant;     // Return the determinant of the matrix
  222.      }
  223.  
  224.      // Computes the inverse of a matrix
  225.      // $A: a square matrix
  226.      function inverse($A){
  227.           $n = sizeof($A);     // Dimension of the square matrix
  228.           $V = identity($n);     // The inverse of the matrix
  229.           $E = identity($n);     // An elementary matrix
  230.  
  231.           // Find the inverse matrix by performing elementary matrix operations
  232.           // on an augmented matrix through the use of elementary matrices
  233.           for($j = 0; $j < $n; $j++){
  234.                for($i = $j; $i < $n; $i++){
  235.                     if($i == $j){
  236.                          if($A[$i][$j] == 0){
  237.                               for($k = $j + 1; $k < $n; $k++){
  238.                                    if($A[$k][$j] != 0){
  239.                                         $swap = $A[$i];
  240.                                         $A[$i] = $A[$k];
  241.                                         $A[$k] = $swap;
  242.                                         $swap = $V[$i];
  243.                                         $V[$i] = $V[$k];
  244.                                         $V[$k] = $swap;
  245.                                         $k = $n;
  246.                                    }
  247.                               }
  248.                          }
  249.                          $E[$i][$j] = 1 / $A[$i][$j];
  250.                     }else{
  251.                          $E[$i][$j] = -$A[$i][$j];
  252.                     }
  253.                     $A = multiply($E, $A);
  254.                     $V = multiply($E, $V);
  255.                     $E = identity($n);
  256.                }
  257.           }
  258.           for($j = $n - 1; $j > 0; $j--){
  259.                for($i = $j - 1; $i > -1; $i--){
  260.                     $E[$i][$j] = -$A[$i][$j];
  261.                     $A = multiply($E, $A);
  262.                     $V = multiply($E, $V);
  263.                     $E = identity($n);
  264.                }
  265.           }
  266.  
  267.           return $V;     // Return the inverse matrix
  268.      }
  269.  
  270.      // Computes the product of a matrix multiplication
  271.      // $A: An m x n matrix
  272.      // $B: An n x o matrix
  273.      function multiply($A, $B){
  274.           $M;     // The product of the multiplication
  275.           $B = transpose($B);     // Transpose the second matrix
  276.  
  277.           // Do the multiplication by making use of the dot product
  278.           for($i = 0; $i < sizeof($A); $i++){
  279.                for($j = 0; $j < sizeof($B); $j++){
  280.                     $M[$i][$j] = dotProduct(array($A[$i]), array($B[$j]));
  281.                }
  282.           }
  283.  
  284.           return $M;     // Return the product
  285.      }
  286.  
  287.      // Computes the dot product of two vectors
  288.      // $a: a row or column vector
  289.      // $b; a row or column vector
  290.      function dotProduct($a, $b){
  291.           $result = 0;     // The result of the dot product
  292.  
  293.           // The dot product
  294.           for($i = 0; $i < sizeof($a); $i++){
  295.                for($j = 0; $j < sizeof($a[0]); $j++){
  296.                     $result += $a[$i][$j] * $b[$i][$j];
  297.                }
  298.           }
  299.  
  300.           return $result;     // Return the dot product
  301.      }
  302.  
  303.      // Computes the transpose of a matrix
  304.      // $A: the matrix to be transposed
  305.      function transpose($A){
  306.           $T;          // Transpose matrix
  307.  
  308.           // Switch the i,jth entry to the j,ith entry
  309.           for($i = 0; $i < sizeof($A); $i++){
  310.                for($j = 0; $j < sizeof($A[0]); $j++){
  311.                     $T[$j][$i] = $A[$i][$j];
  312.                }
  313.           }
  314.  
  315.           return $T;     // Return the transpose matrix
  316.      }
  317.  
  318.      // Computes an identity matrix of size n x n
  319.      // $n: size of the matrix wanted
  320.      function identity($n){
  321.           $I;          // Identity matrix
  322.  
  323.           // Fill the matrices diagonal with 1's and everything else with 0's
  324.           for($i = 0; $i < $n; $i++){
  325.                for($j = 0; $j < $n; $j++){
  326.                     if($i == $j){
  327.                          $I[$i][$j] = 1;
  328.                     }else{
  329.                          $I[$i][$j] = 0;
  330.                     }
  331.                }
  332.           }
  333.  
  334.           return $I;     // Return the identity matrix
  335.      }
  336.  
  337.      class VirtualObject{
  338.           // Member declarations
  339.           private $polyObject;
  340.  
  341.           // Constructor
  342.           function __construct(){
  343.                $this->polyObject =
  344.                array(     // object
  345.                     array(     // polygon
  346.                          array(     // vector
  347.                               array(50),
  348.                               array(-50),
  349.                               array(50),
  350.                               array(0)
  351.                          ),
  352.                          array(     // vector
  353.                               array(-50),
  354.                               array(-50),
  355.                               array(50),
  356.                               array(0)
  357.                          ),
  358.                          array(     // vector
  359.                               array(-50),
  360.                               array(50),
  361.                               array(50),
  362.                               array(0)
  363.                          )
  364.                     ),
  365.                     array(     // polygon
  366.                          array(     // vector
  367.                               array(-50),
  368.                               array(50),
  369.                               array(50),
  370.                               array(0)
  371.                          ),
  372.                          array(     // vector
  373.                               array(50),
  374.                               array(50),
  375.                               array(50),
  376.                               array(0)
  377.                          ),
  378.                          array(     // vector
  379.                               array(50),
  380.                               array(-50),
  381.                               array(50),
  382.                               array(0)
  383.                          )
  384.                     ),
  385.                     array(     // polygon
  386.                          array(     // vector
  387.                               array(50),
  388.                               array(-50),
  389.                               array(-50),
  390.                               array(0)
  391.                          ),
  392.                          array(     // vector
  393.                               array(50),
  394.                               array(-50),
  395.                               array(50),
  396.                               array(0)
  397.                          ),
  398.                          array(     // vector
  399.                               array(50),
  400.                               array(50),
  401.                               array(50),
  402.                               array(0)
  403.                          )
  404.                     ),
  405.                     array(     // polygon
  406.                          array(     // vector
  407.                               array(50),
  408.                               array(50),
  409.                               array(50),
  410.                               array(0)
  411.                          ),
  412.                          array(     // vector
  413.                               array(50),
  414.                               array(50),
  415.                               array(-50),
  416.                               array(0)
  417.                          ),
  418.                          array(     // vector
  419.                               array(50),
  420.                               array(-50),
  421.                               array(-50),
  422.                               array(0)
  423.                          )
  424.                     ),
  425.                     array(     // polygon
  426.                          array(     // vector
  427.                               array(50),
  428.                               array(50),
  429.                               array(-50),
  430.                               array(0)
  431.                          ),
  432.                          array(     // vector
  433.                               array(50),
  434.                               array(50),
  435.                               array(50),
  436.                               array(0)
  437.                          ),
  438.                          array(     // vector
  439.                               array(-50),
  440.                               array(50),
  441.                               array(50),
  442.                               array(0)
  443.                          )
  444.                     ),
  445.                     array(     // polygon
  446.                          array(     // vector
  447.                               array(-50),
  448.                               array(50),
  449.                               array(50),
  450.                               array(0)
  451.                          ),
  452.                          array(     // vector
  453.                               array(-50),
  454.                               array(50),
  455.                               array(-50),
  456.                               array(0)
  457.                          ),
  458.                          array(     // vector
  459.                               array(50),
  460.                               array(50),
  461.                               array(-50),
  462.                               array(0)
  463.                          )
  464.                     ),
  465.                     array(     // polygon
  466.                          array(     // vector
  467.                               array(-50),
  468.                               array(-50),
  469.                               array(-50),
  470.                               array(0)
  471.                          ),
  472.                          array(     // vector
  473.                               array(50),
  474.                               array(-50),
  475.                               array(-50),
  476.                               array(0)
  477.                          ),
  478.                          array(     // vector
  479.                               array(50),
  480.                               array(50),
  481.                               array(-50),
  482.                               array(0)
  483.                          )
  484.                     ),
  485.                     array(     // polygon
  486.                          array(     // vector
  487.                               array(50),
  488.                               array(50),
  489.                               array(-50),
  490.                               array(0)
  491.                          ),
  492.                          array(     // vector
  493.                               array(-50),
  494.                               array(50),
  495.                               array(-50),
  496.                               array(0)
  497.                          ),
  498.                          array(     // vector
  499.                               array(-50),
  500.                               array(-50),
  501.                               array(-50),
  502.                               array(0)
  503.                          )
  504.                     ),
  505.                     array(     // polygon
  506.                          array(     // vector
  507.                               array(-50),
  508.                               array(50),
  509.                               array(-50),
  510.                               array(0)
  511.                          ),
  512.                          array(     // vector
  513.                               array(-50),
  514.                               array(50),
  515.                               array(50),
  516.                               array(0)
  517.                          ),
  518.                          array(     // vector
  519.                               array(-50),
  520.                               array(-50),
  521.                               array(50),
  522.                               array(0)
  523.                          )
  524.                     ),
  525.                     array(     // polygon
  526.                          array(     // vector
  527.                               array(-50),
  528.                               array(-50),
  529.                               array(50),
  530.                               array(0)
  531.                          ),
  532.                          array(     // vector
  533.                               array(-50),
  534.                               array(-50),
  535.                               array(-50),
  536.                               array(0)
  537.                          ),
  538.                          array(     // vector
  539.                               array(-50),
  540.                               array(50),
  541.                               array(-50),
  542.                               array(0)
  543.                          )
  544.                     ),
  545.                     array(     // polygon
  546.                          array(     // vector
  547.                               array(-50),
  548.                               array(-50),
  549.                               array(-50),
  550.                               array(0)
  551.                          ),
  552.                          array(     // vector
  553.                               array(-50),
  554.                               array(-50),
  555.                               array(50),
  556.                               array(0)
  557.                          ),
  558.                          array(     // vector
  559.                               array(50),
  560.                               array(-50),
  561.                               array(50),
  562.                               array(0)
  563.                          )
  564.                     ),
  565.                     array(     // polygon
  566.                          array(     // vector
  567.                               array(50),
  568.                               array(-50),
  569.                               array(50),
  570.                               array(0)
  571.                          ),
  572.                          array(     // vector
  573.                               array(50),
  574.                               array(-50),
  575.                               array(-50),
  576.                               array(0)
  577.                          ),
  578.                          array(     // vector
  579.                               array(-50),
  580.                               array(-50),
  581.                               array(-50),
  582.                               array(0)
  583.                          )
  584.                     )
  585.                );
  586.           }
  587.  
  588.           // Method declarations
  589.  
  590.           // Returns the polygon count of the object
  591.           public function getPolyCount(){
  592.                return sizeof($this->polyObject);
  593.           }
  594.  
  595.           // Returns a particular polygon of the object
  596.           public function getPolygon($n){
  597.                return $this->polyObject[$n];
  598.           }
  599.      }
  600. ?>

Copy & Paste


Comments


Aurel300 2007-11-14 10:22:50

Hm... Little bit hard to use, but good.

Rohtie 2009-02-04 13:04:24

This is really cool :3 I combined this with javascript and the cube can now be controlled and moved around ^^

grimpirate 2009-02-04 18:43:16

Sweet, I'd love to see that code in action. Mind sharing, or uploading so we can check it out live?

DingleNutZ 2009-05-05 17:13:05

bloody hell, must have taken ages

Xtron 2009-05-21 00:54:41

Oh my php! Diddn't know you can do that. Nice work.


Add comment


You must be registered and logged on to </dream.in.code> to leave comments.





Live PHP Help!

Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter Fan Us On Facebook

PHP Tutorials

Reference Sheets

PHP Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month