css Audio - Active file-generic CSS - Active Generic - Active HTML - Active JS - Active SVG - Active Text - Active file-generic Video - Active header Love html icon-new-collection icon-person icon-team numbered-list123 pop-out spinner split-screen star tv

Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

            
              
<canvas id="canvas"></canvas>
            
          
!
            
              body {
  background-color: #404040;
  color: white;
  font-family: arial;
  font-size: 12px;
}

.instructions {
  width: 380px;
  text-align: center;
}

canvas {
  width: 100%;
  height: 100%;
}
            
          
!
            
              /*
Closely based on :
https://github.com/revdancatt/CAT38-rotating-cobra-mk-3
( Running: http://revdancatt.github.io/CAT38-rotating-cobra-mk-3/ )

Models from the Wayback Machine archive copy of:
https://web.archive.org/web/   [ASTRISK HERE - JS comments break]  /http://mackayj.doosh.net/eliteships.html


They were converted with:
Some hardcoded VRML to JS naive conversions:
https://codepen.io/SarahC/pen/yzZKWN

VRML file selector and JS naive converter:
https://codepen.io/SarahC/pen/pWYJKV

*/

var debugPolys = false;
var fixBadlyWindedPolys = false;
var scale = 0.5;
var boxSize = 170;
var fontSize = 18;

var c = document.getElementById("canvas");
c.width = 1400;
c.height = 2500;
var ctx = c.getContext('2d');

var dim = {	size : {w : c.width, h : c.height}, 
           center : {x : c.width / 2, y : c.height / 2}
          };

var object = [];
var translation = [];
var ships = 0;
if(debugPolys){
  object[0] = make_testShip(); translation[0] = {x: 0, y: 0};
}else{
  var index = 0;
  var xPos = 0;
  var yPos = 0;
  var halfX = (c.width>>1) - (boxSize>>1);
  var halfY = (c.height>>1) - (boxSize>>1);
  for(var key in window) {
    if(key.indexOf("make_") > -1 && key != "make_testShip") {
      object[index] = window[key](); translation[index] = {x: xPos - halfX, y: yPos - halfY};
      object[index].name = toTitleCase(object[index].name);
      xPos += boxSize;
      if(xPos > c.width-boxSize){
        xPos = 0;
        yPos += boxSize;
      }
      if(fixBadlyWindedPolys) fixWinding(object[index]);
      index += 1;
    }
  }
  c.height = ~~(yPos + boxSize * 1.25);
  ctx.font = fontSize + "px Arial";
  ctx.textAlign = "center"; 
  ships = index;
  //temp
  //reverseWinding(object[6]);
}

//var rotator = new matrixRotate();
var camera = { zoom : 240 };
var counter = 0;
var wiggle = 0;
var start_time = 0;
var report = null;
var radmod = Math.PI / 180;

ctx.fillStyle = "black";
ctx.strokeStyle = "#a0a0a0";
ctx.lineWidth = 1;
ctx.translate(dim.center.x, dim.center.y);
requestAnimationFrame(frame);


var rotator = (function(){
  function matrixRotate(){
    this.radmod = Math.PI / 180;
    this.matrixRotate_cosa = null;
    this.matrixRotate_sina = null;

    this.matrixRotate_cosb = null;
    this.matrixRotate_sinb = null;

    this.matrixRotate_cosc = null;
    this.matrixRotate_sinc = null;

    this.matrixRotate_Axx = null;
    this.matrixRotate_Axy = null;
    this.matrixRotate_Axz = null;

    this.matrixRotate_Ayx = null;
    this.matrixRotate_Ayy = null;
    this.matrixRotate_Ayz = null;

    this.matrixRotate_Azx = null;
    this.matrixRotate_Azy = null;
    this.matrixRotate_Azz = null;
  }

  matrixRotate.prototype.makeMatrix = function(x, y, z){
    this.cosa = Math.cos(z * this.radmod);
    this.sina = Math.sin(z * this.radmod);

    this.cosb = Math.cos(y * this.radmod);
    this.sinb = Math.sin(y * this.radmod);

    this.cosc = Math.cos(x * this.radmod);
    this.sinc = Math.sin(x * this.radmod);

    this.Axx = this.cosa * this.cosb;
    this.Axy = this.cosa * this.sinb * this.sinc - this.sina * this.cosc;
    this.Axz = this.cosa * this.sinb * this.cosc + this.sina * this.sinc;

    this.Ayx = this.sina * this.cosb;
    this.Ayy = this.sina * this.sinb * this.sinc + this.cosa * this.cosc;
    this.Ayz = this.sina * this.sinb * this.cosc - this.cosa * this.sinc;

    this.Azx = -this.sinb;
    this.Azy = this.cosb * this.sinc;
    this.Azz = this.cosb * this.cosc;
  }

  matrixRotate.prototype.rotate = function(x, y, z){
    return {x: this.Axx * x + this.Axy * y + this.Axz * z,
            y: this.Ayx * x + this.Ayy * y + this.Ayz * z,
            z: this.Azx * x + this.Azy * y + this.Azz * z}
  }

  matrixRotate.prototype.rotateFromArray = function(from, to, scale){
    let xs = from.x * scale;
    let ys = from.y * scale;
    let zs = from.z * scale;
    to.x = this.Axx * xs + this.Axy * ys + this.Axz * zs;
    to.y = this.Ayx * xs + this.Ayy * ys + this.Ayz * zs;
    to.z = this.Azx * xs + this.Azy * ys + this.Azz * zs;
  }

  return new matrixRotate();
}());

function toTitleCase(str) {
  return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
}

function frame() {
  counter++;
  wiggle += (Math.sin(counter * radmod));
  var rotation = null;

  if(debugPolys)
    rotation = {x : 0, y : counter, z : 0};
  else
    rotation = {x : 90 + counter / 4, y : counter / 2, z : wiggle / 5};

  rotator.makeMatrix(rotation.x, rotation.y, rotation.z);

  for(var obj=0; obj< object.length; obj++)
    rotateObject(object[obj], rotator, scale);

  ctx.fillStyle = "black";
  ctx.fillRect(-dim.center.x, -dim.center.y, dim.size.w, dim.size.h);

  for(var obj=0; obj< object.length; obj++){
    draw_shape(object[obj], translation[obj]);
    ctx.fillStyle = "#606060";
    ctx.fillText(object[obj].name, translation[obj].x, translation[obj].y + (boxSize>>1));
  }

  requestAnimationFrame(frame);
}

function rotateObject(object, rotator, scale) {
  for(var i=0; i < object.rotatedPoints.length; i++){    
    rotator.rotateFromArray(object.modelPoints[i], object.rotatedPoints[i], scale);
  }
}

//My little lighting algorithm.
function getAngle(points){
  var normalVector = getNormal(points);
  var ang = Math.atan2(normalVector.z, normalVector.x); // y first.
  ang += Math.PI; // 0 to 2PI
  ang /= Math.PI; // 0 to 2
  return 2 - (ang * 2); // 4 to 0 (But only ever between 2 to 0 due to rotation position)
}

function reverseWinding(shape){
  for (var i=0; i < shape.polygons.length; i++) {
    shape.polygons[i] = shape.polygons[i].reverse();
    var b = shape.polygons[i].shift(); // Get the polygon color, and put it back at the end.
    shape.polygons[i].push(b);
  }
}

function fixWinding(shape){
  for (var i=0; i < shape.polygons.length; i++) {
    var polygon3DPoints = [];
    for (var j=0; j < shape.polygons[i].length-1; j++) {
      polygon3DPoints.push(shape.modelPoints[shape.polygons[i][j]]);
    }
    //Get normal to see which way polygon is pointing.
    var normal = getNormal(polygon3DPoints);

    //Check if polygon is facing front - determinate.
    var a = ((polygon3DPoints[2].x - polygon3DPoints[0].x) * (polygon3DPoints[1].y - polygon3DPoints[2].y));
    var b = ((polygon3DPoints[2].y - polygon3DPoints[0].y) * (polygon3DPoints[1].x - polygon3DPoints[2].x));
    var front = a > b;

    //If the normal is pointing away, inverse front flag.
    if(normal.z < 0) front !=front;

    if(front) {
      console.log("Facing front", normal);
    }else{
      console.log("Facing back, flipping", normal);
      //Flip.
      shape.polygons[i] = shape.polygons[i].reverse();
      var b = shape.polygons[i].shift(); // Get the polygon color, and put it back at the end.
      shape.polygons[i].push(b);
    }
  }
}

function getNormal(p){
  var nx = (p[1].y - p[0].y)*(p[2].z - p[0].z) - (p[1].z - p[0].z)*(p[2].y - p[0].y);
  var ny = NaN; //(p[1].z - p[0].z)*(p[2].x - p[0].x) - (p[1].x - p[0].x)*(p[2].z - p[0].z); // Y normal not needed.
  var nz = (p[1].x - p[0].x)*(p[2].y - p[0].y) - (p[1].y - p[0].y)*(p[2].x - p[0].x);
  return {x: nx, y: ny, z: nz};
}

function draw_shape(shape, screenTranslate) {
  var projectedPoints = [];
  for (var i=0; i < shape.rotatedPoints.length; i++) {
    projectedPoints.push(project_point(shape.rotatedPoints[i], screenTranslate));
  }
  for (var i=0; i < shape.polygons.length; i++) {
    var polygonProjectedPoints = [];
    var polygon3DPoints = [];
    for (var j=0; j < shape.polygons[i].length-1; j++) {
      polygonProjectedPoints.push(projectedPoints[shape.polygons[i][j]]);
      polygon3DPoints.push(shape.rotatedPoints[shape.polygons[i][j]]);
    }
    polygonProjectedPoints.push(shape.polygons[i][shape.polygons[i].length-1]);
    draw_poly(polygonProjectedPoints, polygon3DPoints);
  }
}

function draw_poly(poly, polygon3DPoints) {
  // Determinate.
  var a = ((poly[2].x - poly[0].x) * (poly[1].y - poly[2].y));
  var b = ((poly[2].y - poly[0].y) * (poly[1].x - poly[2].x));
  var front = a > b;
  if (front) {
    var angle = getAngle(polygon3DPoints);

    ctx.beginPath();
    ctx.moveTo(poly[0].x, poly[0].y);	
    for (var i = 1; i < poly.length-1; i++) {
      ctx.lineTo(poly[i].x, poly[i].y);
    }
    var colour = poly[poly.length-1];
    colour = applyLighting(colour, angle);
    ctx.fillStyle = `rgb(${colour[0]}, ${colour[1]}, ${colour[2]})`;
    ctx.strokeStyle = ctx.fillStyle;
    ctx.lineTo(poly[0].x, poly[0].y);
    ctx.stroke(); // Solve aliasing problems.
    ctx.fill();
  }
}

function applyLighting(colour, angle){
  var r = colour[0];
  var g = colour[1];
  var b = colour[2];
  r *= angle;
  g *= angle;
  b *= angle;
  return [~~r, ~~g, ~~b];
}

function translate_point(point, translate){
  var new_point = {
    x: point.x + translate.x,
    y: point.y + translate.y,
    z: point.z + translate.z
  }
  return new_point;
}

function project_point_alt(point, screenTranslate) {
  var r = camera.zoom / (point.z + 300);
  var new_point = {
    x: (point.x * r) + screenTranslate.x,
    y: (point.y * r) + screenTranslate.y
  }
  return new_point;
}

function project_point(point, screenTranslate) {
  var f =  1 + (point.z / camera.zoom);
  var new_point = {
    x: (point.x * f) + screenTranslate.x,
    y: (point.y * f) + screenTranslate.y
  }
  return new_point;
}

//#############################################################################

function make_testShip() {
  var modelPoints = [
    {x: 0, y: 0, z: 0},
    {x: 50, y: 0, z: 0},
    {x: 0, y: 50, z: 0}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 2, [50, 50, 150]]
  ];

  return {
    name: "test ship",
    modelPoints,
    rotatedPoints,
    polygons
  };
}

//#############################################################################

function make_originalCobra() {
  var	modelPoints = [
    {x:32, y:0, z: 76},
    {x:-32, y:0, z:76},
    {x:0, y: 26, z:24},
    {x:-120, y: -3, z:-8},
    {x:120, y: -3, z:-8},
    {x:-88, y: 16, z:-40},
    {x:88, y: 16, z:-40},
    {x:128, y: -8, z:-40},
    {x:-128, y: -8, z:-40},
    {x:0, y: 26, z:-40},
    {x:-32, y: -24, z:-40},
    {x:32, y: -24, z:-40},
    {x:-0.25, y:0, z:76},
    {x:0, y:0, z:86},
    {x:0.25, y:0, z:76},
    {x:-36, y:8, z:-40},
    {x:-8, y:12, z:-40},
    {x:-8, y:-16, z:-40},
    {x:-36, y:-12, z:-40},
    {x:36, y:8, z:-40},
    {x:8, y:12, z:-40},
    {x:8, y:-16, z:-40},
    {x:36, y:-12, z:-40},
    {x:-80, y:-6, z:-40},
    {x:-80, y:6, z:-40},
    {x:-88, y:0, z:-40},
    {x:80, y:-6, z:-40},
    {x:80, y:6, z:-40},
    {x:88, y:0, z:-40}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 2, [48, 48, 112]], // Top front
    [0, 11, 10, 1, [64, 64, 64]], // Bottom middle
    [0, 2, 6, [192, 192, 192]], // Top middle right
    [0, 6, 4, [160, 160, 160]], // Top Middle right 2
    [0, 4, 7, 11, [80, 80, 80]], // Bottom right
    [1, 5, 2, [192, 192, 192]], // Top middle left
    [1, 3, 5, [160, 160, 160]], // Top middle left 2
    [1, 10, 8, 3, [80, 80, 80]], // Bottom left
    [2, 5, 9, [144, 144, 144]], // Top back left
    [2, 9, 6, [144, 144, 144]], // Top back right
    [3, 8, 5, [112, 112, 112]], // Top back far left
    [4, 6, 7, [112, 112, 112]], // Top back far right
    [5, 8, 10, 11, 7, 6, 9, [128, 128, 128]], // Back
    [12, 13, 14, [128, 128, 128]], // Pointy shooty thing
    [12, 14, 13, [128, 128, 128]], // Pointy shooty thing
    [15, 18, 17, 16, [240, 64, 64]], // Main engine left
    [19, 20, 21, 22, [240, 64, 64]], // Main engine right
    [23, 24, 25, [192, 0, 0]], // Small engine left
    [26, 28, 27, [192, 0, 0]] // Small engine right
  ];

  return {
    name: "Cobra original",
    modelPoints,
    rotatedPoints,
    polygons
  };
}

//#############################################################################
//#############################################################################

function make_adder() {
  var modelPoints = [
    {x: -80, y: 0, z: -110},
    {x: -80, y: 0, z: -70},
    {x: -60, y: 19, z: -110},
    {x: -60, y: 19, z: 10},
    {x: 60, y: 19, z: 10},
    {x: 60, y: 19, z: -110},
    {x: 80, y: 0, z: -70},
    {x: 80, y: 0, z: -110},
    {x: -60, y: 0, z: 90},
    {x: 60, y: 0, z: 90},
    {x: 60, y: -20, z: -110},
    {x: 60, y: -20, z: 10},
    {x: -60, y: -20, z: -110},
    {x: -60, y: -20, z: 10},
    {x: -35, y: 7, z: 60},
    {x: -35, y: 12, z: 40},
    {x: 35, y: 12, z: 40},
    {x: 35, y: 7, z: 60},
    {x: -25, y: 9, z: -110.1},
    {x: 25, y: 9, z: -110.1},
    {x: 25, y: -15, z: -110.1},
    {x: -25, y: -15, z: -110.1},
    {x: 13, y: 20, z: -29},
    {x: 13, y: 20, z: -89},
    {x: 25, y: 20, z: -69},
    {x: -13, y: 20, z: -29},
    {x: -13, y: 20, z: -89},
    {x: -25, y: 20, z: -69}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [2, 1, 0, [159, 159, 32]],
    [2, 3, 1, [159, 159, 32]],
    [4, 3, 2, [223, 159, 32]],
    [4, 2, 5, [223, 159, 32]],
    [22, 23, 24, [32, 96, 32]],
    [27, 26, 25, [32, 96, 32]],
    [5, 6, 4, [159, 159, 32]],
    [6, 5, 7, [159, 159, 32]],
    [3, 8, 1, [96, 159, 32]],
    [4, 6, 9, [96, 159, 32]],
    [3, 9, 8, [159, 159, 32]],
    [3, 4, 9, [159, 159, 32]],
    [7, 10, 6, [96, 159, 32]],
    [10, 11, 6, [96, 159, 32]],
    [6, 11, 9, [96, 96, 32]],
    [1, 12, 0, [96, 159, 32]],
    [13, 12, 1, [96, 159, 32]],
    [8, 13, 1, [96, 96, 32]],
    [12, 13, 11, [96, 96, 32]],
    [10, 12, 11, [96, 96, 32]],
    [11, 13, 9, [32, 96, 32]],
    [13, 8, 9, [32, 96, 32]],
    [14, 15, 16, [96, 96, 32]],
    [16, 17, 14, [96, 96, 32]],
    [0, 12, 2, [96, 96, 96]],
    [2, 12, 10, [96, 96, 96]],
    [10, 5, 2, [96, 96, 96]],
    [5, 10, 7, [96, 96, 96]],
    [20, 19, 18, [223, 32, 32]],
    [20, 18, 21, [223, 32, 32]]
  ];

  return {
    name: "adder",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_anaconda() {
  var modelPoints = [
    {x: 0, y: -25, z: 175},
    {x: -70, y: -75, z: -145},
    {x: 70, y: -75, z: -145},
    {x: 110, y: -35, z: -95},
    {x: -110, y: -35, z: -95},
    {x: -60, y: 35, z: -115},
    {x: 60, y: 35, z: -115},
    {x: 0, y: 15, z: -175},
    {x: 0, y: -15, z: -165.1},
    {x: -30, y: -51, z: -153.1},
    {x: 30, y: -51, z: -153.1},
    {x: -17, y: -6, z: 83},
    {x: 18, y: -6, z: 83},
    {x: 20, y: -4, z: 74},
    {x: -20, y: -4, z: 74},
    {x: -18, y: -6, z: 83},
    {x: 16, y: -8, z: 94},
    {x: 14, y: -10, z: 103},
    {x: -14, y: -10, z: 103},
    {x: -16, y: -8, z: 94}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [2, 1, 0, [223, 159, 32]],
    [0, 3, 2, [159, 159, 32]],
    [1, 4, 0, [159, 159, 32]],
    [0, 5, 6, [223, 159, 32]],
    [0, 6, 3, [159, 159, 96]],
    [5, 7, 6, [159, 96, 32]],
    [7, 1, 2, [159, 96, 32]],
    [8, 9, 10, [223, 32, 32]],
    [6, 7, 2, [96, 32, 32]],
    [3, 6, 2, [96, 32, 32]],
    [4, 5, 0, [159, 159, 96]],
    [1, 7, 5, [96, 32, 32]],
    [5, 4, 1, [96, 32, 32]],
    [13, 12, 11, [32, 32, 32]],
    [15, 14, 13, [32, 32, 32]],
    [16, 17, 18, [32, 32, 32]],
    [18, 19, 16, [32, 32, 32]]
  ];

  return {
    name: "anaconda",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_asp2() {
  var modelPoints = [
    {x: -60, y: 0, z: -75},
    {x: 0, y: 20, z: -75},
    {x: 0, y: -20, z: -75},
    {x: 60, y: 0, z: -75},
    {x: 0, y: 20, z: -5},
    {x: -60, y: 10, z: 15},
    {x: 60, y: -10, z: 15},
    {x: 0, y: 10, z: -75.1},
    {x: -60, y: -10, z: 15},
    {x: -100, y: 0, z: 5},
    {x: 60, y: 10, z: 15},
    {x: -20, y: 0, z: -75.1},
    {x: 100, y: 0, z: 5},
    {x: -40, y: 0, z: 75},
    {x: 40, y: 0, z: 75},
    {x: 0, y: -10, z: -75.1},
    {x: 20, y: 0, z: -75.1}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [2, 1, 0, [96, 96, 96]],
    [3, 1, 2, [96, 96, 96]],
    [7, 11, 15, [223, 32, 32]],
    [16, 7, 15, [223, 32, 32]],
    [0, 1, 4, [96, 159, 96]],
    [4, 5, 0, [96, 159, 96]],
    [5, 9, 0, [96, 159, 96]],
    [3, 4, 1, [32, 223, 96]],
    [3, 10, 4, [32, 223, 96]],
    [12, 10, 3, [32, 223, 96]],
    [4, 13, 5, [96, 96, 32]],
    [14, 13, 4, [96, 96, 32]],
    [14, 4, 10, [96, 96, 32]],
    [5, 13, 9, [32, 96, 32]],
    [10, 12, 14, [32, 96, 32]],
    [8, 6, 2, [96, 96, 32]],
    [8, 13, 6, [32, 96, 96]],
    [13, 14, 6, [32, 96, 96]],
    [8, 9, 13, [32, 159, 96]],
    [14, 12, 6, [32, 159, 96]],
    [2, 6, 12, [32, 96, 32]],
    [12, 3, 2, [32, 96, 32]],
    [9, 8, 2, [32, 96, 32]],
    [2, 0, 9, [32, 96, 32]]
  ];

  return {
    name: "asp2",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_asp2v() {
  var modelPoints = [
    {x: 115, y: -10, z: 15},
    {x: 50, y: -10, z: 97},
    {x: 90, y: 16, z: 27},
    {x: -50, y: -10, z: 97},
    {x: -115, y: -10, z: 15},
    {x: -90, y: 16, z: 27},
    {x: 65, y: -10, z: -103},
    {x: 98, y: -30, z: 37},
    {x: -98, y: -30, z: 37},
    {x: -65, y: -10, z: -103},
    {x: 0, y: 30, z: -11},
    {x: 0, y: 20, z: -103},
    {x: -18, y: -10, z: -103},
    {x: 18, y: -10, z: -103},
    {x: -18, y: -14, z: 85.1},
    {x: -24, y: -26, z: 49.1},
    {x: -14, y: -26, z: 49.1},
    {x: 24, y: -26, z: 49.1},
    {x: 14, y: -26, z: 49.1},
    {x: 18, y: -14, z: 85.1}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [7, 0, 6, [32, 96, 32]],
    [8, 3, 1, [32, 159, 32]],
    [7, 8, 1, [32, 159, 32]],
    [16, 15, 14, [223, 96, 32]],
    [17, 18, 19, [223, 96, 32]],
    [7, 9, 8, [32, 96, 32]],
    [7, 6, 9, [32, 96, 32]],
    [6, 2, 10, [32, 223, 96]],
    [5, 9, 10, [32, 223, 96]],
    [11, 6, 10, [96, 159, 32]],
    [11, 10, 9, [32, 159, 32]],
    [2, 1, 10, [223, 159, 32]],
    [1, 3, 10, [223, 159, 32]],
    [3, 5, 10, [223, 159, 32]],
    [11, 12, 13, [32, 96, 96]],
    [11, 9, 12, [223, 32, 32]],
    [6, 11, 13, [223, 32, 32]],
    [9, 5, 4, [96, 96, 32]],
    [8, 9, 4, [32, 96, 32]],
    [3, 8, 4, [159, 159, 32]],
    [4, 5, 3, [159, 159, 32]],
    [1, 2, 0, [159, 159, 32]],
    [0, 7, 1, [159, 159, 32]],
    [0, 2, 6, [96, 96, 32]]
  ];

  return {
    name: "asp2v",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_boa() {
  var modelPoints = [
    {x: 46, y: 3, z: -114},
    {x: 0, y: -46, z: -67},
    {x: 0, y: 4, z: 114},
    {x: 44, y: 46, z: -87},
    {x: -44, y: 46, z: -87},
    {x: -46, y: 3, z: -114},
    {x: 0, y: 16, z: -105},
    {x: 14, y: 39, z: -92},
    {x: -12, y: 39, z: -92}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 2, [96, 96, 159]],
    [3, 0, 2, [159, 96, 159]],
    [4, 3, 2, [223, 96, 159]],
    [5, 4, 2, [159, 96, 159]],
    [1, 5, 2, [96, 96, 159]],
    [3, 4, 5, [96, 32, 159]],
    [3, 5, 0, [96, 32, 159]],
    [1, 0, 5, [32, 32, 96]],
    [6, 7, 8, [223, 32, 32]]
  ];

  return {
    name: "boa",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_bushmaster() {
  var modelPoints = [
    {x: 100, y: -20, z: 30},
    {x: -100, y: -20, z: 30},
    {x: 0, y: -20, z: 130},
    {x: 100, y: -20, z: -90},
    {x: -100, y: -20, z: -90},
    {x: 40, y: -20, z: -130},
    {x: -40, y: -20, z: -130},
    {x: 40, y: 20, z: -130},
    {x: 40, y: 20, z: -10},
    {x: -40, y: 20, z: -130},
    {x: -40, y: 20, z: -10},
    {x: 0, y: -20, z: 130},
    {x: -40, y: -20.1, z: 30},
    {x: -50, y: -20.1, z: -90},
    {x: -30, y: -20.1, z: -90},
    {x: 40, y: -20.1, z: 30},
    {x: 30, y: -20.1, z: -90},
    {x: 50, y: -20.1, z: -90},
    {x: -30, y: 0, z: -130.1},
    {x: -10, y: 10, z: -130.1},
    {x: -10, y: -10, z: -130.1},
    {x: 10, y: 10, z: -130.1},
    {x: 10, y: -10, z: -130.1},
    {x: 30, y: 0, z: -130.1}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 2, [96, 32, 32]],
    [0, 3, 1, [96, 32, 32]],
    [3, 4, 1, [96, 32, 32]],
    [3, 5, 6, [96, 32, 32]],
    [6, 4, 3, [96, 32, 32]],
    [14, 13, 12, [223, 32, 32]],
    [17, 16, 15, [223, 32, 32]],
    [5, 3, 7, [96, 96, 96]],
    [8, 9, 7, [96, 223, 223]],
    [10, 9, 8, [96, 223, 223]],
    [2, 10, 8, [159, 223, 223]],
    [10, 2, 1, [32, 159, 159]],
    [8, 0, 11, [32, 159, 159]],
    [8, 7, 0, [96, 159, 159]],
    [7, 3, 0, [32, 159, 159]],
    [10, 1, 9, [96, 159, 159]],
    [1, 4, 9, [32, 159, 159]],
    [5, 7, 9, [32, 96, 96]],
    [9, 6, 5, [32, 96, 96]],
    [20, 19, 18, [223, 32, 32]],
    [21, 22, 23, [223, 32, 32]],
    [6, 9, 4, [96, 96, 96]]
  ];

  return {
    name: "bushmaster",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_caiman() {
  var modelPoints = [
    {x: -40, y: -30, z: 40},
    {x: -120, y: -30, z: -120},
    {x: 0, y: 10, z: -120},
    {x: 120, y: -30, z: -120},
    {x: 40, y: -30, z: 40},
    {x: 0, y: 30, z: 40},
    {x: 0, y: -30, z: 120},
    {x: 8, y: -6, z: -120.1},
    {x: 8, y: -22, z: -120.1},
    {x: 52, y: -22, z: -120.1},
    {x: -8, y: -22, z: -120.1},
    {x: -8, y: -6, z: -120.1},
    {x: -52, y: -22, z: -120.1},
    {x: 13, y: 2, z: 52},
    {x: 25, y: -14, z: 52},
    {x: 13, y: -14, z: 76},
    {x: -13, y: -14, z: 76},
    {x: -25, y: -14, z: 52},
    {x: -13, y: 2, z: 52}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 2, [96, 96, 159]],
    [2, 3, 4, [96, 96, 159]],
    [2, 5, 0, [96, 159, 159]],
    [2, 4, 5, [32, 159, 159]],
    [6, 0, 5, [96, 223, 159]],
    [5, 4, 6, [159, 223, 159]],
    [3, 2, 1, [96, 159, 96]],
    [7, 8, 9, [223, 32, 32]],
    [10, 11, 12, [223, 32, 32]],
    [1, 6, 3, [32, 32, 159]],
    [13, 14, 15, [32, 32, 96]],
    [16, 17, 18, [32, 32, 96]]
  ];

  return {
    name: "caiman",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_cobra1() {
  var modelPoints = [
    {x: 45, y: -6, z: 78},
    {x: -45, y: -6, z: 78},
    {x: 0, y: 25, z: -12},
    {x: -91, y: 10, z: -78},
    {x: 91, y: 10, z: -78},
    {x: -130, y: -6, z: 30},
    {x: 130, y: -6, z: 30},
    {x: 130, y: -6, z: -57},
    {x: -130, y: -6, z: -57},
    {x: 91, y: -25, z: -77},
    {x: -91, y: -25, z: -78},
    {x: -27, y: 4.7, z: 47},
    {x: 27, y: 4.7, z: 47},
    {x: 27, y: 0.3, z: 60},
    {x: -27, y: 0.3, z: 60},
    {x: 0, y: 1, z: -78},
    {x: 45, y: -15, z: -78},
    {x: 60, y: 0, z: -78},
    {x: -60, y: 0, z: -78},
    {x: -45, y: -15, z: -78}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 2, [223, 223, 223]],
    [2, 3, 4, [32, 223, 223]],
    [0, 2, 4, [32, 159, 223]],
    [2, 1, 3, [32, 159, 223]],
    [5, 3, 1, [32, 159, 223]],
    [6, 0, 4, [32, 159, 223]],
    [6, 4, 7, [32, 96, 223]],
    [8, 3, 5, [32, 96, 223]],
    [6, 7, 9, [96, 32, 223]],
    [10, 8, 5, [96, 32, 223]],
    [10, 3, 8, [159, 96, 223]],
    [4, 9, 7, [159, 96, 223]],
    [4, 3, 9, [32, 32, 159]],
    [9, 3, 10, [32, 32, 159]],
    [0, 10, 1, [32, 32, 96]],
    [0, 9, 10, [32, 32, 96]],
    [10, 5, 1, [96, 32, 96]],
    [0, 6, 9, [96, 32, 96]],
    [11, 12, 13, [32, 32, 96]],
    [13, 14, 11, [32, 32, 96]],
    [15, 16, 17, [223, 32, 32]],
    [15, 18, 19, [223, 32, 32]]
  ];

  return {
    name: "cobra1",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_cobra3() {
  var modelPoints = [
    {x: 0, y: 15, z: 10},
    {x: 80, y: 5, z: -45},
    {x: 25, y: -5, z: 45},
    {x: -25, y: -5, z: 45},
    {x: -80, y: 5, z: -45},
    {x: 0, y: 15, z: -45},
    {x: 95, y: -5, z: -25},
    {x: -95, y: -5, z: -25},
    {x: 95, y: -5, z: -45},
    {x: -95, y: -5, z: -45},
    {x: -25, y: -15, z: -45},
    {x: 25, y: -15, z: -45},
    {x: -60, y: -5, z: -45.1},
    {x: -60, y: 5, z: -45.1},
    {x: -75, y: 0, z: -45.1},
    {x: 60, y: 5, z: -45.1},
    {x: 75, y: 0, z: -45.1},
    {x: 60, y: -5, z: -45.1},
    {x: -5, y: 5, z: -45.1},
    {x: -5, y: -10, z: -45.1},
    {x: -30, y: 0, z: -45.1},
    {x: -30, y: -5, z: -45.1},
    {x: 5, y: 5, z: -45.1},
    {x: 5, y: -10, z: -45.1},
    {x: 30, y: 0, z: -45.1},
    {x: 30, y: -5, z: -45.1}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 2, [96, 32, 223]],
    [0, 3, 4, [96, 32, 223]],
    [0, 5, 1, [32, 159, 159]],
    [0, 4, 5, [32, 159, 159]],
    [2, 1, 6, [32, 32, 159]],
    [3, 7, 4, [32, 32, 159]],
    [1, 8, 6, [32, 32, 96]],
    [4, 7, 9, [32, 32, 96]],
    [2, 3, 0, [96, 159, 223]],
    [4, 9, 10, [96, 96, 96]],
    [1, 11, 8, [96, 96, 96]],
    [5, 4, 10, [96, 96, 96]],
    [5, 10, 11, [32, 96, 96]],
    [1, 5, 11, [96, 96, 96]],
    [12, 13, 14, [223, 32, 32]],
    [17, 16, 15, [223, 32, 32]],
    [20, 19, 18, [223, 32, 32]],
    [20, 21, 19, [223, 32, 32]],
    [22, 23, 24, [223, 32, 32]],
    [23, 25, 24, [223, 32, 32]],
    [2, 11, 10, [32, 32, 159]],
    [10, 3, 2, [32, 32, 159]],
    [8, 11, 2, [32, 96, 96]],
    [2, 6, 8, [32, 96, 96]],
    [3, 9, 7, [32, 96, 96]],
    [3, 10, 9, [32, 96, 96]]
  ];

  return {
    name: "cobra3",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_cobra3v() {
  var modelPoints = [
    {x: 0, y: 15, z: 10},
    {x: 80, y: 5, z: -45},
    {x: 25, y: -5, z: 45},
    {x: -25, y: -5, z: 45},
    {x: -80, y: 5, z: -45},
    {x: 0, y: 15, z: -45},
    {x: 95, y: -5, z: -25},
    {x: -95, y: -5, z: -25},
    {x: 95, y: -5, z: -45},
    {x: -95, y: -5, z: -45},
    {x: -25, y: -15, z: -45},
    {x: 25, y: -15, z: -45},
    {x: -60, y: -5, z: -45.1},
    {x: -60, y: 5, z: -45.1},
    {x: -75, y: 0, z: -45.1},
    {x: 60, y: 5, z: -45.1},
    {x: 75, y: 0, z: -45.1},
    {x: 60, y: -5, z: -45.1},
    {x: -5, y: 5, z: -45.1},
    {x: -5, y: -10, z: -45.1},
    {x: -30, y: 0, z: -45.1},
    {x: -30, y: -5, z: -45.1},
    {x: 5, y: 5, z: -45.1},
    {x: 5, y: -10, z: -45.1},
    {x: 30, y: 0, z: -45.1},
    {x: 30, y: -5, z: -45.1}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 2, [159, 96, 32]],
    [0, 3, 4, [159, 96, 32]],
    [0, 5, 1, [96, 32, 32]],
    [0, 4, 5, [96, 32, 32]],
    [2, 1, 6, [32, 96, 32]],
    [3, 7, 4, [32, 96, 32]],
    [1, 8, 6, [32, 32, 96]],
    [4, 7, 9, [32, 32, 96]],
    [2, 3, 0, [159, 32, 32]],
    [4, 9, 10, [96, 96, 96]],
    [1, 11, 8, [96, 96, 96]],
    [5, 4, 10, [96, 96, 96]],
    [5, 10, 11, [32, 96, 96]],
    [1, 5, 11, [96, 96, 96]],
    [12, 13, 14, [223, 32, 32]],
    [17, 16, 15, [223, 32, 32]],
    [20, 19, 18, [223, 32, 32]],
    [20, 21, 19, [223, 32, 32]],
    [22, 23, 24, [223, 32, 32]],
    [23, 25, 24, [223, 32, 32]],
    [2, 11, 10, [32, 96, 32]],
    [10, 3, 2, [32, 96, 32]],
    [8, 11, 2, [32, 96, 96]],
    [2, 6, 8, [32, 96, 96]],
    [3, 9, 7, [32, 96, 96]],
    [3, 10, 9, [32, 96, 96]]
  ];

  return {
    name: "cobra3v",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_constrictor() {
  var modelPoints = [
    {x: -20, y: -12, z: 45},
    {x: -35, y: -12, z: 25},
    {x: 20, y: -12, z: 45},
    {x: -35, y: -12, z: -45},
    {x: 35, y: -12, z: 25},
    {x: 35, y: -12, z: -45},
    {x: -20, y: 2, z: -45},
    {x: -20, y: 2, z: 15},
    {x: -10, y: 2, z: 30},
    {x: 10, y: 2, z: 30},
    {x: 20, y: 2, z: -45},
    {x: 20, y: 2, z: 15},
    {x: -15, y: -2, z: -45.1},
    {x: -20, y: -7, z: -45.1},
    {x: 15, y: -2, z: -45.1},
    {x: 20, y: -7, z: -45.1},
    {x: -15, y: -12.1, z: -35},
    {x: -10, y: -12.1, z: -35},
    {x: -10, y: -12.1, z: 20},
    {x: 10, y: -12.1, z: 20},
    {x: 10, y: -12.1, z: -35},
    {x: 15, y: -12.1, z: -35},
    {x: 0, y: 2.2, z: 25},
    {x: -10, y: 2.2, z: 5},
    {x: 10, y: 2.2, z: 5},
    {x: -10, y: 2.1, z: -25},
    {x: 0, y: 2.1, z: 15},
    {x: 10, y: 2.1, z: -25}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [3, 1, 0, [32, 96, 96]],
    [3, 0, 2, [32, 96, 96]],
    [3, 2, 5, [32, 96, 96]],
    [5, 2, 4, [32, 96, 96]],
    [18, 17, 16, [32, 32, 96]],
    [21, 20, 19, [32, 32, 96]],
    [8, 7, 6, [223, 223, 32]],
    [6, 9, 8, [223, 223, 32]],
    [6, 10, 9, [223, 223, 32]],
    [10, 11, 9, [223, 223, 32]],
    [22, 23, 24, [32, 223, 96]],
    [26, 25, 27, [159, 223, 96]],
    [5, 6, 3, [96, 32, 32]],
    [5, 10, 6, [96, 32, 32]],
    [12, 13, 15, [223, 32, 32]],
    [14, 12, 15, [223, 32, 32]],
    [2, 0, 8, [96, 223, 32]],
    [8, 9, 2, [96, 223, 32]],
    [4, 11, 10, [159, 223, 32]],
    [10, 5, 4, [159, 223, 32]],
    [6, 7, 1, [159, 223, 32]],
    [1, 3, 6, [159, 223, 32]],
    [2, 9, 11, [32, 159, 32]],
    [11, 4, 2, [32, 159, 32]],
    [7, 8, 0, [32, 159, 32]],
    [0, 1, 7, [32, 159, 32]]
  ];

  return {
    name: "constrictor",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_copperhead() {
  var modelPoints = [
    {x: 0, y: 40, z: 0},
    {x: -60, y: -20, z: 100},
    {x: 60, y: -20, z: 100},
    {x: 80, y: 0, z: -40},
    {x: 0, y: -20, z: -80},
    {x: -80, y: 0, z: -40},
    {x: 0, y: -20.1, z: -20},
    {x: -20, y: -20.1, z: 40},
    {x: 20, y: -20.1, z: 40}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [5, 4, 0, [32, 96, 32]],
    [4, 3, 0, [16, 80, 16]],
    [1, 5, 0, [48, 112, 48]],
    [2, 1, 0, [112, 112, 48]],
    [3, 2, 0, [48, 112, 48]],
    [5, 1, 4, [48, 112, 112]],
    [2, 3, 4, [48, 112, 112]],
    [1, 2, 4, [80, 80, 80]],
    [7, 8, 6, [223, 32, 32]]
  ];

  return {
    name: "copperhead",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_ferdelance() {
  var modelPoints = [
    {x: 0, y: -25, z: 120},
    {x: -70, y: 15, z: -60},
    {x: 0, y: 25, z: -90},
    {x: 70, y: 15, z: -60},
    {x: -70, y: -25, z: -60},
    {x: 70, y: -25, z: -60},
    {x: 40, y: 15, z: -120},
    {x: -40, y: 15, z: -120},
    {x: 40, y: -25, z: -120},
    {x: -40, y: -25, z: -120},
    {x: -10, y: -13, z: 70},
    {x: -50, y: 15, z: -50},
    {x: -10, y: 21, z: -70},
    {x: 10, y: -13, z: 70},
    {x: 10, y: 21, z: -70},
    {x: 50, y: 15, z: -50},
    {x: -10, y: 5, z: -120.1},
    {x: 10, y: 5, z: -120.1},
    {x: 10, y: -15, z: -120.1},
    {x: -10, y: -15, z: -120.1}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 2, [223, 159, 96]],
    [3, 0, 2, [223, 159, 32]],
    [0, 4, 1, [96, 32, 32]],
    [3, 5, 0, [96, 32, 32]],
    [2, 6, 3, [159, 159, 32]],
    [2, 1, 7, [159, 159, 32]],
    [2, 7, 6, [32, 96, 32]],
    [6, 8, 3, [159, 96, 32]],
    [3, 8, 5, [159, 96, 32]],
    [7, 1, 4, [159, 96, 32]],
    [7, 4, 9, [159, 96, 32]],
    [9, 6, 7, [96, 96, 96]],
    [8, 6, 9, [96, 96, 96]],
    [18, 17, 16, [223, 32, 32]],
    [16, 19, 18, [223, 32, 32]],
    [9, 4, 0, [96, 96, 96]],
    [8, 9, 0, [32, 96, 96]],
    [8, 0, 5, [96, 96, 96]],
    [10, 11, 12, [96, 32, 32]],
    [13, 14, 15, [96, 32, 32]]
  ];

  return {
    name: "ferdelance",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_gecko() {
  var modelPoints = [
    {x: -60, y: 30, z: -100},
    {x: 60, y: 30, z: -100},
    {x: 120, y: 0, z: -60},
    {x: 60, y: -30, z: -100},
    {x: -60, y: -30, z: -100},
    {x: -120, y: 0, z: -60},
    {x: -30, y: 0, z: 100},
    {x: 30, y: 0, z: 100},
    {x: 10, y: -9, z: 40},
    {x: 25, y: -28, z: -80},
    {x: 10, y: -28, z: -80},
    {x: -10, y: -28, z: -80},
    {x: -25, y: -28, z: -80},
    {x: -10, y: -9, z: 40},
    {x: -30, y: 20, z: -100.1},
    {x: 30, y: 20, z: -100.1},
    {x: -30, y: -20, z: -100.1},
    {x: 30, y: -20, z: -100.1},
    {x: -90, y: 0, z: -80.1},
    {x: -72, y: 10, z: -92.1},
    {x: -72, y: -10, z: -92.1},
    {x: 72, y: 10, z: -92.1},
    {x: 72, y: -10, z: -92.1},
    {x: 90, y: 0, z: -80.1}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [6, 0, 1, [143, 143, 16]],
    [1, 7, 6, [143, 143, 16]],
    [4, 6, 7, [143, 143, 80]],
    [7, 3, 4, [143, 143, 80]],
    [8, 9, 10, [112, 48, 48]],
    [11, 12, 13, [112, 48, 48]],
    [5, 4, 0, [207, 143, 80]],
    [20, 19, 18, [223, 32, 32]],
    [1, 3, 2, [207, 143, 80]],
    [21, 22, 23, [223, 32, 32]],
    [2, 7, 1, [159, 159, 32]],
    [6, 5, 0, [159, 159, 32]],
    [5, 6, 4, [159, 159, 96]],
    [3, 7, 2, [159, 159, 96]],
    [4, 3, 1, [223, 159, 96]],
    [1, 0, 4, [223, 159, 96]],
    [17, 15, 14, [223, 32, 32]],
    [14, 16, 17, [223, 32, 32]]
  ];

  return {
    name: "gecko",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_hawk() {
  var modelPoints = [
    {x: -90, y: 30, z: 7},
    {x: -30, y: 60, z: 97},
    {x: -30, y: 30, z: 97},
    {x: 90, y: 30, z: 7},
    {x: 30, y: 30, z: 97},
    {x: 30, y: 60, z: 97},
    {x: -30, y: 30, z: 142},
    {x: 30, y: 30, z: 142},
    {x: -30, y: 30, z: -142},
    {x: 30, y: 30, z: -142},
    {x: 135, y: -60, z: -142},
    {x: 120, y: -15, z: -82},
    {x: -135, y: -60, z: -142},
    {x: -120, y: -15, z: -82},
    {x: -30, y: 60, z: -142},
    {x: 30, y: 60, z: -142}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 2, [32, 96, 96]],
    [3, 4, 5, [32, 96, 96]],
    [6, 7, 8, [96, 96, 96]],
    [7, 9, 8, [96, 96, 96]],
    [10, 9, 4, [32, 96, 96]],
    [11, 10, 4, [32, 96, 96]],
    [3, 11, 4, [32, 96, 96]],
    [2, 8, 12, [32, 96, 96]],
    [12, 13, 2, [32, 96, 96]],
    [2, 13, 0, [32, 96, 96]],
    [6, 2, 1, [32, 96, 223]],
    [5, 4, 7, [32, 96, 223]],
    [1, 5, 7, [96, 159, 159]],
    [7, 6, 1, [96, 159, 159]],
    [5, 1, 14, [96, 96, 96]],
    [14, 15, 5, [96, 96, 96]],
    [14, 13, 12, [96, 32, 96]],
    [15, 10, 11, [96, 32, 96]],
    [0, 13, 14, [32, 96, 159]],
    [15, 11, 3, [32, 96, 159]],
    [1, 0, 14, [96, 32, 159]],
    [5, 15, 3, [96, 32, 159]],
    [15, 14, 8, [223, 32, 32]],
    [8, 9, 15, [223, 32, 32]],
    [12, 8, 14, [32, 32, 96]],
    [15, 9, 10, [32, 32, 96]]
  ];

  return {
    name: "hawk",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_hognose() {
  var modelPoints = [
    {x: 0, y: 70, z: 95},
    {x: -120, y: -30, z: 95},
    {x: 0, y: -70, z: 175},
    {x: 120, y: -30, z: 95},
    {x: 0, y: -70, z: -175},
    {x: 15, y: -45, z: 155},
    {x: 75, y: -25, z: 115},
    {x: 15, y: 25, z: 115},
    {x: -15, y: 25, z: 115},
    {x: -75, y: -25, z: 115},
    {x: -15, y: -45, z: 155}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [2, 1, 0, [223, 96, 32]],
    [10, 9, 8, [223, 159, 32]],
    [0, 3, 2, [223, 96, 32]],
    [7, 6, 5, [223, 159, 32]],
    [0, 4, 3, [159, 96, 32]],
    [0, 1, 4, [96, 96, 32]],
    [4, 1, 2, [32, 96, 96]],
    [3, 4, 2, [96, 96, 96]]
  ];

  return {
    name: "hognose",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_krait() {
  var modelPoints = [
    {x: 0, y: 40, z: -100},
    {x: -100, y: 10, z: -30},
    {x: -100, y: -10, z: -30},
    {x: 0, y: -40, z: -100},
    {x: 100, y: -10, z: -30},
    {x: 100, y: 10, z: -30},
    {x: 0, y: 0, z: 100},
    {x: 0, y: 20, z: -100.1},
    {x: -60, y: 0, z: -58.1},
    {x: 0, y: -20, z: -100.1},
    {x: 60, y: 0, z: -58.1},
    {x: -100, y: 0, z: 100},
    {x: 100, y: 0, z: 100}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [5, 12, 4, [16, 80, 207]],
    [1, 2, 11, [32, 96, 223]],
    [4, 5, 0, [96, 96, 96]],
    [3, 4, 0, [96, 96, 96]],
    [2, 3, 0, [96, 96, 96]],
    [1, 2, 0, [96, 96, 96]],
    [7, 9, 10, [223, 32, 32]],
    [7, 8, 9, [223, 32, 32]],
    [0, 5, 6, [16, 80, 207]],
    [0, 6, 1, [32, 96, 223]],
    [5, 4, 6, [80, 80, 143]],
    [1, 6, 2, [80, 80, 143]],
    [6, 4, 3, [48, 112, 239]],
    [6, 3, 2, [32, 96, 223]],
    [5, 4, 12, [32, 96, 223]],
    [1, 11, 2, [16, 80, 207]]
  ];

  return {
    name: "krait",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_mamba() {
  var modelPoints = [
    {x: -110, y: -20, z: -110},
    {x: 0, y: -20, z: 110},
    {x: -60, y: 20, z: -110},
    {x: 60, y: 20, z: -110},
    {x: 110, y: -20, z: -110},
    {x: -11, y: -3.9, z: 22},
    {x: 11, y: -3.9, z: 22},
    {x: 5, y: 0.1, z: 0},
    {x: -5, y: 0.1, z: 0},
    {x: -60, y: 8, z: -110.1},
    {x: -60, y: -8, z: -110.1},
    {x: -76, y: -4, z: -110.1},
    {x: 60, y: -8, z: -110.1},
    {x: 60, y: 8, z: -110.1},
    {x: 76, y: -4, z: -110.1},
    {x: -28, y: 8, z: -110.1},
    {x: 28, y: 8, z: -110.1},
    {x: -28, y: -12, z: -110.1},
    {x: 28, y: -12, z: -110.1},
    {x: -20, y: -20.1, z: 0},
    {x: -40, y: -20.1, z: -70},
    {x: -30, y: -20.1, z: -70},
    {x: 30, y: -20.1, z: -70},
    {x: 20, y: -20.1, z: 0},
    {x: 40, y: -20.1, z: -70}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [2, 1, 0, [32, 159, 32]],
    [1, 2, 3, [32, 96, 32]],
    [7, 6, 5, [32, 223, 159]],
    [5, 8, 7, [32, 223, 159]],
    [3, 4, 1, [32, 159, 32]],
    [2, 0, 4, [32, 96, 96]],
    [4, 3, 2, [32, 96, 96]],
    [11, 10, 9, [223, 32, 32]],
    [14, 13, 12, [223, 32, 32]],
    [17, 16, 15, [223, 32, 32]],
    [18, 16, 17, [223, 32, 32]],
    [0, 1, 4, [32, 96, 32]],
    [20, 19, 21, [96, 32, 32]],
    [22, 23, 24, [96, 32, 32]]
  ];

  return {
    name: "mamba",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_moccasin() {
  var modelPoints = [
    {x: 75, y: -15, z: 45},
    {x: 30, y: 15, z: 45},
    {x: 0, y: 15, z: -105},
    {x: 90, y: -15, z: -105},
    {x: -30, y: 15, z: 45},
    {x: -75, y: -15, z: 45},
    {x: -90, y: -15, z: -105},
    {x: 0, y: -8, z: 105},
    {x: -6, y: -9, z: -105.1},
    {x: -15, y: 3, z: -105.1},
    {x: -33, y: -3, z: -105.1},
    {x: 18, y: 3, z: -105.1},
    {x: 9, y: -9, z: -105.1},
    {x: 33, y: -3, z: -105.1},
    {x: 10, y: 9, z: 61},
    {x: -10, y: 9, z: 61},
    {x: 0, y: -1, z: 87},
    {x: 3, y: 15.1, z: -54},
    {x: 18, y: 15.1, z: 33},
    {x: 3, y: 15.1, z: 33},
    {x: -18, y: 15.1, z: 33},
    {x: -3, y: 15.1, z: -54},
    {x: -3, y: 15.1, z: 33}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 2, [96, 159, 96]],
    [2, 3, 0, [159, 159, 96]],
    [2, 4, 5, [96, 159, 96]],
    [5, 6, 2, [159, 159, 96]],
    [3, 6, 5, [32, 159, 96]],
    [3, 5, 0, [32, 159, 96]],
    [1, 4, 2, [223, 159, 96]],
    [17, 18, 19, [159, 223, 96]],
    [20, 21, 22, [159, 223, 96]],
    [3, 2, 6, [96, 159, 96]],
    [8, 9, 10, [223, 32, 32]],
    [11, 12, 13, [223, 32, 32]],
    [1, 7, 4, [96, 159, 32]],
    [0, 7, 1, [159, 223, 159]],
    [4, 7, 5, [159, 223, 159]],
    [0, 5, 7, [96, 159, 96]],
    [16, 15, 14, [223, 96, 96]]
  ];

  return {
    name: "moccasin",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_moray() {
  var modelPoints = [
    {x: 0, y: -25, z: 85},
    {x: -110, y: -25, z: 25},
    {x: -60, y: 25, z: 25},
    {x: -30, y: -25, z: -85},
    {x: 60, y: 25, z: 25},
    {x: 110, y: -25, z: 25},
    {x: 30, y: -25, z: -85},
    {x: 0, y: -9, z: 66},
    {x: -20, y: 11, z: 42},
    {x: 20, y: 11, z: 42},
    {x: -25, y: -25.1, z: -65},
    {x: -10, y: -25.1, z: -85},
    {x: 10, y: -25.1, z: -85},
    {x: 25, y: -25.1, z: -65}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 2, [223, 159, 32]],
    [0, 2, 4, [159, 159, 96]],
    [7, 8, 9, [32, 159, 159]],
    [0, 4, 5, [223, 159, 32]],
    [2, 3, 4, [159, 96, 32]],
    [4, 3, 6, [159, 96, 32]],
    [4, 6, 5, [223, 96, 32]],
    [3, 2, 1, [223, 96, 32]],
    [3, 1, 0, [96, 96, 96]],
    [6, 3, 0, [32, 96, 96]],
    [6, 0, 5, [96, 96, 96]],
    [3, 10, 11, [223, 32, 32]],
    [12, 13, 6, [223, 32, 32]]
  ];

  return {
    name: "moray",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_python() {
  var modelPoints = [
    {x: 0, y: 0, z: 160},
    {x: -80, y: 0, z: -80},
    {x: 0, y: 50, z: -30},
    {x: 80, y: 0, z: -80},
    {x: 0, y: 50, z: -80},
    {x: 0, y: 30, z: -160},
    {x: 50, y: 0, z: -160},
    {x: -50, y: 0, z: -160},
    {x: 0, y: -50, z: -30},
    {x: 0, y: -50, z: -80},
    {x: 0, y: -30, z: -160},
    {x: 0, y: -10, z: -160.1},
    {x: 10, y: 0, z: -160.1},
    {x: 0, y: 10, z: -160.1},
    {x: -10, y: 0, z: -160.1}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 2, [96, 32, 159]],
    [0, 2, 3, [32, 32, 159]],
    [1, 4, 2, [32, 96, 159]],
    [2, 4, 3, [32, 96, 159]],
    [5, 4, 1, [96, 159, 159]],
    [3, 4, 5, [96, 159, 159]],
    [5, 6, 3, [159, 159, 159]],
    [1, 7, 5, [159, 159, 159]],
    [0, 3, 8, [96, 32, 159]],
    [0, 8, 1, [32, 32, 159]],
    [3, 9, 8, [32, 96, 159]],
    [8, 9, 1, [32, 96, 159]],
    [10, 9, 3, [96, 159, 159]],
    [1, 9, 10, [96, 159, 159]],
    [10, 7, 1, [159, 159, 159]],
    [3, 6, 10, [159, 159, 159]],
    [5, 7, 10, [96, 96, 96]],
    [5, 10, 6, [96, 96, 96]],
    [11, 12, 13, [223, 32, 32]],
    [13, 14, 11, [223, 32, 32]]
  ];

  return {
    name: "python",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_shuttle() {
  var modelPoints = [
    {x: -60, y: -60, z: -120},
    {x: -60, y: 60, z: -120},
    {x: 60, y: 60, z: -120},
    {x: 60, y: -60, z: -120},
    {x: 50, y: 0, z: 80},
    {x: 0, y: -50, z: 80},
    {x: 0, y: 50, z: 80},
    {x: -50, y: 0, z: 80},
    {x: 0, y: -20, z: 120},
    {x: -10, y: 30, z: 90},
    {x: -30, y: 10, z: 90},
    {x: -10, y: 0, z: 103},
    {x: 10, y: 0, z: 103},
    {x: 10, y: 30, z: 90},
    {x: 30, y: 10, z: 90},
    {x: 0, y: 20, z: -120.1},
    {x: -20, y: 0, z: -120.1},
    {x: 0, y: -20, z: -120.1},
    {x: 20, y: 0, z: -120.1}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [2, 1, 0, [96, 96, 96]],
    [2, 0, 3, [96, 96, 96]],
    [15, 16, 17, [223, 32, 32]],
    [17, 18, 15, [223, 32, 32]],
    [3, 4, 2, [96, 32, 32]],
    [3, 0, 5, [96, 32, 32]],
    [1, 2, 6, [96, 32, 32]],
    [1, 7, 0, [96, 32, 32]],
    [4, 6, 2, [159, 96, 32]],
    [6, 7, 1, [159, 96, 32]],
    [0, 7, 5, [159, 96, 32]],
    [5, 4, 3, [159, 96, 32]],
    [5, 7, 8, [32, 96, 96]],
    [8, 4, 5, [96, 96, 96]],
    [7, 6, 8, [96, 96, 96]],
    [4, 8, 6, [32, 96, 96]],
    [11, 10, 9, [159, 223, 159]],
    [12, 13, 14, [159, 223, 159]]
  ];

  return {
    name: "shuttle",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_sidewinder() {
  var modelPoints = [
    {x: 0, y: 25, z: -75},
    {x: 100, y: 0, z: -75},
    {x: 0, y: -25, z: -75},
    {x: -100, y: 0, z: -75},
    {x: -50, y: 0, z: 75},
    {x: 50, y: 0, z: 75},
    {x: -25, y: 15, z: -75.1},
    {x: 25, y: 15, z: -75.1},
    {x: -25, y: -15, z: -75.1},
    {x: 25, y: -15, z: -75.1}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 3, 2, [0, 0, 191]],
    [0, 2, 1, [0, 0, 191]],
    [6, 8, 9, [223, 32, 32]],
    [6, 9, 7, [223, 32, 32]],
    [0, 1, 5, [32, 96, 96]],
    [0, 5, 4, [48, 112, 112]],
    [0, 4, 3, [32, 96, 96]],
    [1, 2, 5, [32, 96, 96]],
    [5, 2, 4, [48, 112, 112]],
    [4, 2, 3, [32, 96, 96]]
  ];

  return {
    name: "sidewinder",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_thargoid() {
  var modelPoints = [
    {x: -60, y: -9, z: 25},
    {x: -25, y: -9, z: 60},
    {x: 25, y: -9, z: 60},
    {x: 60, y: -9, z: 25},
    {x: 60, y: -9, z: -25},
    {x: 25, y: -9, z: -60},
    {x: -25, y: -9, z: -60},
    {x: -60, y: -9, z: -25},
    {x: 36, y: 9, z: 14},
    {x: 16, y: 9, z: 36},
    {x: -14, y: 9, z: 36},
    {x: -36, y: 9, z: 15},
    {x: -36, y: 9, z: -15},
    {x: -15, y: 9, z: -36},
    {x: 15, y: 9, z: -36},
    {x: 36, y: 9, z: -15},
    {x: -27, y: -9.1, z: -25},
    {x: -23, y: -9.1, z: 25},
    {x: -19, y: -9.1, z: -25},
    {x: 19, y: -9.1, z: -25},
    {x: 23, y: -9.1, z: 25},
    {x: 27, y: -9.1, z: -25}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 2, [32, 32, 96]],
    [0, 2, 3, [32, 32, 96]],
    [0, 3, 4, [32, 32, 96]],
    [0, 4, 5, [32, 32, 96]],
    [0, 5, 6, [32, 32, 96]],
    [0, 6, 7, [32, 32, 96]],
    [16, 17, 18, [96, 32, 32]],
    [19, 20, 21, [96, 32, 32]],
    [8, 9, 10, [32, 32, 96]],
    [8, 10, 11, [32, 32, 96]],
    [8, 11, 12, [32, 32, 96]],
    [8, 12, 13, [32, 32, 96]],
    [8, 13, 14, [32, 32, 96]],
    [8, 14, 15, [32, 32, 96]],
    [1, 0, 11, [159, 32, 96]],
    [1, 11, 10, [159, 32, 96]],
    [2, 1, 10, [223, 32, 96]],
    [2, 10, 9, [223, 32, 96]],
    [3, 2, 9, [159, 32, 96]],
    [3, 9, 8, [159, 32, 96]],
    [8, 15, 3, [223, 32, 96]],
    [3, 15, 4, [223, 32, 96]],
    [4, 15, 14, [96, 32, 96]],
    [14, 5, 4, [96, 32, 96]],
    [5, 14, 13, [159, 32, 96]],
    [13, 6, 5, [159, 32, 96]],
    [6, 13, 12, [96, 32, 96]],
    [12, 7, 6, [96, 32, 96]],
    [11, 0, 7, [223, 32, 96]],
    [12, 11, 7, [223, 32, 96]]
  ];

  return {
    name: "thargoid",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_thargon() {
  var modelPoints = [
    {x: 0, y: -20, z: -75},
    {x: -70, y: -20, z: -35},
    {x: -30, y: -20, z: 75},
    {x: 30, y: -20, z: 75},
    {x: 70, y: -20, z: -35},
    {x: 0, y: 20, z: -45},
    {x: -20, y: 20, z: -35},
    {x: -10, y: 20, z: -15},
    {x: 10, y: 20, z: -15},
    {x: 20, y: 20, z: -35}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 2, [223, 32, 32]],
    [0, 2, 3, [32, 96, 96]],
    [0, 3, 4, [223, 32, 32]],
    [7, 6, 5, [223, 32, 32]],
    [8, 7, 5, [32, 96, 96]],
    [8, 5, 9, [223, 32, 32]],
    [5, 0, 4, [96, 96, 223]],
    [4, 9, 5, [96, 96, 223]],
    [3, 9, 4, [159, 96, 223]],
    [3, 8, 9, [159, 96, 223]],
    [8, 3, 2, [223, 96, 223]],
    [2, 7, 8, [223, 96, 223]],
    [2, 1, 6, [159, 96, 223]],
    [2, 6, 7, [159, 96, 223]],
    [6, 1, 0, [96, 96, 223]],
    [6, 0, 5, [96, 96, 223]]
  ];

  return {
    name: "thargon",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_transporter() {
  var modelPoints = [
    {x: -100, y: -25, z: 60},
    {x: -100, y: -25, z: -120},
    {x: 100, y: -25, z: -120},
    {x: 100, y: -25, z: 60},
    {x: -30, y: -25, z: 120},
    {x: 30, y: -25, z: 120},
    {x: 100, y: 5, z: -120},
    {x: -100, y: 5, z: -120},
    {x: 0, y: 25, z: -120},
    {x: 100, y: 5, z: 60},
    {x: -100, y: 5, z: 60},
    {x: 0, y: 25, z: 60},
    {x: -30, y: 5, z: 120},
    {x: 30, y: 5, z: 120},
    {x: -50, y: -15, z: -120.1},
    {x: 30, y: 19.1, z: -10},
    {x: 70, y: 11.1, z: -10},
    {x: 50, y: 15.1, z: 20},
    {x: 30, y: 19.1, z: -90},
    {x: 70, y: 11.1, z: -90},
    {x: 50, y: 15.1, z: -60},
    {x: -80, y: 9.1, z: -10},
    {x: -30, y: 19.1, z: -10},
    {x: -30, y: 19.1, z: 4},
    {x: -80, y: 9.1, z: 4},
    {x: -70, y: 11.1, z: -60},
    {x: -50, y: 15.1, z: -60},
    {x: -50, y: 15.1, z: -90},
    {x: -30, y: 19.1, z: -60},
    {x: 50, y: 15.1, z: -10},
    {x: -50, y: -25.1, z: 20},
    {x: -60, y: -25.1, z: -60},
    {x: -40, y: -25.1, z: -60},
    {x: 50, y: -25.1, z: 20},
    {x: 40, y: -25.1, z: -60},
    {x: 60, y: -25.1, z: -60},
    {x: -50, y: 5, z: -120.1},
    {x: 40, y: 5, z: -120.1},
    {x: 40, y: -15, z: -120.1}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 3, 2, [32, 32, 96]],
    [0, 4, 5, [32, 32, 96]],
    [3, 0, 5, [32, 32, 96]],
    [2, 1, 0, [32, 32, 96]],
    [32, 31, 30, [32, 223, 159]],
    [35, 34, 33, [32, 223, 159]],
    [2, 6, 7, [96, 96, 96]],
    [7, 1, 2, [96, 96, 96]],
    [6, 8, 7, [32, 96, 96]],
    [37, 36, 14, [223, 32, 32]],
    [14, 38, 37, [223, 32, 32]],
    [6, 2, 3, [96, 159, 159]],
    [6, 3, 9, [96, 159, 159]],
    [10, 1, 7, [96, 159, 159]],
    [10, 0, 1, [96, 159, 159]],
    [8, 11, 10, [32, 32, 223]],
    [10, 7, 8, [32, 32, 223]],
    [21, 22, 23, [96, 32, 32]],
    [23, 24, 21, [96, 32, 32]],
    [27, 26, 25, [32, 159, 159]],
    [27, 28, 26, [96, 223, 159]],
    [11, 8, 6, [32, 96, 223]],
    [6, 9, 11, [32, 96, 223]],
    [18, 19, 20, [159, 96, 96]],
    [29, 17, 15, [223, 223, 96]],
    [16, 17, 29, [32, 223, 96]],
    [11, 12, 10, [32, 32, 159]],
    [12, 11, 13, [32, 96, 223]],
    [13, 11, 9, [32, 32, 159]],
    [9, 3, 5, [32, 159, 159]],
    [5, 13, 9, [32, 159, 159]],
    [13, 5, 4, [32, 159, 223]],
    [4, 12, 13, [32, 159, 223]],
    [4, 10, 12, [32, 159, 159]],
    [4, 0, 10, [32, 159, 159]]
  ];

  return {
    name: "transporter",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_urutu() {
  var modelPoints = [
    {x: 75, y: -27, z: 45},
    {x: 30, y: 3, z: 45},
    {x: 0, y: 27, z: -105},
    {x: 170, y: -22, z: -105},
    {x: -30, y: 3, z: 45},
    {x: -75, y: -27, z: 45},
    {x: -170, y: -22, z: -105},
    {x: 0, y: -20, z: 105},
    {x: -6, y: -21, z: -105.1},
    {x: -15, y: 11, z: -105.1},
    {x: -70, y: -15, z: -105.1},
    {x: 18, y: 11, z: -105.1},
    {x: 9, y: -21, z: -105.1},
    {x: 70, y: -15, z: -105.1},
    {x: 0, y: 0, z: 53},
    {x: -9, y: -10, z: 79},
    {x: 8, y: -10, z: 79}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 2, [96, 159, 96]],
    [2, 3, 0, [159, 159, 96]],
    [2, 4, 5, [96, 159, 96]],
    [5, 6, 2, [159, 159, 96]],
    [3, 6, 5, [32, 159, 96]],
    [3, 5, 0, [32, 159, 96]],
    [1, 4, 2, [223, 159, 96]],
    [3, 2, 6, [96, 96, 96]],
    [8, 9, 10, [223, 32, 32]],
    [1, 7, 4, [96, 159, 32]],
    [0, 7, 1, [159, 223, 159]],
    [4, 7, 5, [159, 223, 159]],
    [0, 5, 7, [96, 159, 96]],
    [11, 12, 13, [223, 32, 32]],
    [16, 15, 14, [32, 223, 32]]
  ];

  return {
    name: "urutu",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_viper() {
  var modelPoints = [
    {x: 0, y: 30, z: 0},
    {x: -45, y: 30, z: -100},
    {x: 45, y: 30, z: -100},
    {x: 45, y: -30, z: -100},
    {x: 0, y: -30, z: 0},
    {x: -45, y: -30, z: -100},
    {x: -80, y: 0, z: -100},
    {x: 80, y: 0, z: -100},
    {x: 0, y: 0, z: 100},
    {x: -10, y: -15, z: -100.1},
    {x: -10, y: 15, z: -100.1},
    {x: -40, y: 0, z: -100.1},
    {x: 10, y: 15, z: -100.1},
    {x: 10, y: -15, z: -100.1},
    {x: 40, y: 0, z: -100.1}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 2, [159, 32, 32]],
    [5, 4, 3, [159, 32, 32]],
    [1, 6, 5, [32, 96, 96]],
    [7, 2, 3, [32, 96, 96]],
    [3, 1, 5, [96, 96, 96]],
    [2, 1, 3, [96, 96, 96]],
    [9, 10, 11, [223, 32, 32]],
    [12, 13, 14, [223, 32, 32]],
    [8, 0, 2, [96, 32, 32]],
    [2, 7, 8, [32, 96, 32]],
    [1, 0, 8, [96, 32, 32]],
    [8, 6, 1, [32, 96, 32]],
    [5, 8, 4, [96, 32, 32]],
    [8, 5, 6, [96, 96, 32]],
    [4, 8, 3, [96, 32, 32]],
    [3, 8, 7, [96, 96, 32]]
  ];

  return {
    name: "viper",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_worm() {
  var modelPoints = [
    {x: 75, y: 54, z: -150},
    {x: 36, y: -18, z: 111},
    {x: -36, y: -18, z: 111},
    {x: -75, y: 54, z: -150},
    {x: 36, y: -54, z: 150},
    {x: -36, y: -54, z: 150},
    {x: 111, y: -54, z: -150},
    {x: 60, y: -54, z: 111},
    {x: -60, y: -54, z: 111},
    {x: -111, y: -54, z: -150},
    {x: 15, y: -18, z: 111},
    {x: 0, y: -48, z: 144},
    {x: -15, y: -18, z: 111},
    {x: 60, y: 33, z: -150.1},
    {x: -60, y: 33, z: -150.1},
    {x: 66, y: 18, z: -150.1},
    {x: -66, y: 18, z: -150.1}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 2, [223, 159, 159]],
    [2, 3, 0, [223, 159, 159]],
    [1, 4, 2, [223, 96, 96]],
    [4, 5, 2, [223, 96, 96]],
    [0, 6, 7, [159, 159, 159]],
    [7, 1, 0, [159, 159, 159]],
    [4, 1, 7, [159, 96, 96]],
    [2, 8, 3, [159, 159, 159]],
    [5, 8, 2, [159, 96, 96]],
    [6, 3, 9, [96, 96, 96]],
    [6, 0, 3, [96, 96, 96]],
    [13, 14, 15, [223, 32, 32]],
    [14, 16, 15, [223, 32, 32]],
    [8, 9, 3, [159, 159, 159]],
    [6, 9, 8, [32, 96, 96]],
    [8, 7, 6, [32, 96, 96]],
    [8, 5, 7, [32, 96, 96]],
    [5, 4, 7, [32, 96, 96]],
    [10, 1, 11, [32, 159, 159]],
    [11, 2, 12, [32, 159, 159]]
  ];

  return {
    name: "worm",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}

//#############################################################################

function make_bushmaster() {
  var modelPoints = [
    {x: 0, y: 0, z: 60},
    {x: 50, y: 0, z: 20},
    {x: -50, y: 0, z: 20},
    {x: 0, y: 20, z: 0},
    {x: 0, y: -20, z: -40},
    {x: 0, y: 14, z: -40},
    {x: 40, y: 0, z: -40},
    {x: -40, y: 0, z: -40},
    {x: 0, y: 4, z: -40},
    {x: 10, y: 0, z: -40},
    {x: 0, y: -4, z: -40},
    {x: -10, y: 0, z: -40}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 4, [190, 190, 190]],
    [0, 1, 3, [190, 190, 190]],
    [0, 2, 4, [190, 190, 190]],
    [0, 2, 3, [190, 190, 190]],
    [1, 3, 5, 6, [190, 190, 190]],
    [1, 4, 6, [190, 190, 190]],
    [2, 3, 5, 7, [190, 190, 190]],
    [2, 4, 7, [190, 190, 190]],
    [4, 6, 5, 7, [190, 190, 190]]
  ];

  return {
    name: "bushmaster",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_chameleon() {
  var modelPoints = [
    {x: -18, y: 0, z: 110},
    {x: 18, y: 0, z: 110},
    {x: -40, y: 0, z: 0},
    {x: -8, y: 24, z: 0},
    {x: 8, y: 24, z: 0},
    {x: 40, y: 0, z: 0},
    {x: 8, y: -24, z: 0},
    {x: -8, y: -24, z: 0},
    {x: 0, y: 24, z: 40},
    {x: 0, y: -24, z: 40},
    {x: -32, y: 0, z: -40},
    {x: 0, y: 24, z: -40},
    {x: 32, y: 0, z: -40},
    {x: 0, y: -24, z: -40},
    {x: -8, y: 0, z: -40},
    {x: 0, y: 8, z: -40},
    {x: 8, y: 0, z: -40},
    {x: 0, y: -8, z: -40}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 9, [190, 190, 190]],
    [0, 1, 8, [190, 190, 190]],
    [0, 2, 7, 9, [190, 190, 190]],
    [0, 2, 3, 8, [190, 190, 190]],
    [1, 5, 6, 9, [190, 190, 190]],
    [1, 5, 4, 8, [190, 190, 190]],
    [2, 3, 11, 10, [190, 190, 190]],
    [2, 7, 13, 10, [190, 190, 190]],
    [3, 8, 4, 11, [190, 190, 190]],
    [4, 5, 12, 11, [190, 190, 190]],
    [5, 6, 13, 12, [190, 190, 190]],
    [6, 9, 7, 13, [190, 190, 190]],
    [10, 11, 12, 13, [190, 190, 190]]
  ];

  return {
    name: "chameleon",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_ghavial() {
  var modelPoints = [
    {x: 30, y: 0, z: 100},
    {x: -30, y: 0, z: 100},
    {x: 40, y: 30, z: -26},
    {x: -40, y: 30, z: -26},
    {x: 60, y: 0, z: -20},
    {x: 40, y: 0, z: -60},
    {x: -60, y: 0, z: -20},
    {x: -40, y: 0, z: -60},
    {x: 0, y: -30, z: -20},
    {x: 10, y: 24, z: 0},
    {x: -10, y: 24, z: 0},
    {x: 0, y: 22, z: 10}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 2, 4, [190, 190, 190]],
    [0, 2, 3, 1, [190, 190, 190]],
    [0, 4, 8, [190, 190, 190]],
    [0, 8, 1, [190, 190, 190]],
    [1, 8, 6, [190, 190, 190]],
    [3, 1, 6, [190, 190, 190]],
    [3, 2, 5, 7, [190, 190, 190]],
    [4, 2, 5, [190, 190, 190]],
    [4, 5, 8, [190, 190, 190]],
    [5, 7, 8, [190, 190, 190]],
    [6, 3, 7, [190, 190, 190]],
    [6, 8, 7, [190, 190, 190]]
  ];

  return {
    name: "ghavial",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_iguana() {
  var modelPoints = [
    {x: 0, y: 0, z: 90},
    {x: 0, y: 20, z: 30},
    {x: -40, y: 0, z: 10},
    {x: 0, y: -20, z: 30},
    {x: 40, y: 0, z: 10},
    {x: 0, y: 20, z: -40},
    {x: -40, y: 0, z: -30},
    {x: 0, y: -20, z: -40},
    {x: 40, y: 0, z: -30},
    {x: -40, y: 0, z: 40},
    {x: 40, y: 0, z: 40},
    {x: 0, y: 8, z: -40},
    {x: -16, y: 0, z: -36},
    {x: 0, y: -8, z: -40},
    {x: 16, y: 0, z: -36}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 4, [190, 190, 190]],
    [0, 1, 2, [190, 190, 190]],
    [0, 2, 3, [190, 190, 190]],
    [0, 3, 4, [190, 190, 190]],
    [1, 2, 6, 5, [190, 190, 190]],
    [1, 4, 8, 5, [190, 190, 190]],
    [2, 3, 7, 6, [190, 190, 190]],
    [3, 4, 8, 7, [190, 190, 190]],
    [5, 6, 7, [190, 190, 190]],
    [5, 7, 8, [190, 190, 190]]
  ];

  return {
    name: "iguana",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_monitor() {
  var modelPoints = [
    {x: 0, y: 10, z: 140},
    {x: 20, y: 40, z: -20},
    {x: -20, y: 40, z: -20},
    {x: 50, y: 0, z: 10},
    {x: -50, y: 0, z: 10},
    {x: 30, y: 4, z: -60},
    {x: -30, y: 4, z: -60},
    {x: 18, y: 20, z: -60},
    {x: -18, y: 20, z: -60},
    {x: 0, y: -20, z: -60},
    {x: 0, y: -40, z: 10},
    {x: 0, y: 34, z: 10},
    {x: 0, y: 26, z: 50},
    {x: 20, y: -10, z: 60},
    {x: 10, y: 0, z: 100},
    {x: -20, y: -10, z: 60},
    {x: -10, y: 0, z: 100}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 3, [190, 190, 190]],
    [0, 1, 2, [190, 190, 190]],
    [0, 2, 4, [190, 190, 190]],
    [0, 3, 10, [190, 190, 190]],
    [0, 10, 4, [190, 190, 190]],
    [1, 2, 8, 7, [190, 190, 190]],
    [1, 3, 5, 7, [190, 190, 190]],
    [2, 4, 6, 8, [190, 190, 190]],
    [3, 5, 9, 10, [190, 190, 190]],
    [4, 10, 9, 6, [190, 190, 190]],
    [5, 9, 6, 8, 7, [190, 190, 190]]
  ];

  return {
    name: "monitor",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_ophidian() {
  var modelPoints = [
    {x: -20, y: 0, z: 70},
    {x: 20, y: 0, z: 70},
    {x: 0, y: 10, z: 40},
    {x: -30, y: 0, z: 30},
    {x: 30, y: 0, z: 30},
    {x: 0, y: 16, z: 10},
    {x: 20, y: 10, z: -50},
    {x: -20, y: 10, z: -50},
    {x: -30, y: 0, z: -50},
    {x: -40, y: 0, z: -50},
    {x: -30, y: 0, z: -30},
    {x: 30, y: 0, z: -50},
    {x: 40, y: 0, z: -50},
    {x: 30, y: 0, z: -30},
    {x: 0, y: -10, z: -50},
    {x: 0, y: -16, z: 20},
    {x: 10, y: 4, z: -50},
    {x: 10, y: -2, z: -50},
    {x: -10, y: -2, z: -50},
    {x: -10, y: 4, z: -50}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 15, [190, 190, 190]],
    [0, 1, 2, [190, 190, 190]],
    [0, 2, 5, 3, [190, 190, 190]],
    [0, 3, 15, [190, 190, 190]],
    [1, 2, 5, 4, [190, 190, 190]],
    [1, 4, 15, [190, 190, 190]],
    [3, 5, 7, 8, [190, 190, 190]],
    [8, 9, 10, [190, 190, 190]],
    [3, 15, 14, 8, [190, 190, 190]],
    [4, 5, 6, 11, [190, 190, 190]],
    [11, 12, 13, [190, 190, 190]],
    [4, 15, 14, 11, [190, 190, 190]],
    [5, 6, 7, [190, 190, 190]],
    [6, 7, 8, 14, 11, [190, 190, 190]]
  ];

  return {
    name: "ophidian",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_salamander() {
  var modelPoints = [
    {x: 0, y: 0, z: 60},
    {x: 40, y: 0, z: 40},
    {x: -40, y: 0, z: 40},
    {x: 60, y: 0, z: 0},
    {x: -60, y: 0, z: 0},
    {x: 70, y: 0, z: -40},
    {x: -70, y: 0, z: -40},
    {x: 0, y: 20, z: -40},
    {x: 0, y: -20, z: -40},
    {x: -10, y: 6, z: -40},
    {x: -10, y: -6, z: -40},
    {x: -20, y: 0, z: -40},
    {x: 10, y: 6, z: -40},
    {x: 10, y: -6, z: -40},
    {x: 20, y: 0, z: -40}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 8, [190, 190, 190]],
    [0, 1, 7, [190, 190, 190]],
    [0, 2, 8, [190, 190, 190]],
    [0, 2, 7, [190, 190, 190]],
    [1, 3, 8, [190, 190, 190]],
    [1, 3, 7, [190, 190, 190]],
    [2, 4, 8, [190, 190, 190]],
    [2, 4, 7, [190, 190, 190]],
    [3, 5, 8, [190, 190, 190]],
    [3, 5, 7, [190, 190, 190]],
    [4, 6, 8, [190, 190, 190]],
    [4, 6, 7, [190, 190, 190]],
    [5, 7, 6, 8, [190, 190, 190]]
  ];

  return {
    name: "salamander",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
//#############################################################################

function make_shuttlev() {
  var modelPoints = [
    {x: 0, y: 0, z: 40},
    {x: 0, y: 20, z: 30},
    {x: -20, y: 0, z: 30},
    {x: 0, y: -20, z: 30},
    {x: 20, y: 0, z: 30},
    {x: -20, y: 20, z: 20},
    {x: -20, y: -20, z: 20},
    {x: 20, y: -20, z: 20},
    {x: 20, y: 20, z: 20},
    {x: 0, y: 20, z: -40},
    {x: -20, y: 0, z: -40},
    {x: 0, y: -20, z: -40},
    {x: 20, y: 0, z: -40},
    {x: -4, y: 4, z: -40},
    {x: -4, y: -4, z: -40},
    {x: 4, y: -4, z: -40},
    {x: 4, y: 4, z: -40}
  ];

  var rotatedPoints = [];
  for(var i = 0; i < modelPoints.length; i++)
    rotatedPoints.push({x: modelPoints[i].x, y: modelPoints[i].y, z: modelPoints[i].z});

  var polygons = [
    [0, 1, 5, 2, [190, 190, 190]],
    [0, 1, 8, 4, [190, 190, 190]],
    [0, 2, 6, 3, [190, 190, 190]],
    [0, 3, 7, 4, [190, 190, 190]],
    [1, 5, 9, 8, [190, 190, 190]],
    [2, 5, 10, 6, [190, 190, 190]],
    [3, 6, 11, 7, [190, 190, 190]],
    [4, 7, 12, 8, [190, 190, 190]],
    [5, 9, 10, [190, 190, 190]],
    [6, 10, 11, [190, 190, 190]],
    [7, 11, 12, [190, 190, 190]],
    [8, 9, 12, [190, 190, 190]],
    [9, 10, 11, 12, [190, 190, 190]]
  ];

  return {
    name: "shuttlev",
    modelPoints: modelPoints,
    rotatedPoints: rotatedPoints,
    polygons: polygons
  };
}
            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.
Loading ..................

Console