Package nu3a.scene

Source Code of nu3a.scene.N3TransformationNode

/*
*  Copyright (c) 2003 Jorge García, Unai Aguilera
*
*  This file is part of Nu3A.
*
*   Nu3A is free software: you can redistribute it and/or modify
*   it under the terms of the GNU General Public License as published by
*   the Free Software Foundation, either version 3 of the License, or
*   (at your option) any later version.

*   Nu3A is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*   GNU General Public License for more details.
*
*   You should have received a copy of the GNU General Public License
*   along with Nu3A.  If not, see <http://www.gnu.org/licenses/>.
*
*
*  Authors: Jorge García <bardok@gmail.com>, Unai Aguilera <gkalgan@gmail.com>
*/

package nu3a.scene;

import java.util.StringTokenizer;

import nu3a.math.N3Matrix4D;
import nu3a.math.N3Vector3D;
import nu3a.names.exception.N3NameException;
import nu3a.persistence.N3PersistentResource;
import nu3a.persistence.N3PersistentResourceList;
import nu3a.persistence.N3SceneReader;
import nu3a.render.N3Render;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
* Nodo de agrupaci�n que soporta transformaciones en el espacio 3D. Estas
* transformaciones se aplicar�n a todos los nodos hijos. Para actualizar las
* transformaciones hechas a un nodo es necesario llamar al metodo update.
*/

public class N3TransformationNode extends N3GroupNode {
  /**
   * Matriz de transformaci�n del nodo.
   */
  protected N3Matrix4D matrix;

  /**
   * Translaci�n del nodo.
   */
  protected N3Vector3D translation;

  /**
   * Indica que la transformaci�n es needa.
   */
  protected boolean needTranslation;

  /**
   * Escalado del nodo.
   */
  protected N3Vector3D scale;

  /**
   * Indica que el escalado es needo.
   */
  protected boolean needScale;

  /**
   * Angulo de rotaci�n del nodo.
   */
  protected float angle;

  /**
   * Vector de rotaci�n del nodo.
   */
  protected N3Vector3D rotation;

  /**
   * Indica que la rotaci�n es valida.
   */
  protected boolean needRotation;

  /**
   * Matriz de transformaci�n anterior del nodo. Utilizada por si hay que
   * deshacer un cambio por ejemplo al detectar una colision.
   */
  protected N3Matrix4D lastMatrix;

  /**
   * Matriz temporal para realizar los calculos de la transformaci�n acumulada
   * sin tener que sobrecargar al sistema con la creaci�n de una nueva
   * instancia, cada vez que debamos recalcularla.
   */
  private N3Matrix4D tmpAccMatrix;

  /**
   * Constructor de la clase.
   *
   * @param scene
   *            Escena a la que pertenece el nodo.
   * @param name
   *            Nombre del nodo
   */
  public N3TransformationNode(N3Scene scene, String name)
      throws N3NameException {
    super(scene, name);
    matrix = new N3Matrix4D();
    tmpAccMatrix = new N3Matrix4D();
    lastMatrix = new N3Matrix4D();
    translation = new N3Vector3D(0, 0, 0);
    scale = new N3Vector3D(1.0f, 1.0f, 1.0f);
    angle = 0;
    rotation = new N3Vector3D(1.0f, 1.0f, 1.0f);
    needTranslation = needScale = needRotation = false;
    matrix.identity();
  }

  /**
   * M�todo que rota el nodo de transformaci�n el �ngulo indicado alrededor
   * del eje determinado por el vector 'axis'.
   *
   * @param angle
   *            �ngulo a rotar
   * @param axis
   *            Eje de rotaci�n
   */
  public void rotate(float angle, N3Vector3D axis) {
    this.angle = angle;
    rotation.x = axis.x;
    rotation.y = axis.y;
    rotation.z = axis.z;
    needRotation = true;
  }

  /**
   * M�todo que traslada el nodo de transformaci�n en la cantidad especificada
   * por el vector 'v'.
   *
   * @param v
   *            Vector que indica la traslaci�n en cada uno de los ejes.
   */
  public void translate(N3Vector3D v) {
    translation.x = v.x;
    translation.y = v.y;
    translation.z = v.z;
    needTranslation = true;
  }

  /**
   * M�todo que escala el nodo de transformaci�n en la proporci�n indicada por
   * el vector 'v'.
   *
   * @param v
   *            Vector que indica la magnitud del escalado en cada uno de los
   *            ejes
   */
  public void scale(N3Vector3D v) {
    scale.x = v.x;
    scale.y = v.y;
    scale.z = v.z;
    needScale = true;
  }

  /**
   * Postmultiplica la matriz de transformaci�n del nodo por la matriz
   * indicada. Si se realiza un update a continuaci�n este no tendra ning�n
   * efecto.
   *
   * @param m
   *            Matriz de transformaci�n por la que se postmultiplicar� la
   *            matriz del nodo de transformaci�n
   */
  public void mult(N3Matrix4D m) {
    lastMatrix.setData(matrix);
    matrix.mult(m);
    needTranslation = needScale = needRotation = false;
    setDirty();
  }

  /**
   * Deshace la ultima transformaci�n realizada en el nodo. Si se realiza un
   * update a continuaci�n este no tendra ning�n efecto.
   */
  public void undo() {
    matrix.setData(lastMatrix);
    needTranslation = needScale = needRotation = false;
    setDirty();
  }

  /**
   * Devuelve la matriz de transformaci�n del nodo.
   *
   * @return Matriz de transformaci�n
   */
  public N3Matrix4D getMatrix() {
    return matrix;
  }

  /**
   * Establece como matriz de transformaci�n del nodo la matriz indicada.Si se
   * realiza un update a continuaci�n este no tendra ning�n efecto.
   *
   * @param m
   *            Nueva matriz de transformaci�n
   */

  public void setMatrix(N3Matrix4D m) {
    matrix = m;
    needTranslation = needScale = needRotation = false;
    setDirty();
  }

  /**
   * Obtiene la matriz acumulada de transformaciones para el nodo.
   *
   * @return Matriz acumulada de transformaciones
   */
  public N3Matrix4D getAccMatrix() {
    if (isDirty) {
      super.getAccMatrix();
      tmpAccMatrix.setData(accMatrix);
      accMatrix = tmpAccMatrix;
      accMatrix.mult(matrix);
      isDirty = false;
    }
    return accMatrix;
  }

  /**
   * Actualiza el nodo con las transformaciones que se han hecho.
   */
  public void update() {
    if (needScale || needRotation || needTranslation) {
      lastMatrix.setData(matrix);
      if (needScale) {
        N3Matrix4D scaleMatrix = new N3Matrix4D();
        scaleMatrix.scale(scale);
        matrix.mult(scaleMatrix);
        needScale = false;
      }
      if (needRotation) {
        N3Matrix4D rotationMatrix = new N3Matrix4D();
        rotationMatrix.rotate(angle, rotation);
        matrix.mult(rotationMatrix);
        needRotation = false;
      }
      if (needTranslation) {
        N3Matrix4D translationMatrix = new N3Matrix4D();
        translationMatrix.translate(translation);
        matrix.mult(translationMatrix);
        needTranslation = false;
      }
      setDirty();
    }
  }

  public Element getXMLDescription(Document doc,
      N3PersistentResourceList resources) {
    Element result = super.getXMLDescription(doc, resources);

    String floatString = "";

    float[] m = matrix.getMatrix();

    for (int i = 0; i < 16; i++)
      floatString += ("" + m[i] + ((i < 15) ? " " : ""));

    Element data = doc.createElement("matrix");
    data.setAttribute("values", floatString);
    result.appendChild(data);

    return result;
  }

  /**
   * Devuelve una instancia de la clase, a partir de los par�metros, y de la
   * descripci�n XML en infoNode.
   *
   * @param infoNode
   *            Descripci�n XML de la instacia a crear
   * @param nodes
   *            Rama XML con las descripciones de los recursos de la escena
   * @param resources
   *            Lista de recursos de la escena
   * @param reader
   *            Instancia capaz de crear recursos que a�n no se han creado
   * @param render
   *            Render para el que se est� creando la escena
   * @param scene
   *            Escena que se est� creando
   * @return Instancia de la clase con la informaci�n especificada
   */
  public static N3PersistentResource loadInstance(Element infoNode,
      NodeList nodes, N3PersistentResourceList resources,
      N3SceneReader reader, N3Render render, N3Scene scene)
      throws Exception {
    String name = infoNode.getAttribute("name");
    N3TransformationNode result = new N3TransformationNode(scene, name);

    Element data = (Element) infoNode.getElementsByTagName("collisionable")
        .item(0);
    result.setCollisionable((new Boolean(data.getAttribute("value")))
        .booleanValue());

    data = (Element) infoNode.getElementsByTagName("matrix").item(0);
    String floatstring = data.getAttribute("values");
    StringTokenizer st = new StringTokenizer(floatstring, " ");
    int i = 0;
    float[] matrix = result.matrix.getMatrix();
    while (st.hasMoreTokens()) {
      matrix[i] = Float.parseFloat(st.nextToken());
      i++;
    }

    return result;
  }
}
TOP

Related Classes of nu3a.scene.N3TransformationNode

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.