Skip to content

Commit

Permalink
+RenderPassInformation for easier callbacks
Browse files Browse the repository at this point in the history
+bumped to 0.2
  • Loading branch information
WorldSEnder committed Feb 17, 2015
1 parent 16be380 commit 021b08d
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 93 deletions.
2 changes: 1 addition & 1 deletion build.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = "0.1.201b_1710"
version = "0.2.001b_1710"
group= "com.github.worldsender.mcanm"
archivesBaseName = "mcanm"
ext {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,6 @@
*
*/
public interface IAnimation {
/**
* This is a default animation that always returns the binding pose for each
* bone it is asked for. Actually it returns <code>null</code> which is to
* be interpreted as the binding-pose.
*/
public static final IAnimation BIND_POSE = new IAnimation() {
@Override
public BoneTransformation getCurrentTransformation(String bone,
float frame) {
return null;
};
};
/**
* Describes a BoneTransformation, including rotation, translation and
* scaling.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package com.github.worldsender.mcanm.client.model.mcanmmodel.data;

import com.github.worldsender.mcanm.client.model.mcanmmodel.animation.IAnimation;
import com.google.common.base.Predicate;
/**
* Used to simplify the pre-render callback process. This class is an aggregate
* of all needed information for one render pass (aka. rendering one object).
* You may use the setter methods or simply extend the class and override the
* getter methods to return what you need.<br>
* You should not call new RenderPassInformation(...) every time one is needed
* but reuse instances you used before. The internal API doesn't keep custom
* instances around after the render-pass is over.
*
* @author WorldSEnder
*
*/
public class RenderPassInformation {
/**
* A suitable {@link Predicate} to return in
* {@link #getPartPredicate(float)} to render all parts without exception.
* Note that this will not test if the currently executed animation wants to
* display the part.
*/
public static final Predicate<String> RENDER_ALL = new Predicate<String>() {
@Override
public boolean apply(String input) {
return true;
}
};
/**
* A suitable {@link Predicate} to return in
* {@link #getPartPredicate(float)} to render no parts without exception.
* Note that this will not test if the currently executed animation wants to
* display the part.
*/
public static final Predicate<String> RENDER_NONE = new Predicate<String>() {
@Override
public boolean apply(String input) {
return false;
}
};
/**
* This is a default animation that always returns the binding pose for each
* bone it is asked for. Actually it returns <code>null</code> which is to
* be interpreted as the binding-pose.
*/
public static final IAnimation BIND_POSE = new IAnimation() {
@Override
public BoneTransformation getCurrentTransformation(String bone,
float frame) {
return null;
};
};

private float frame;
private IAnimation animation;
private Predicate<String> partPredicate;

public RenderPassInformation() {
this.reset();
}

public RenderPassInformation(float frame, IAnimation animation,
Predicate<String> partPredicate) {
this.frame = frame;
this.animation = animation;
this.partPredicate = partPredicate;
}
/**
* Resets this information to be reused.
*/
public void reset() {
this.frame = 0F;
this.animation = BIND_POSE;
this.partPredicate = RENDER_ALL;
}
/**
* Returns the current Frame in the animation. This is not inside the
* {@link IAnimation} so that each object/entity can decide on its own.
* Should include the current subframe for smoother transitions.
*
* @return the current frame
*/
public float getFrame() {
return frame;
}
/**
* @param frame
* the frame to set
*/
public RenderPassInformation setFrame(float frame) {
this.frame = frame;
return this;
}
/**
* Gets the animation to play. If you return null here the model will be
* displayed in bind pose.
*
* @return the current animation
*/
public IAnimation getAnimation() {
return animation;
}
/**
* @param animation
* the animation to set
*/
public RenderPassInformation setAnimation(IAnimation animation) {
this.animation = animation;
return this;
}
/**
* Returns for the current animation a predicate that get applied all
* model-parts to test if they should be rendered.
*
* @return a predicate to match parts against that may be rendered
*/
public Predicate<String> getPartPredicate() {
return partPredicate;
}
/**
* @param partPredicate
* the partPredicate to set
*/
public RenderPassInformation setPartPredicate(
Predicate<String> partPredicate) {
this.partPredicate = partPredicate;
return this;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
import com.github.worldsender.mcanm.client.model.mcanmmodel.animation.IAnimation;
import com.github.worldsender.mcanm.client.model.mcanmmodel.data.ModelDataBasic;
import com.github.worldsender.mcanm.client.model.mcanmmodel.data.RawDataV1;
import com.github.worldsender.mcanm.client.model.mcanmmodel.data.RenderPassInformation;
import com.github.worldsender.mcanm.client.renderer.IAnimatedObject;
import com.google.common.base.Predicate;

public class GLHelperBasic extends GLHelper {
private ModelDataBasic modelData;
private RenderPassInformation passInformation = new RenderPassInformation();;

@Override
public void loadFrom(RawDataV1 datav1) {
Expand All @@ -18,13 +20,21 @@ public void loadFrom(RawDataV1 datav1) {
public void render(IAnimatedObject object, float subFrame) {
if (this.modelData == null) // Not loaded correctly
return;
object.preRenderCallback(subFrame);
Predicate<String> filter = object.getPartPredicate(subFrame);
IAnimation currAnim = object.getCurrentAnimation(subFrame);
float frame = object.getCurrentFrame(subFrame);
if (filter != null)
this.modelData.renderFiltered(filter, currAnim, frame);
else
this.modelData.renderAll(currAnim, frame);
if (object == null) // Don't render
return;
passInformation.reset();
RenderPassInformation currentPass = object.preRenderCallback(subFrame,
passInformation);
if (currentPass == null)
this.modelData.renderAll(RenderPassInformation.BIND_POSE, 0.0F);
else {
Predicate<String> filter = currentPass.getPartPredicate();
IAnimation animation = currentPass.getAnimation();
float frame = currentPass.getFrame();
if (filter != null)
this.modelData.renderFiltered(filter, animation, frame);
else
this.modelData.renderAll(animation, frame);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.github.worldsender.mcanm.client.renderer;

import com.github.worldsender.mcanm.client.model.mcanmmodel.animation.IAnimation;
import com.google.common.base.Predicate;
import com.github.worldsender.mcanm.client.model.mcanmmodel.data.RenderPassInformation;
/**
* Kind of a default implementation for {@link IAnimatedObject} which means that
* the user isn't bothered as much.
Expand All @@ -10,23 +9,9 @@
*
*/
public abstract class AnimatedObjAdapter implements IAnimatedObject {

@Override
public IAnimation getCurrentAnimation(float subFrame) {
return null;
}

@Override
public float getCurrentFrame(float subFrame) {
return 0.0f;
}

@Override
public void preRenderCallback(float subFrame) {}

@Override
public Predicate<String> getPartPredicate(float subFrame) {
return RENDER_ALL;
public RenderPassInformation preRenderCallback(float subFrame,
RenderPassInformation callback) {
return callback; // Passthrough
}

}
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package com.github.worldsender.mcanm.client.renderer;

import com.github.worldsender.mcanm.client.model.mcanmmodel.animation.IAnimation;
import com.github.worldsender.mcanm.client.model.mcanmmodel.data.RenderPassInformation;
import com.github.worldsender.mcanm.client.renderer.entity.RenderAnimatedModel;
import com.google.common.base.Predicate;
/**
* An animatable type that is typically rendered with a
* {@link RenderAnimatedModel} or a //TODO: RenderMHFCModelTile
Expand All @@ -12,58 +11,16 @@
*/
public interface IAnimatedObject {
/**
* A suitable {@link Predicate} to return in
* {@link #getPartPredicate(float)} to render all parts without exception.
* Note that this will not test if the currently executed animation wants to
* display the part.
*/
public static final Predicate<String> RENDER_ALL = new Predicate<String>() {
@Override
public boolean apply(String input) {
return true;
}
};
/**
* A suitable {@link Predicate} to return in
* {@link #getPartPredicate(float)} to render no parts without exception.
* Note that this will not test if the currently executed animation wants to
* display the part.
*/
public static final Predicate<String> RENDER_NONE = new Predicate<String>() {
@Override
public boolean apply(String input) {
return false;
}
};
/**
* Gets the animation to play. If you return null here the model will be
* displayed in bind pose.
*
* @return the current attack
*/
public IAnimation getCurrentAnimation(float subFrame);
/**
* Returns the current Frame in the animation. This is not inside the
* {@link IAnimation} so that each object/entity can decide on its own.
* Should add the subFrame ontop for smoother transitions.
*/
public float getCurrentFrame(float subFrame);
/**
* A callback to the animated object just before it is rendered. For
* convenience the subFrame is provided. The method is always called BEFORE
* {@link #getCurrentAnimation(float)}, {@link #getCurrentFrame(float)} and
* {@link #getPartPredicate(float)}. The object should ONLY apply some
* simple transformations, for example a scaling or an offset.
*/
public void preRenderCallback(float subFrame);
/**
* Returns for a specific subFrame in the current animation a predicate that
* get applied all model-parts to test if they should be rendered.
* A callback to the animated object just before it is rendered. The method
* is always called BEFORE. The object should setup and return the
* {@link RenderPassInformation} given as callback (never null).
*
* @param subFrame
* makes the method subFrame sensible
*
* @return a predicate to match parts against that may be rendered
* the current subFrame (subTick)
* @param callback
* a {@link RenderPassInformation} to prepare
* @return A {@link RenderPassInformation} to use in the current pass
*/
public Predicate<String> getPartPredicate(float subFrame);
public RenderPassInformation preRenderCallback(float subFrame,
RenderPassInformation callback);
}

0 comments on commit 021b08d

Please sign in to comment.