All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.brashmonkey.spriter.ik.SpriterIKResolver Maven / Gradle / Ivy

There is a newer version: 1.1
Show newest version
package com.brashmonkey.spriter.ik;

import java.util.HashMap;
import java.util.Map.Entry;

import com.brashmonkey.spriter.objects.SpriterAbstractObject;
import com.brashmonkey.spriter.objects.SpriterBone;
import com.brashmonkey.spriter.objects.SpriterIKObject;
import com.brashmonkey.spriter.objects.SpriterObject;
import com.brashmonkey.spriter.player.SpriterAbstractPlayer;

public abstract class  SpriterIKResolver {
	
	/**
	 * Resolves the inverse kinematics constraint with a specific algtorithm
	 * @param x the target x value
	 * @param y the target y value
	 * @param chainLength number of parents which are affected
	 * @param effector the actual effector where the resolved information has to be stored in.
	 */
	protected abstract void resolve(float x, float y, int chainLength, SpriterAbstractObject effector, SpriterAbstractPlayer player);
	
	protected boolean resovling;
	protected HashMap ikMap;
	protected float tolerance;

	public SpriterIKResolver() {
		this.resovling = true;
		this.tolerance = 5f;
		this.ikMap = new HashMap();
	}
	
	/**
	 * Resolves the inverse kinematics constraints with the implemented algorithm in {@link #resolve(float, float, int, SpriterAbstractObject, SpriterAbstractPlayer)}.
	 * @param player player to apply the resolving.
	 */
	public void resolve(SpriterAbstractPlayer player){
		for(Entry entry: this.ikMap.entrySet()){
			for(int j = 0; j < entry.getKey().iterations; j++)
				this.resolve(entry.getKey().getX(), entry.getKey().getY(), entry.getKey().chainLength, 
						(entry.getValue() instanceof SpriterBone) ? player.getRuntimeBones()[entry.getValue().getId()] : player.getRuntimeObjects()[entry.getValue().getId()],player);
		}
	}

	/**
	 * @return the resovling
	 */
	public boolean isResovling() {
		return resovling;
	}

	/**
	 * @param resovling the resovling to set
	 */
	public void setResovling(boolean resovling) {
		this.resovling = resovling;
	}
	
	/**
	 * Adds the given object to the internal SpriterIKObject - SpriterBone map, which works like a HashMap.
	 * This means, the values of the given object affect the mapped bone.
	 * @param object
	 * @param bone
	 */
	public void mapIKObject(SpriterIKObject object, SpriterAbstractObject abstractObject){
		this.ikMap.put(object, abstractObject);
	}
	
	/**
	 * Removes the given object from the internal map.
	 * @param object
	 */
	public void unmapIKObject(SpriterIKObject object){
		this.ikMap.remove(object);
	}

	public float getTolerance() {
		return tolerance;
	}

	public void setTolerance(float tolerance) {
		this.tolerance = tolerance;
	}
	
	/**
	 * Changes the state of each effector to unactive. The effect results in non animated bodyparts.
	 * @param parents indicates whether parents of the effectors have to be deactivated or not.
	 */
	public void deactivateEffectors(SpriterAbstractPlayer player, boolean parents){
		for(Entry entry: this.ikMap.entrySet()){
			SpriterAbstractObject obj = entry.getValue();
			obj = (obj instanceof SpriterBone) ? player.getRuntimeBones()[obj.getId()]: player.getRuntimeObjects()[obj.getId()];
			obj.active = false;
			if(!parents) continue;
			SpriterBone par = (SpriterBone) entry.getValue().getParent();
			for(int j = 0; j < entry.getKey().chainLength && par != null; j++){
				player.getRuntimeBones()[par.getId()].active = false;
				par = (SpriterBone) par.getParent();
			}
		}
	}
	
	public void activateEffectors(SpriterAbstractPlayer player){
		for(Entry entry: this.ikMap.entrySet()){
			SpriterAbstractObject obj = entry.getValue();
			obj = (obj instanceof SpriterBone) ? player.getRuntimeBones()[obj.getId()]: player.getRuntimeObjects()[obj.getId()];
			obj.active = true;
			SpriterBone par = (SpriterBone) entry.getValue().getParent();
			for(int j = 0; j < entry.getKey().chainLength && par != null; j++){
				player.getRuntimeBones()[par.getId()].active = false;
				par = (SpriterBone) par.getParent();
			}
		}
	}
	
	public void activateAll(SpriterAbstractPlayer player){
		for(SpriterBone bone: player.getRuntimeBones())
			bone.active = true;
		for(SpriterObject obj: player.getRuntimeObjects())
			obj.active = true;
	}
	
	protected void updateObject(SpriterAbstractPlayer player, SpriterAbstractObject object){
		player.updateAbstractObject(object);
	}
	
	protected void updateRecursively(SpriterAbstractPlayer player, SpriterAbstractObject object){
		this.updateObject(player, object);
		if(object instanceof SpriterBone){
			for(SpriterBone child: ((SpriterBone) object).getChildBones())
				this.updateRecursively(player, player.getRuntimeBones()[child.getId()]);
			for(SpriterObject child: ((SpriterBone) object).getChildObjects())
				this.updateRecursively(player, player.getRuntimeObjects()[child.getId()]);
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy