/**
* Copyright (c) 2007-2008, JAGaToo Project Group all rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the 'Xith3D Project Group' nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) A
* RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE
*/
package org.xith3d.physics.util;
import java.util.ArrayList;
import org.jagatoo.datatypes.RepositionListener3f;
import org.openmali.vecmath2.Matrix3f;
import org.openmali.vecmath2.Point3f;
import org.openmali.vecmath2.Tuple3f;
import org.openmali.vecmath2.util.MatrixUtils;
/**
* A small, GC-friendly implementation of the Placeable
* interface. Extend it when you need Placeable without
* much hassle and you don't already have a superclass.
*
* @author Amos Wenger (aka BlueSky)
*/
public abstract class PlaceableImpl implements ListeningPlaceable
{
protected boolean valueCheckedBeforeChanged = false;
protected final Point3f position;
protected final Matrix3f rotation;
private Tuple3f rotEuler = null;
private final ArrayList<RepositionListener3f> repositionListeners = new ArrayList<RepositionListener3f>();
/**
* {@inheritDoc}
*/
public void addRepositionListener( RepositionListener3f l )
{
repositionListeners.add( l );
}
/**
* {@inheritDoc}
*/
public void removeRepositionListener( RepositionListener3f l )
{
repositionListeners.remove( l );
}
protected void onPositionChanged()
{
for ( int i = 0; i < repositionListeners.size(); i++ )
{
repositionListeners.get( i ).onPositionChanged( position.getX(), position.getY(), position.getZ() );
}
}
public void setPosition( float posX, float posY, float posZ )
{
if ( valueCheckedBeforeChanged && ( position.getX() == posX ) && ( position.getY() == posY ) && ( position.getZ() == posZ ) )
return;
this.position.set( posX, posY, posZ );
onPositionChanged();
}
public final void setPosition( Tuple3f pos )
{
setPosition( pos.getX(), pos.getY(), pos.getZ() );
}
public final Point3f getPosition()
{
return ( this.position.getReadOnly() );
}
public final void getPosition( Tuple3f pos )
{
pos.set( this.position );
}
protected void onRotationChanged()
{
}
public void setRotation( float rotX, float rotY, float rotZ )
{
MatrixUtils.eulerToMatrix3f( rotX, rotY, rotZ, this.rotation );
onRotationChanged();
}
public final void setRotation( Tuple3f rot )
{
setRotation( rot.getX(), rot.getY(), rot.getZ() );
}
public final Tuple3f getRotation()
{
if ( rotEuler == null )
rotEuler = new Tuple3f();
MatrixUtils.matrixToEuler( this.rotation, rotEuler );
return ( rotEuler.getReadOnly() );
}
public final void getRotation( Tuple3f rot )
{
setRotation( rot.getX(), rot.getY(), rot.getZ() );
}
public void setRotationMatrix( Matrix3f rot )
{
this.rotation.set( rot );
onRotationChanged();
}
public final Matrix3f getRotationMatrix()
{
return ( this.rotation.getReadOnly() );
}
public final void getRotationMatrix( Matrix3f rot )
{
rot.set( this.rotation );
}
/*
* Additionnal methods (e.g. for those wanting to connect
* Interpolators to only one dimension
*/
public final void setPositionX( float v ) { this.position.setX( v ); onPositionChanged(); }
public final void setPositionY( float v ) { this.position.setY( v ); onPositionChanged(); }
public final void setPositionZ( float v ) { this.position.setZ( v ); onPositionChanged(); }
public final float getPositionX() { return this.position.getX(); }
public final float getPositionY() { return this.position.getY(); }
public final float getPositionZ() { return this.position.getZ(); }
public final void setRotationX( float v) { Tuple3f rot = getRotation(); MatrixUtils.eulerToMatrix3f( v, rot.getY(), rot.getZ(), this.rotation ); onRotationChanged(); }
public final void setRotationY( float v ) { Tuple3f rot = getRotation(); MatrixUtils.eulerToMatrix3f( rot.getX(), v, rot.getZ(), this.rotation ); onRotationChanged(); }
public final void setRotationZ( float v ) { Tuple3f rot = getRotation(); MatrixUtils.eulerToMatrix3f( rot.getX(), rot.getY(), v, this.rotation ); onRotationChanged(); }
public final float getRotationX() { return getRotation().getX(); }
public final float getRotationY() { return getRotation().getY(); }
public final float getRotationZ() { return getRotation().getZ(); }
/**
* Creation a new PlaceableImpl with pos (0, 0, 0)
* and no rotation.
*/
public PlaceableImpl()
{
this.position = new Point3f( 0f, 0f, 0f );
this.rotation = new Matrix3f();
this.rotation.setIdentity();
}
}