/******************************************************************************* * Copyright 2011 See AUTHORS file. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package sink.scene3d; import sink.core.Sink; import com.badlogic.gdx.graphics.g3d.Model; import com.badlogic.gdx.graphics.g3d.ModelInstance; import com.badlogic.gdx.math.collision.BoundingBox; import com.badlogic.gdx.scenes.scene2d.EventListener; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.DelayedRemovalArray; public class Actor3d extends ModelInstance{ private Stage3d stage3d; private Group3d parent; private final DelayedRemovalArray<EventListener> listeners = new DelayedRemovalArray<EventListener>(0); private final Array<Action3d> actions3d = new Array<Action3d>(0); private String name; private boolean visible = true; float x, y, z; float width, height, depth; float originX, originY, originZ; float scaleX = 1, scaleY = 1, scaleZ = 1; float rotation = 0; BoundingBox boundBox; public Actor3d(){ super(new Model()); setPosition(0,0,0); setOrigin(0,0,0); } public Actor3d(Model model){ super(model); setPosition(0,0,0); boundBox = model.meshes.get(0).calculateBoundingBox(); setOrigin(boundBox.max.x, boundBox.max.y, boundBox.max.z); } public Actor3d(Model model, float x, float y, float z){ super(model); setPosition(x,y,z); boundBox = model.meshes.get(0).calculateBoundingBox(); setOrigin(boundBox.max.x, boundBox.max.y, boundBox.max.z); } /** Updates the actor3d based on time. Typically this is called each frame by {@link Stage3d#act(float)}. * <p> * The default implementation calls {@link Action3d#act(float)} on each action and removes actions that are complete. * @param delta Time in seconds since the last frame. */ public void act (float delta) { for (int i = 0; i < actions3d.size; i++) { Action3d action3d = actions3d.get(i); if (action3d.act(delta) && i < actions3d.size) { actions3d.removeIndex(i); action3d.setActor3d(null); i--; } } } public Actor3d hit (float x, float y) { return null; } /** Removes this actor3d from its parent, if it has a parent. * @see Group#removeActor(Actor) */ public boolean remove () { if (parent != null) return parent.removeActor(this); return false; } /** Add a listener to receive events that {@link #hit(float, float, boolean) hit} this actor3d. See {@link #fire(Event)}. * * @see InputListener * @see ClickListener */ public boolean addListener(EventListener listener) { if (!listeners.contains(listener, true)) { listeners.add(listener); return true; } return false; } public boolean removeListener (EventListener listener) { return listeners.removeValue(listener, true); } public Array<EventListener> getListeners () { return listeners; } public void addAction3d (Action3d action) { action.setActor3d(this); actions3d.add(action); } public void removeAction3d (Action3d action) { if (actions3d.removeValue(action, true)) action.setActor3d(null); } public Array<Action3d> getActions3d () { return actions3d; } /** Removes all actions on this actor3d. */ public void clearActions3d () { for (int i = actions3d.size - 1; i >= 0; i--) actions3d.get(i).setActor3d(null); actions3d.clear(); } /** Removes all listeners on this actor3d. */ public void clearListeners () { listeners.clear(); } /** Removes all actions and listeners on this actor3d. */ public void clear () { clearActions3d(); clearListeners(); } /** Called by the framework when this actor3d or any parent is added to a group that is in the stage3d. * @param stage3d May be null if the actor3d or any parent is no longer in a stage. */ protected void setStage3d(Stage3d stage3d) { this.stage3d = stage3d; } /** Returns the stage3d that this actor3d is currently in, or null if not in a stage. */ public Stage3d getStage3d() { return stage3d; } /** Returns true if this actor3d is the same as or is the descendant of the specified actor3d. */ public boolean isDescendantOf (Actor3d actor3d) { if (actor3d == null) throw new IllegalArgumentException("actor3d cannot be null."); Actor3d parent = this; while (true) { if (parent == null) return false; if (parent == actor3d) return true; parent = parent.parent; } } /** Returns true if this actor3d is the same as or is the ascendant of the specified actor3d. */ public boolean isAscendantOf (Actor3d actor3d) { if (actor3d == null) throw new IllegalArgumentException("actor3d cannot be null."); while (true) { if (actor3d == null) return false; if (actor3d == this) return true; actor3d = actor3d.parent; } } /** Returns true if the actor3d's parent is not null. */ public boolean hasParent () { return parent != null; } /** Returns the parent actor3d, or null if not in a stage. */ public Group3d getParent () { return parent; } /** Called by the framework when an actor3d is added to or removed from a group. * @param parent May be null if the actor3d has been removed from the parent. */ protected void setParent (Group3d parent) { this.parent = parent; } public boolean isVisible () { return visible; } /** If false, the actor3d will not be drawn and will not receive touch events. Default is true. */ public void setVisible (boolean visible) { this.visible = visible; } /* Sets the originx , originy and originz used for rotation */ public void setOrigin (float originX, float originY, float originZ) { this.originX = originX; this.originY = originY; this.originZ = originZ; } public void setPosition(float x, float y, float z) { this.x = x; this.y = y; this.z = z; transform.setToTranslationAndScaling(this.x, this.y, this.z, scaleX, scaleY, scaleZ); } public void translate(float x, float y, float z) { this.x += x; this.y += y; this.z += z; transform.setToTranslationAndScaling(this.x, this.y, this.z, scaleX, scaleY, scaleZ); } public void setRotation(float degrees) { this.rotation = degrees; setPosition(x, y, z); transform.setToRotation(originX, originY, originZ, rotation); } public void rotate (float degrees) { rotation += degrees; setPosition(x, y, z); transform.setToRotation(originX, originY, originZ, rotation); } public void setScale(float scaleX, float scaleY, float scaleZ) { this.scaleX = scaleX; this.scaleY = scaleY; this.scaleZ = scaleZ; transform.scale(scaleX, scaleY, scaleZ); } public void setScale(float scale) { this.scaleX = scale; this.scaleY = scale; this.scaleZ = scale; transform.scale(scaleX, scaleY, scaleZ); } /** Adds the specified scale to the current scale. */ public void scale(float scale) { scaleX += scale; scaleY += scale; scaleZ += scale; transform.scl(scale); } public void scale(float scaleX, float scaleY, float scaleZ) { this.scaleX += scaleX; this.scaleY += scaleY; this.scaleZ += scaleZ; transform.scl(scaleX, scaleY, scaleZ); } public void setX (float x) { this.x = x;transform.setToTranslation(x, y, z); } public float getX () { return x; } public void setY (float y) { this.y = y;transform.setToTranslation(x, y, z); } public float getY () { return y; } public void setZ (float z) { this.z = z;transform.setToTranslation(x, y, z); } public float getZ (){ return z; } public void setOriginX (float originX) { this.originX = originX; } public float getOriginX () { return originX; } public void setOriginY (float originY) { this.originY = originY; } public float getOriginY () { return originY; } public void setOriginZ (float originZ) { this.originZ = originZ; } public float getOriginZ () { return originZ; } public void setScaleX (float scaleX) { this.scaleX = scaleX; transform.scale(scaleX, scaleY, scaleZ); } public float getScaleX () { return scaleX; } public float getRotation () { return rotation; } public void setScaleY (float scaleY) { this.scaleY = scaleY; transform.scale(scaleX, scaleY, scaleZ); } public float getScaleY () { return scaleY; } public void setScaleZ (float scaleZ) { this.scaleY = scaleZ; transform.scale(scaleX, scaleY, scaleZ); } public float getScaleZ () { return scaleZ; } /** Sets a name for easier identification of the actor3d in application code. * @see Group#findActor(String) */ public void setName (String name) { this.name = name; } public String getName () { return name; } public void setWidth (float width) { //for(Mesh m: model.meshes) // m.scale(width, arg1, arg2); this.width = width; } public void setHeight (float height) { this.height = height; } public float getWidth () { return width; } public float getHeight () { return height; } public float getDepth () { return depth; } /** Sets the width and height. */ public void setSize (float width, float height) { } /** Adds the specified size to the current size. */ public void size (float size) { width += size; height += size; } /** Adds the specified size to the current size. */ public void size (float width, float height) { this.width += width; this.height += height; } public String toString () { String name = this.name; if (name == null) { name = getClass().getName(); int dotIndex = name.lastIndexOf('.'); if (dotIndex != -1) name = name.substring(dotIndex + 1); } return name; } }