Ejemplo n.º 1
0
  /**
   * The method applies bone's current position to all of the traces of the given animations.
   *
   * @param boneContext the bone context
   * @param space the bone's evaluation space
   * @param referenceAnimData the object containing the animations
   */
  protected void applyAnimData(BoneContext boneContext, Space space, AnimData referenceAnimData) {
    ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class);
    Transform transform = constraintHelper.getBoneTransform(space, boneContext.getBone());

    AnimData animData = blenderContext.getAnimData(boneContext.getBoneOma());

    for (Animation animation : referenceAnimData.anims) {
      BoneTrack parentTrack = (BoneTrack) animation.getTracks()[0];

      float[] times = parentTrack.getTimes();
      Vector3f[] translations = new Vector3f[times.length];
      Quaternion[] rotations = new Quaternion[times.length];
      Vector3f[] scales = new Vector3f[times.length];
      Arrays.fill(translations, transform.getTranslation());
      Arrays.fill(rotations, transform.getRotation());
      Arrays.fill(scales, transform.getScale());
      for (Animation anim : animData.anims) {
        anim.addTrack(
            new BoneTrack(
                animData.skeleton.getBoneIndex(boneContext.getBone()),
                times,
                translations,
                rotations,
                scales));
      }
    }
    blenderContext.setAnimData(boneContext.getBoneOma(), animData);
  }
Ejemplo n.º 2
0
 @Override
 public Transform clone() {
   try {
     Transform tq = (Transform) super.clone();
     tq.rot = rot.clone();
     tq.scale = scale.clone();
     tq.translation = translation.clone();
     return tq;
   } catch (CloneNotSupportedException e) {
     throw new AssertionError();
   }
 }
Ejemplo n.º 3
0
 /** Should only be called from updateGeometricState(). In most cases should not be subclassed. */
 protected void updateWorldTransforms() {
   if (parent == null) {
     worldTransform.set(localTransform);
     refreshFlags &= ~RF_TRANSFORM;
   } else {
     // check if transform for parent is updated
     assert ((parent.refreshFlags & RF_TRANSFORM) == 0);
     worldTransform.set(localTransform);
     worldTransform.combineWithParent(parent.worldTransform);
     refreshFlags &= ~RF_TRANSFORM;
   }
 }
Ejemplo n.º 4
0
  /**
   * @return A clone of this Spatial, the scene graph in its entirety is cloned and can be altered
   *     independently of the original scene graph.
   *     <p>Note that meshes of geometries are not cloned explicitly, they are shared if static, or
   *     specially cloned if animated.
   *     <p>All controls will be cloned using the Control.cloneForSpatial method on the clone.
   * @see Mesh#cloneForAnim()
   */
  public Spatial clone(boolean cloneMaterial) {
    try {
      Spatial clone = (Spatial) super.clone();
      if (worldBound != null) {
        clone.worldBound = worldBound.clone();
      }
      clone.worldLights = worldLights.clone();
      clone.localLights = localLights.clone();

      // Set the new owner of the light lists
      clone.localLights.setOwner(clone);
      clone.worldLights.setOwner(clone);

      // No need to force cloned to update.
      // This node already has the refresh flags
      // set below so it will have to update anyway.
      clone.worldTransform = worldTransform.clone();
      clone.localTransform = localTransform.clone();

      if (clone instanceof Node) {
        Node node = (Node) this;
        Node nodeClone = (Node) clone;
        nodeClone.children = new SafeArrayList<Spatial>(Spatial.class);
        for (Spatial child : node.children) {
          Spatial childClone = child.clone(cloneMaterial);
          childClone.parent = nodeClone;
          nodeClone.children.add(childClone);
        }
      }

      clone.parent = null;
      clone.setBoundRefresh();
      clone.setTransformRefresh();
      clone.setLightListRefresh();

      clone.controls = new SafeArrayList<Control>(Control.class);
      for (int i = 0; i < controls.size(); i++) {
        Control newControl = controls.get(i).cloneForSpatial(clone);
        newControl.setSpatial(clone);
        clone.controls.add(newControl);
      }

      if (userData != null) {
        clone.userData = (HashMap<String, Savable>) userData.clone();
      }

      return clone;
    } catch (CloneNotSupportedException ex) {
      throw new AssertionError();
    }
  }
Ejemplo n.º 5
0
  public static void convertToFixed(Geometry geom, Format posFmt, Format nmFmt, Format tcFmt) {
    geom.updateModelBound();
    BoundingBox bbox = (BoundingBox) geom.getModelBound();
    Mesh mesh = geom.getMesh();

    VertexBuffer positions = mesh.getBuffer(Type.Position);
    VertexBuffer normals = mesh.getBuffer(Type.Normal);
    VertexBuffer texcoords = mesh.getBuffer(Type.TexCoord);
    VertexBuffer indices = mesh.getBuffer(Type.Index);

    // positions
    FloatBuffer fb = (FloatBuffer) positions.getData();
    if (posFmt != Format.Float) {
      Buffer newBuf =
          VertexBuffer.createBuffer(posFmt, positions.getNumComponents(), mesh.getVertexCount());
      Transform t = convertPositions(fb, bbox, newBuf);
      t.combineWithParent(geom.getLocalTransform());
      geom.setLocalTransform(t);

      VertexBuffer newPosVb = new VertexBuffer(Type.Position);
      newPosVb.setupData(positions.getUsage(), positions.getNumComponents(), posFmt, newBuf);
      mesh.clearBuffer(Type.Position);
      mesh.setBuffer(newPosVb);
    }

    // normals, automatically convert to signed byte
    fb = (FloatBuffer) normals.getData();

    ByteBuffer bb = BufferUtils.createByteBuffer(fb.capacity());
    convertNormals(fb, bb);

    normals = new VertexBuffer(Type.Normal);
    normals.setupData(Usage.Static, 3, Format.Byte, bb);
    normals.setNormalized(true);
    mesh.clearBuffer(Type.Normal);
    mesh.setBuffer(normals);

    // texcoords
    fb = (FloatBuffer) texcoords.getData();
    if (tcFmt != Format.Float) {
      Buffer newBuf =
          VertexBuffer.createBuffer(tcFmt, texcoords.getNumComponents(), mesh.getVertexCount());
      convertTexCoords2D(fb, newBuf);

      VertexBuffer newTcVb = new VertexBuffer(Type.TexCoord);
      newTcVb.setupData(texcoords.getUsage(), texcoords.getNumComponents(), tcFmt, newBuf);
      mesh.clearBuffer(Type.TexCoord);
      mesh.setBuffer(newTcVb);
    }
  }
Ejemplo n.º 6
0
  /**
   * <code>rotateUpTo</code> is a utility function that alters the local rotation to point the Y
   * axis in the direction given by newUp.
   *
   * @param newUp the up vector to use - assumed to be a unit vector.
   */
  public void rotateUpTo(Vector3f newUp) {
    TempVars vars = TempVars.get();

    Vector3f compVecA = vars.vect1;
    Quaternion q = vars.quat1;

    // First figure out the current up vector.
    Vector3f upY = compVecA.set(Vector3f.UNIT_Y);
    Quaternion rot = localTransform.getRotation();
    rot.multLocal(upY);

    // get angle between vectors
    float angle = upY.angleBetween(newUp);

    // figure out rotation axis by taking cross product
    Vector3f rotAxis = upY.crossLocal(newUp).normalizeLocal();

    // Build a rotation quat and apply current local rotation.
    q.fromAngleNormalAxis(angle, rotAxis);
    q.mult(rot, rot);

    vars.release();

    setTransformRefresh();
  }
Ejemplo n.º 7
0
  /**
   * Compute bounds from an array of points
   *
   * @param pts
   * @param transform
   * @return
   */
  public static BoundingBox computeBoundForPoints(Vector3f[] pts, Transform transform) {
    Vector3f min = new Vector3f(Vector3f.POSITIVE_INFINITY);
    Vector3f max = new Vector3f(Vector3f.NEGATIVE_INFINITY);
    Vector3f temp = new Vector3f();
    for (int i = 0; i < pts.length; i++) {
      transform.transformVector(pts[i], temp);

      min.minLocal(temp);
      max.maxLocal(temp);
    }
    Vector3f center = min.add(max).multLocal(0.5f);
    Vector3f extent = max.subtract(min).multLocal(0.5f);
    return new BoundingBox(center, extent.x, extent.y, extent.z);
  }
Ejemplo n.º 8
0
  /** Computes the world transform of this Spatial in the most efficient manner possible. */
  void checkDoTransformUpdate() {
    if ((refreshFlags & RF_TRANSFORM) == 0) {
      return;
    }

    if (parent == null) {
      worldTransform.set(localTransform);
      refreshFlags &= ~RF_TRANSFORM;
    } else {
      TempVars vars = TempVars.get();

      Spatial[] stack = vars.spatialStack;
      Spatial rootNode = this;
      int i = 0;
      while (true) {
        Spatial hisParent = rootNode.parent;
        if (hisParent == null) {
          rootNode.worldTransform.set(rootNode.localTransform);
          rootNode.refreshFlags &= ~RF_TRANSFORM;
          i--;
          break;
        }

        stack[i] = rootNode;

        if ((hisParent.refreshFlags & RF_TRANSFORM) == 0) {
          break;
        }

        rootNode = hisParent;
        i++;
      }

      vars.release();

      for (int j = i; j >= 0; j--) {
        rootNode = stack[j];
        // rootNode.worldTransform.set(rootNode.localTransform);
        // rootNode.worldTransform.combineWithParent(rootNode.parent.worldTransform);
        // rootNode.refreshFlags &= ~RF_TRANSFORM;
        rootNode.updateWorldTransforms();
      }
    }
  }
 @AttributeName("rot")
 private void loadRotation(Quaternion rotation) {
   Transform transform = spatial.getLocalTransform();
   transform.setRotation(rotation);
 }
 @AttributeName("rot")
 private Quaternion saveRotation() {
   Transform transform = spatial.getLocalTransform();
   return transform.getRotation();
 }
 @AttributeName("trns")
 private void loadTranslation(Vector3f translation) {
   Transform transform = spatial.getLocalTransform();
   transform.setTranslation(translation);
 }
 @AttributeName("trns")
 private Vector3f saveTranslation() {
   Transform transform = spatial.getLocalTransform();
   return transform.getTranslation();
 }
Ejemplo n.º 13
0
 /**
  * <code>getLocalTranslation</code> retrieves the local translation of this node.
  *
  * @return the local translation of this node.
  */
 public Vector3f getLocalTranslation() {
   return localTransform.getTranslation();
 }
Ejemplo n.º 14
0
 /**
  * Convert a vector (in) from this spatials' local coordinate space to world coordinate space.
  *
  * @param in vector to read from
  * @param store where to write the result (null to create a new vector, may be same as in)
  * @return the result (store)
  */
 public Vector3f localToWorld(final Vector3f in, Vector3f store) {
   checkDoTransformUpdate();
   return worldTransform.transformVector(in, store);
 }
Ejemplo n.º 15
0
 /**
  * <code>getWorldRotation</code> retrieves the absolute rotation of the Spatial.
  *
  * @return the Spatial's world rotation quaternion.
  */
 public Quaternion getWorldRotation() {
   checkDoTransformUpdate();
   return worldTransform.getRotation();
 }
Ejemplo n.º 16
0
  private static Transform convertPositions(FloatBuffer input, BoundingBox bbox, Buffer output) {
    if (output.capacity() < input.capacity())
      throw new RuntimeException("Output must be at least as large as input!");

    Vector3f offset = bbox.getCenter().negate();
    Vector3f size = new Vector3f(bbox.getXExtent(), bbox.getYExtent(), bbox.getZExtent());
    size.multLocal(2);

    ShortBuffer sb = null;
    ByteBuffer bb = null;
    float dataTypeSize;
    float dataTypeOffset;
    if (output instanceof ShortBuffer) {
      sb = (ShortBuffer) output;
      dataTypeOffset = shortOff;
      dataTypeSize = shortSize;
    } else {
      bb = (ByteBuffer) output;
      dataTypeOffset = byteOff;
      dataTypeSize = byteSize;
    }
    Vector3f scale = new Vector3f();
    scale.set(dataTypeSize, dataTypeSize, dataTypeSize).divideLocal(size);

    Vector3f invScale = new Vector3f();
    invScale.set(size).divideLocal(dataTypeSize);

    offset.multLocal(scale);
    offset.addLocal(dataTypeOffset, dataTypeOffset, dataTypeOffset);

    // offset = (-modelOffset * shortSize)/modelSize + shortOff
    // scale = shortSize / modelSize

    input.clear();
    output.clear();
    Vector3f temp = new Vector3f();
    int vertexCount = input.capacity() / 3;
    for (int i = 0; i < vertexCount; i++) {
      BufferUtils.populateFromBuffer(temp, input, i);

      // offset and scale vector into -32768 ... 32767
      // or into -128 ... 127 if using bytes
      temp.multLocal(scale);
      temp.addLocal(offset);

      // quantize and store
      if (sb != null) {
        short v1 = (short) temp.getX();
        short v2 = (short) temp.getY();
        short v3 = (short) temp.getZ();
        sb.put(v1).put(v2).put(v3);
      } else {
        byte v1 = (byte) temp.getX();
        byte v2 = (byte) temp.getY();
        byte v3 = (byte) temp.getZ();
        bb.put(v1).put(v2).put(v3);
      }
    }

    Transform transform = new Transform();
    transform.setTranslation(offset.negate().multLocal(invScale));
    transform.setScale(invScale);
    return transform;
  }
Ejemplo n.º 17
0
 /**
  * <code>getWorldScale</code> retrieves the absolute scale factor of the spatial.
  *
  * @return the Spatial's world scale factor.
  */
 public Vector3f getWorldScale() {
   checkDoTransformUpdate();
   return worldTransform.getScale();
 }
Ejemplo n.º 18
0
 /**
  * <code>setLocalRotation</code> sets the local rotation of this node.
  *
  * @param quaternion the new local rotation.
  */
 public void setLocalRotation(Quaternion quaternion) {
   localTransform.setRotation(quaternion);
   setTransformRefresh();
 }
Ejemplo n.º 19
0
 /**
  * <code>setLocalRotation</code> sets the local rotation of this node by using a {@link Matrix3f}.
  *
  * @param rotation the new local rotation.
  */
 public void setLocalRotation(Matrix3f rotation) {
   localTransform.getRotation().fromRotationMatrix(rotation);
   setTransformRefresh();
 }
Ejemplo n.º 20
0
 /**
  * <code>getLocalRotation</code> retrieves the local rotation of this node.
  *
  * @return the local rotation of this node.
  */
 public Quaternion getLocalRotation() {
   return localTransform.getRotation();
 }
Ejemplo n.º 21
0
 /**
  * Convert a vector (in) from world coordinate space to this spatials' local coordinate space.
  *
  * @param in vector to read from
  * @param store where to write the result
  * @return the result (store)
  */
 public Vector3f worldToLocal(final Vector3f in, final Vector3f store) {
   checkDoTransformUpdate();
   return worldTransform.transformInverseVector(in, store);
 }
 @AttributeName("scal")
 private Vector3f saveScale() {
   Transform transform = spatial.getLocalTransform();
   return transform.getScale();
 }
 @AttributeName("scal")
 private void loadScale(Vector3f scale) {
   Transform transform = spatial.getLocalTransform();
   transform.setScale(scale);
 }
Ejemplo n.º 24
0
 /**
  * <code>getWorldTranslation</code> retrieves the absolute translation of the spatial.
  *
  * @return the Spatial's world tranlsation vector.
  */
 public Vector3f getWorldTranslation() {
   checkDoTransformUpdate();
   return worldTransform.getTranslation();
 }
Ejemplo n.º 25
0
 /**
  * <code>getLocalScale</code> retrieves the local scale of this node.
  *
  * @return the local scale of this node.
  */
 public Vector3f getLocalScale() {
   return localTransform.getScale();
 }
Ejemplo n.º 26
0
 /**
  * <code>setLocalScale</code> sets the local scale of this node.
  *
  * @param localScale the new local scale.
  */
 public void setLocalScale(Vector3f localScale) {
   localTransform.setScale(localScale);
   setTransformRefresh();
 }
Ejemplo n.º 27
0
  public void bake(
      Transform ownerTransform,
      Transform targetTransform,
      Track ownerTrack,
      Track targetTrack,
      Ipo influenceIpo) {
    TrackWrapper ownerWrapperTrack = ownerTrack != null ? new TrackWrapper(ownerTrack) : null;
    TrackWrapper targetWrapperTrack = targetTrack != null ? new TrackWrapper(targetTrack) : null;

    // uruchamiamy bake dla transformat zalenie od tego, ktre argumenty s nullami, a ktre - nie
    this.bake(ownerTransform, targetTransform, influenceIpo.calculateValue(0));
    if (ownerWrapperTrack != null) {
      float[] ownerTimes = ownerWrapperTrack.getTimes();
      Vector3f[] translations = ownerWrapperTrack.getTranslations();
      Quaternion[] rotations = ownerWrapperTrack.getRotations();
      Vector3f[] scales = ownerWrapperTrack.getScales();

      float[] targetTimes = targetWrapperTrack == null ? null : targetWrapperTrack.getTimes();
      Vector3f[] targetTranslations =
          targetWrapperTrack == null ? null : targetWrapperTrack.getTranslations();
      Quaternion[] targetRotations =
          targetWrapperTrack == null ? null : targetWrapperTrack.getRotations();
      Vector3f[] targetScales = targetWrapperTrack == null ? null : targetWrapperTrack.getScales();
      Vector3f translation = new Vector3f(), scale = new Vector3f();
      Quaternion rotation = new Quaternion();

      Transform ownerTemp = new Transform(), targetTemp = new Transform();
      for (int i = 0; i < ownerTimes.length; ++i) {
        float t = ownerTimes[i];
        ownerTemp.setTranslation(translations[i]);
        ownerTemp.setRotation(rotations[i]);
        ownerTemp.setScale(scales[i]);
        if (targetWrapperTrack == null) {
          this.bake(ownerTemp, targetTransform, influenceIpo.calculateValue(i));
        } else {
          // getting the values that are the interpolation of the target track for the time 't'
          this.interpolate(targetTranslations, targetTimes, t, translation);
          this.interpolate(targetRotations, targetTimes, t, rotation);
          this.interpolate(targetScales, targetTimes, t, scale);

          targetTemp.setTranslation(translation);
          targetTemp.setRotation(rotation);
          targetTemp.setScale(scale);

          this.bake(ownerTemp, targetTemp, influenceIpo.calculateValue(i));
        }
        // need to clone here because each of the arrays will reference the same instance if they
        // hold the same value in the compact array
        translations[i] = ownerTemp.getTranslation().clone();
        rotations[i] = ownerTemp.getRotation().clone();
        scales[i] = ownerTemp.getScale().clone();
      }
      ownerWrapperTrack.setKeyframes(ownerTimes, translations, rotations, scales);
    }
  }
Ejemplo n.º 28
0
 /**
  * <code>setLocalScale</code> sets the local scale of this node.
  *
  * @param localScale the new local scale, applied to x, y and z
  */
 public void setLocalScale(float localScale) {
   localTransform.setScale(localScale);
   setTransformRefresh();
 }
Ejemplo n.º 29
0
 /** <code>setLocalScale</code> sets the local scale of this node. */
 public void setLocalScale(float x, float y, float z) {
   localTransform.setScale(x, y, z);
   setTransformRefresh();
 }
Ejemplo n.º 30
0
  private static BoneWorldGrid makeBoneWorldGrid(
      ByteArray3d boneMeshGrid, float worldScale, MyBone bone) {
    Transform transform = BoneTransformUtils.boneTransform2(bone);
    // bounding box needed for boneMeshGrid in world grid:
    float bs = 1.0f;
    Vector3f c1 =
        transform.transformVector(new Vector3f(-bs, -bs, -bs), null).multLocal(worldScale);
    Vector3f c2 =
        transform.transformVector(new Vector3f(+bs, -bs, -bs), null).multLocal(worldScale);
    Vector3f c3 =
        transform.transformVector(new Vector3f(-bs, +bs, -bs), null).multLocal(worldScale);
    Vector3f c4 =
        transform.transformVector(new Vector3f(-bs, -bs, +bs), null).multLocal(worldScale);
    Vector3f c5 =
        transform.transformVector(new Vector3f(+bs, +bs, -bs), null).multLocal(worldScale);
    Vector3f c6 =
        transform.transformVector(new Vector3f(-bs, +bs, +bs), null).multLocal(worldScale);
    Vector3f c7 =
        transform.transformVector(new Vector3f(+bs, -bs, +bs), null).multLocal(worldScale);
    Vector3f c8 =
        transform.transformVector(new Vector3f(+bs, +bs, +bs), null).multLocal(worldScale);

    Vector3f cmin = c1.clone();
    cmin.minLocal(c2);
    cmin.minLocal(c3);
    cmin.minLocal(c4);
    cmin.minLocal(c5);
    cmin.minLocal(c6);
    cmin.minLocal(c7);
    cmin.minLocal(c8);
    Vector3f cmax = c1.clone();
    cmax.maxLocal(c2);
    cmax.maxLocal(c3);
    cmax.maxLocal(c4);
    cmax.maxLocal(c5);
    cmax.maxLocal(c6);
    cmax.maxLocal(c7);
    cmax.maxLocal(c8);

    int xsize = (int) FastMath.ceil(cmax.x - cmin.x);
    int ysize = (int) FastMath.ceil(cmax.y - cmin.y);
    int zsize = (int) FastMath.ceil(cmax.z - cmin.z);

    ByteArray3d grid = new ByteArray3d(xsize, ysize, zsize);
    int w = grid.getWidth();
    int h = grid.getHeight();
    int d = grid.getDepth();
    Vector3f v = new Vector3f();
    Vector3f inv = new Vector3f();
    Vector3f inv2 = new Vector3f();

    // we want to calculate transform: (inv - (-bs)) * (sz / (bs - (-bs)))
    // se let's precalculate it to (inv + shift) * scale
    Vector3f scale =
        new Vector3f(boneMeshGrid.getWidth(), boneMeshGrid.getHeight(), boneMeshGrid.getDepth())
            .divideLocal(bs * 2);
    Vector3f shift = Vector3f.UNIT_XYZ.mult(bs);

    for (int x = 0; x < w; x++) {
      for (int y = 0; y < h; y++) {
        // calculate inverse transform at (x,y,0) and (x,y,1), the rest of the transforms in inner
        // loop
        // can be calculated by adding (inv2-inv1) because the transforms are linear
        v.set(x, y, 0).addLocal(cmin).divideLocal(worldScale);
        transform.transformInverseVector(v, inv);
        inv.addLocal(shift).multLocal(scale);

        v.set(x, y, 1).addLocal(cmin).divideLocal(worldScale);
        transform.transformInverseVector(v, inv2);
        inv2.addLocal(shift).multLocal(scale);

        Vector3f add = inv2.subtractLocal(inv);

        for (int z = 0; z < d; z++) {
          inv.addLocal(add);
          if (inv.x >= 0
              && inv.x < boneMeshGrid.getWidth()
              && inv.y >= 0
              && inv.y < boneMeshGrid.getHeight()
              && inv.z >= 0
              && inv.z < boneMeshGrid.getDepth()) {

            grid.set(x, y, z, boneMeshGrid.get((int) inv.x, (int) inv.y, (int) inv.z));
          }
        }
      }
    }

    // Once the boneMeshGrid has been transformed into world grid, it may suffer from
    // downsampling and upsampling artifacts (because the sampling is very simple nearest-neighbor).
    // Blurring the grid helps with both issues (blur=fake antialias). It has the added benefit
    // that each BoneWorldGrid will have some "smoothing buffer" around the actual shape, so that
    // the shape blends better with other bones' shapes.
    blurGrid(grid);

    BoneWorldGrid bwg2 = new BoneWorldGrid();
    bwg2.grid = grid;
    bwg2.location = new Vector3i(Math.round(cmin.x), Math.round(cmin.y), Math.round(cmin.z));
    return bwg2;
  }