title: How to use Matrix3D.appendTranslation()?
body: <p>With stage 3d I set up a basic triangle, and I can use append rotation and append scale and everything works, but using append translation on the z axis, the triangle will dissapear with the translation being 1 or higher. With other shapes it would dissapear with only 3 or higher. And it doesn't look like the triangle is getting any smaller/farther away between 0 and 0.9 translation. The translation on the x and y axis do work though.</p>
  
  <p>Here are my shader codes:</p>
  
  <pre><code>private static const VERTEX_SHADER_SOURCE:String = "m44 op, va0, vc1";
  private static const FRAGMENT_SHADER_SOURCE:String = "mov oc, fc0";
  </code></pre>
  
  <p>my render loop:</p>
  
  <pre><code>addEventListener(Event.ENTER_FRAME, enter);
  var t:Number=0;
  function enter():void {
      context3D.clear();
      context3D.setProgram(program);
  
      var m:Matrix3D = new Matrix3D;
  
      m.appendTranslation(0, 0, t);
  
      t+=0.01;
  
      context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 1, m, true);
      context3D.setVertexBufferAt(0, buffer, 0, Context3DVertexBufferFormat.FLOAT_3);
      context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, color);
  
      context3D.drawTriangles(indexBuffer);
      context3D.present();
  }
  </code></pre>
  
  <p>my full code:</p>
  
  <pre><code>var assembler:AGALMiniAssembler = new AGALMiniAssembler();
  assembler.assemble(Context3DProgramType.VERTEX, VERTEX_SHADER_SOURCE);
  
  if (assembler.error) {
      trace("vertex shader error " +assembler.error); 
      return; 
  }
  var vertexShaderByteCode:ByteArray = assembler.agalcode;
  assembler.assemble(Context3DProgramType.FRAGMENT, FRAGMENT_SHADER_SOURCE);
  
  if (assembler.error) {
      trace("fragment shader error " + assembler.error); 
      return; 
  }
  var fragmentShaderByteCode:ByteArray = assembler.agalcode;
  var program:Program3D = context3D.createProgram();
  
  try {
      program.upload(vertexShaderByteCode, fragmentShaderByteCode); 
  }
  catch (err:Error) {
      trace("couldnt upload shader program" + err); 
      return; 
  }
  
  color = new &lt;Number&gt;[0.9296875, 0.9140625, 0.84765625, 1];
  var verts:Vector.&lt;Number&gt; = Vector.&lt;Number&gt;([
      0.5, 0, 0,
      -0.5, 0, 0,
      0, 0.5, 0
  ]);
  
  var buffer:VertexBuffer3D = context3D.createVertexBuffer(3, 3);
  buffer.uploadFromVector(verts, 0, 3);
  
  var indices:Vector.&lt;uint&gt; = Vector.&lt;uint&gt;([0, 1, 2])
  var indexBuffer:IndexBuffer3D = context3D.createIndexBuffer(3);
  
  indexBuffer.uploadFromVector(indices, 0, 3);    
  addEventListener(Event.ENTER_FRAME, enter);
  var t:Number=0;
  
  function enter():void {
  
      context3D.clear();
      context3D.setProgram(program);
      var m:Matrix3D = new Matrix3D;
  
      m.appendTranslation(0, 0, t);
      t+=0.01;
  
      context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 1, m, true);
      context3D.setVertexBufferAt(0, buffer, 0, Context3DVertexBufferFormat.FLOAT_3);
      context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, color);
  
      context3D.drawTriangles(indexBuffer);
      context3D.present();
  }
  </code></pre>