package sk.neuromancer.sphaera.rewrite; import java.util.Collection; import java.util.LinkedList; import java.util.List; import sk.neuromancer.sphaera.interf.Collidable; import sk.neuromancer.sphaera.interf.Moveable; import sk.neuromancer.sphaera.interf.Renderable; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.VertexAttributes.Usage; import com.badlogic.gdx.graphics.g3d.Environment; import com.badlogic.gdx.graphics.g3d.Material; import com.badlogic.gdx.graphics.g3d.ModelBatch; import com.badlogic.gdx.graphics.g3d.ModelInstance; import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute; import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder; import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.utils.Disposable; public class Sphere implements Renderable, Moveable, Collidable, Disposable{ private static final int MAX_DIV = 50; private static final int DIV = 12; public static final float BASE_RADIUS = 50f; public static final Color DEFAULT_DIFFUSE = new Color(0.9f, 0.9f, 0.9f, 1f); public static final Color DEFAULT_SPECULAR = new Color(0.5f, 0.5f, 0.5f, 0.5f); public static final Color DEFAULT_AMBIENT = new Color(1f, 1f, 1f, 0.5f); public static final Color DEFAULT_REFLECTION = new Color(0.5f, 0.5f, 0.5f, 0.5f); public static final Color SMALLER_DIFFUSE = new Color(0.05f, 0.05f, 0.9f, 1f); public static final Color BIGGER_DIFFUSE = new Color(0.7f, 0.1f, 0.1f, 1f); public static final Material BASE_MAT = new Material(ColorAttribute.createDiffuse(DEFAULT_DIFFUSE), ColorAttribute.createReflection(DEFAULT_SPECULAR), ColorAttribute.createAmbient(DEFAULT_AMBIENT), ColorAttribute.createReflection(DEFAULT_REFLECTION) ); public static final Material SMALLER_MAT = new Material(ColorAttribute.createDiffuse(SMALLER_DIFFUSE), ColorAttribute.createReflection(DEFAULT_SPECULAR), ColorAttribute.createAmbient(DEFAULT_AMBIENT), ColorAttribute.createReflection(DEFAULT_REFLECTION) ); public static final Material BIGGER_MAT = new Material(ColorAttribute.createDiffuse(BIGGER_DIFFUSE), ColorAttribute.createReflection(DEFAULT_SPECULAR), ColorAttribute.createAmbient(DEFAULT_AMBIENT), ColorAttribute.createReflection(DEFAULT_REFLECTION) ); private Sphere parent = null;//if parent null, then private List children = new LinkedList(); private ModelInstance model; private float radius; /** * Both positions are relative to the parent, * if parent == null, then they are absolute. */ private Vector3 position; private Vector3 sphericalPosition;//degrees /* * Dunno if Ill use it... */ private Vector3 velocity; public Sphere(){ this.position = Vector3.Zero.cpy(); this.sphericalPosition = Vector3.Zero.cpy(); this.velocity = Vector3.Zero.cpy(); } public Sphere(float radius){ this(); this.radius = radius; } public Sphere(float radius, Material... mat){ this(radius); ModelBuilder mb = new ModelBuilder(); int div = Math.min(MAX_DIV, (int) radius * DIV); if(this instanceof Player){ div = MAX_DIV; } this.model = new ModelInstance(mb.createSphere(2, 2, 2, div, div, mat[0], Usage.Position | Usage.Normal)); /*for(Material m : mat){ this.model.materials.add(m); }*/ } public Sphere(float x, float y, float z, float radius, Material... mat){ this(radius, mat); this.position.x = x; this.position.y = y; this.position.z = z; this.sphericalPosition = SphereUtils.toSphericalDeg(x, y, z); } public Sphere(Sphere parent, float a, float b, float radius, Material... mat){ this(radius, mat); this.parent = parent; this.sphericalPosition.x = parent.getRadius() + this.radius; this.sphericalPosition.y = a; this.sphericalPosition.z = b; this.position = SphereUtils.toCartesianDeg(this.sphericalPosition.x, a, b); } public Sphere getParent() { return this.parent; } public void setParent(Sphere newParent){ if(this.parent != null){ this.parent.removeChildren(this); } this.parent = newParent; this.parent.addChildren(this); } public boolean addChildren(Sphere child){ return this.children.add(child); } public boolean removeChildren(Sphere child){ return this.children.remove(child); } public Collection getChildren(){ return new LinkedList(this.children); } public float getRadius() { return this.radius; } public void setRadius(float radius){ this.radius = radius; } public void scaleRadius(float newRadius){ Vector3 newSpherical = this.getSphericalPosition(); if(this.getParent() != null){ newSpherical.x = this.getParent().getRadius() + newRadius; } Vector3 newRelative = this.getRelativePosition(); newRelative.setLength(this.getParent().getRadius() + newRadius); this.setSphericalPosition(newSpherical); this.setRelativePosition(newRelative); this.setRadius(newRadius); } public void setSphericalPosition(Vector3 spherical){ this.sphericalPosition = spherical.cpy(); } public void setRelativePosition(Vector3 relative){ this.position = relative.cpy(); } public void setPositionSpherical(Vector3 spherical){ //both this.setSphericalPosition(spherical); this.setRelativePosition(SphereUtils.toCartesianDeg(spherical)); } public void setPositionRelative(Vector3 relative){ //both this.setRelativePosition(relative); this.setSphericalPosition(SphereUtils.toSphericalDeg(relative)); } public Vector3 getSphericalPosition(){ return this.sphericalPosition.cpy(); } public Vector3 getAbsolutePosition(){ if(this.parent == null){ return this.getRelativePosition(); } return this.position.cpy().add(this.getParent().getAbsolutePosition()); } public Vector3 getRelativePosition(){ return this.position.cpy(); } public void dropOnParent(Vector3 oldParentPos){ if(this.parent == null){ return; } Vector3 absolutePos = oldParentPos.add(this.position); Vector3 fromParent = absolutePos.cpy().sub(this.parent.getAbsolutePosition()); fromParent.setLength(this.parent.getRadius() + this.radius); this.setPositionRelative(fromParent); } public void dropOnParent(Sphere oldParent){ this.dropOnParent(oldParent.getAbsolutePosition()); /*potrebujem absolutne pozicie *OH SHIT! *mam problem, musim toto riesit pri zmene parenta!! *pretoze tu uz nemam toho stareho takze getAbsolutePosition je BS aj getRelative... */ } public void putOnParent(float polar, float azimuth){ if(this.getParent() == null) return; float completeRadius = this.getParent().getRadius() + this.getRadius(); this.setPositionSpherical(new Vector3(completeRadius, polar, azimuth)); } public void setColorAttributes(ColorAttribute... attribs){ this.model.materials.get(0).set(attribs); } @Override public void render(ModelBatch renderer, Environment environment) { model.transform.setToTranslation(this.getAbsolutePosition()); model.transform.scale(radius,radius,radius); renderer.render(model, environment); } @Override public Vector3 getVelocity(){ return this.velocity.cpy(); } public void setVelocity(Vector3 velocity){ this.velocity = velocity; } public void move(){ //all the way this.move(1); } @Override public void move(float howMuch){ if(this.velocity.len() == 0) return; this.velocity.scl(howMuch); this.setPositionRelative(this.getRelativePosition().add(this.velocity)); this.velocity = Vector3.Zero.cpy(); //maybe leave velocity as the rest I want to go? //that way I can call move again and hope I } @Override public boolean collides(Sphere other) { if(this.getParent() != null && other.getParent() != null){ return this.getRelativePosition().sub(other.getRelativePosition()).len() < this.getRadius() + other.getRadius(); } return this.getAbsolutePosition().sub(other.getAbsolutePosition()).len() < this.getRadius() + other.getRadius(); } @Override public String toString(){ return "Sphere" + ":" + /*this.hashCode() +*/ "\n" + " radius=" + this.getRadius() + "\n" + " spherical=" + this.getSphericalPosition() + "\n" + " relative=" + this.getRelativePosition(); } @Override public void dispose() { this.model.model.dispose(); } }