tkormann    02/03/05 08:36:48

  Added:       samples  3D.svg
  Log:
  first quick version of an Atari like 3D demo :)
  
  I will change the colors soon and will do shading when
  style modifications will be supported.
  
  More objects to come and object morphing if I have time...
  
  Revision  Changes    Path
  1.1                  xml-batik/samples/3D.svg
  
  Index: 3D.svg
  ===================================================================
  <?xml version="1.0" standalone="no"?>
  <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd";>
  
  <!-- ====================================================================== -->
  <!-- Copyright (C) The Apache Software Foundation. All rights reserved.     -->
  <!--                                                                        -->
  <!-- This software is published under the terms of the Apache Software      -->
  <!-- License version 1.1, a copy of which has been included with this       -->
  <!-- distribution in the LICENSE file.                                      -->
  <!-- ====================================================================== -->
  
  <!-- ====================================================================== -->
  <!-- 3D demo                                                                -->
  <!--                                                                        -->
  <!-- @author [EMAIL PROTECTED]                                               -->
  <!-- @version $Id: 3D.svg,v 1.1 2002/03/05 16:36:48 tkormann Exp $ -->
  <!-- ====================================================================== -->
  
  <svg xmlns="http://www.w3.org/2000/svg"; 
       xmlns:xlink="http://www.w3.org/1999/xlink";
       id="body" width="450" height="500" viewBox="0 0 450 500">
  
      <script type="text/ecmascript"><![CDATA[
  
          // constants
          var MAX_FOCAL_DISTANCE = 1100;
          var MIN_FOCAL_DISTANCE = 400;
          var _xOrigin = 225;
          var _yOrigin = 250;
          var svgNS = "http://www.w3.org/2000/svg";;
  
          // object definition
          var _points3d;
          var _faces;
  
          // svg shapes that represent the object
          var _shapes;
  
          // transformation matrix
          var _matrix = new Array(1, 0, 0, 0,
                                  0, 1, 0, 0,
                                  0, 0, 1, 0,
                                  0, 0, 0, 1);
          // animation 
          var _focalDistance = MIN_FOCAL_DISTANCE;
          var _incFocalDistance = (MAX_FOCAL_DISTANCE - MIN_FOCAL_DISTANCE) / 75;
          var _currentPoints3d;
          var _alpha = 0;
          var _incAlpha = Math.PI*2 / 100;
          var _beta = 33;
          var _incBeta = Math.PI*2 / 117;
  
          //
          // Animates the object and draw it
          //
          function animate() {
                  setToRotate(_matrix, _alpha, _beta, 0);
                  transformObject(_matrix, _points3d, _currentPoints3d);
  
                  _alpha = (_alpha + _incAlpha) % (Math.PI*2);
                  _beta = (_beta + _incBeta) % (Math.PI*2);
                  for (var i = 0; i < _faces.length; ++i) {
                          buildShape(i);
                  }
  
                  _focalDistance += _incFocalDistance;
                  if (_focalDistance > MAX_FOCAL_DISTANCE) {
                          _incFocalDistance = -_incFocalDistance;
                  } else if (_focalDistance < MIN_FOCAL_DISTANCE) {
                          _incFocalDistance = -_incFocalDistance;
                  }
          }
  
          //
          // Global initialization
          //
          function initializeShape3D(evt) {
                  buildCube();
  
                  // copy current object's coordinates to currentPoints3d
                  _currentPoints3d = new Array(_points3d.length);
                  for (var i = 0; i < _points3d.length; ++i) {
                          var pt3d = _points3d[i];
                          var cPt3d = new Array(3);
                          cPt3d[0] = pt3d[0];
                          cPt3d[1] = pt3d[1];
                          cPt3d[2] = pt3d[2];
                          _currentPoints3d[i] = cPt3d;
                  }
  
                  setToRotate(_matrix, Math.PI/4, Math.PI/4, 0);
                  transformObject(_matrix, _points3d, _currentPoints3d);
  
                  // builds the svg polygon elements
                  _shapes = new Array(_faces.length);
                  var document = evt.target.ownerDocument;
                  var g = document.getElementById('container');
                  var colors = new Array("#04a", "#025",  // front
                                         "#4a4", "#252",  // back
                                         "#a44", "#522",  // top
                                         "#aa4", "#552",  // bottom
                                         "#a4a", "#525",  // left
                                         "#aaa", "#555"); // right
                  for (var i = 0; i < _faces.length; ++i) {
                          var e = document.createElementNS(svgNS, "polygon");
                          e.setAttribute("style", "fill:"+colors[i]);
                          //e.setAttribute("style", "stroke:white;fill:none");
                          _shapes[i] = e;
                          buildShape(i);
                          g.appendChild(e);
                  }
  
                  // launch animation
                  setInterval('animate()', 20);
          }
  
          //
          // Builds the shapes according to the current points 3D 
          //
          function buildShape(index) {
                  var e = _shapes[index];
                  var face = _faces[index];
                  var pointsData = "";
                  if (!isFaceVisible(index)) {
                          pointsData = "-10 -10"; // hide the shape
                  } else {
                          var pt2d = new Array(2);
                          for (var i = 0; i < face.length; ++i) {
                                  projectPoint3d(_currentPoints3d[face[i]], pt2d);
                                  pointsData += pt2d[0]+" "+pt2d[1]+" ";
                          }
                  }
                  e.setAttribute("points", pointsData);
          }
  
          // --------------------------------------------------------------------
          // 2D functions
          // --------------------------------------------------------------------
  
          //
          // Projects a 3D point on the screen
          //
          function projectPoint3d(srcPt3d, destPt2d) {
                  var x = srcPt3d[0];
                  var y = srcPt3d[1];
                  var z = srcPt3d[2];
                  if (z == 0) {
                         z = 1;
                  }
                  destPt2d[0] = _focalDistance * x / (800-z) + _xOrigin; 
                  destPt2d[1] = _focalDistance * y / (800-z) + _yOrigin; 
          }
  
  
          // --------------------------------------------------------------------
          // 3D functions
          // --------------------------------------------------------------------
  
          //
          // Returns true if the face at the specified index is visible
          //
          function isFaceVisible(index) {
                  // take the 3 points that define the triangle
                  var face = _faces[index];
                  var p1 =  _currentPoints3d[face[0]];
                  var p2 =  _currentPoints3d[face[1]];
                  var p3 =  _currentPoints3d[face[2]];
                  return ((p3[0]-p1[0])*(p3[1]-p2[1])-(p3[0]-p2[0])*(p3[1]-p1[1]) > 0);
          }
  
          //
          // Transforms according to the specified matrix, the specified 3D points
          //
          function transformObject(matrix, points3d, currentPoints3d) {
                  for (var i = 0; i < currentPoints3d.length; ++i) {
                        transformPoint3d(matrix, points3d[i], currentPoints3d[i]);
                  }
          }
  
          //
          // Transforms according to the specified matrix, the specified point
          //
          function transformPoint3d(matrix, srcPt3d, destPt3d) {
                  var x = srcPt3d[0];
                  var y = srcPt3d[1];
                  var z = srcPt3d[2];
                  destPt3d[0] = x*matrix[0]+y*matrix[1]+z*matrix[2] + matrix[3];
                  destPt3d[1] = x*matrix[4]+y*matrix[5]+z*matrix[6] + matrix[7];
                  destPt3d[2] = x*matrix[8]+y*matrix[9]+z*matrix[10] + matrix[11];
          }
  
          //
          // Sets the specified matrix to a rotation matrix
          //
          function setToRotate(matrix, alpha, beta, gamma) {
                  // Assuming the angles are in radians
                  var c1 = Math.cos(alpha);
                  var s1 = Math.sin(alpha);
                  var c2 = Math.cos(beta);
                  var s2 = Math.sin(beta);
                  var c3 = Math.cos(gamma);    
                  var s3 = Math.sin(gamma);
  
                  matrix[0] = c1 * c2;
                  matrix[1] = s1 * c2;
                  matrix[2] = -s2;
                  matrix[3] = 0;
  
                  matrix[4] = -(s1 * c3)+(c1 * s2 * s3);
                  matrix[5] = (c1*c3) + (s1 * s2 * s3);
                  matrix[6] = c2 * s3;
                  matrix[7] = 0;
  
                  matrix[8] = (s1 * s3) + (c1 * s2 * c3);
                  matrix[9] = -(c1 * s3) + (s1 * s2 * c3);
                  matrix[10] = c2*c3;
                  matrix[11] = 0;
          }
  
          // --------------------------------------------------------------------
          // Cube initialization
          // --------------------------------------------------------------------
  
          //
          // Sets global variables such that the object represents a cube
          //
          function buildCube() {
                  _points3d = buildCubePoints();
                  _faces = buildCubeFaces();
          }
  
          //
          // Constructs the points array, anti-clockwise
          //
          function buildCubeFaces() {
                  var faces = new Array(12);
                  var i = 0;
  
                  faces[i++] = new Array(0, 2, 3); // front
                  faces[i++] = new Array(0, 3, 1);
  
                  faces[i++] = new Array(6, 4, 5); // back
                  faces[i++] = new Array(6, 5, 7);
  
                  faces[i++] = new Array(4, 0, 1); // top
                  faces[i++] = new Array(4, 1, 5);
  
                  faces[i++] = new Array(2, 6, 7); // bottom
                  faces[i++] = new Array(2, 7, 3);
  
                  faces[i++] = new Array(4, 6, 2); // left
                  faces[i++] = new Array(4, 2, 0);
  
                  faces[i++] = new Array(1, 3, 7); // right
                  faces[i++] = new Array(1, 7, 5);
  
                  return faces;
          }
  
          //
          // Constructs the points array
          //
          function buildCubePoints() {
                  var points3d = new Array(8);
  
                  // front coordinates
                  points3d[0] = new Array(-50, -50, -50);  // x,y,z coordinates
                  points3d[1] = new Array(50, -50, -50);
                  points3d[2] = new Array(-50, 50, -50);
                  points3d[3] = new Array(50, 50, -50);
  
                  // back coordinates
                  points3d[4] = new Array(-50, -50, 50);
                  points3d[5] = new Array(50, -50, 50);
                  points3d[6] = new Array(-50, 50, 50);
                  points3d[7] = new Array(50, 50, 50);
  
                  return points3d;
          }
  ]]></script>
  
  <defs>
          <linearGradient id="grad1">
                  <stop offset="0" style="stop-color:blue" />
                  <stop offset=".2" style="stop-color:red" />
                  <stop offset=".4" style="stop-color:yellow" />
                  <stop offset=".6" style="stop-color:green" />
                  <stop offset=".8" style="stop-color:cyan" />
                  <stop offset="1" style="stop-color:blue" />
          </linearGradient>
  </defs>
  
  <rect x="0" y="10%" width="100%" height="80%" style="fill:black" />
  <rect x="0" y="0" width="100%" height="10%" style="fill:#004" />
  <rect x="0" y="90%" width="100%" height="10%" style="fill:#004" />
  
  <rect x="0" y="10%" width="100%" height="1" style="fill:url(#grad1)" />
  <rect x="0" y="90%" width="100%" height="1" style="fill:url(#grad1)" />
  <text x="50%" y="40" style="text-anchor:middle; font-family:Impact;font-size:36; 
fill:white;">Batik 3D</text>
      <g id="container" onload="initializeShape3D(evt)">
  
      </g>
  
      <!-- ============================================================= -->
      <!-- Batik sample mark                                             -->
      <!-- ============================================================= -->
      <use xlink:href="batikLogo.svg#Batik_Tag_Box" />
  
  </svg>
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to