New facade system (#3702)
Completely new system to render facades. It will now support many more cases compared to the old system. For example connected textures are now possible, as well as multilayer models and so on.
This commit is contained in:
+436
@@ -0,0 +1,436 @@
|
||||
/*
|
||||
* This file is part of CodeChickenLib.
|
||||
* Copyright (c) 2018, covers1624, All rights reserved.
|
||||
*
|
||||
* CodeChickenLib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CodeChickenLib is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with CodeChickenLib. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.thirdparty.codechicken.lib.model.pipeline;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.client.model.pipeline.IVertexConsumer;
|
||||
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
|
||||
|
||||
import appeng.thirdparty.codechicken.lib.model.CachedFormat;
|
||||
import appeng.thirdparty.codechicken.lib.model.ISmartVertexConsumer;
|
||||
import appeng.thirdparty.codechicken.lib.model.Quad;
|
||||
|
||||
|
||||
/**
|
||||
* The BakedPipeline!
|
||||
* Basically this allows us to efficiently transform a BakedQuad,
|
||||
* the Pipeline has Elements, each element has a name, state and a transformer,
|
||||
* you can enable and disable elements easily, you can also grab the underlying
|
||||
* transformer for the element if you need to set its state before rendering.
|
||||
*
|
||||
* The BakedPipeline is final once created, you cannot add or remove elements,
|
||||
* you should not need to add or remove them runtime, enable and disable exist.
|
||||
*
|
||||
* You must use the Builder class to construct a BakedPipeline, see {@link #builder}
|
||||
*
|
||||
* Transformers run on a mutable state inside each transformer, allowing for easy reuse.
|
||||
* It is recommended to store your pipeline inside a ThreadLocal because 'minecraft'.
|
||||
*
|
||||
* Each Transformer should be smart enough to expand itself for each newly sized VertexFormat it comes across,
|
||||
* meaning that the internal states for the transformers can be safely shared across VertexFormats, this reduces
|
||||
* array creations, and generally makes the system as efficient as it is.
|
||||
*
|
||||
* To use the system:
|
||||
* Grab any elements you need to set state data on first, using {@link #getElement(String, Class)}
|
||||
* transformers should NOT clear their state on pipeline Reset's so set any global data on elements now.
|
||||
* Assuming you are looping over a set of quads to transform, next you need to {@link #reset} the pipeline,
|
||||
* Now you should disable / enable any optional elements that are needed, NOTE: Element states are reset when resetting
|
||||
* the pipeline.
|
||||
* Now you will need to call {@link #prepare(IVertexConsumer)} on the pipeline, here you will pass your collector,
|
||||
* usually this is some form of (Unpacked)BakedQuadBuilder, See {@link QuadBuilder} for a simple and fast implementation
|
||||
* for standard BakedQuads, and {@link UnpackedBakedQuad.Builder} for UnpackedBakedQuads.
|
||||
* Now final step, simply pipe the quad you want to transform INTO the pipeline 'quad.pipe(pipeline)'
|
||||
* And that's it! hell, Pipe a pipeline into each other for all i care, the system is efficient enough that there
|
||||
* would be no performance penalty for doing so.
|
||||
*
|
||||
* @author covers1624
|
||||
*/
|
||||
public class BakedPipeline implements ISmartVertexConsumer
|
||||
{
|
||||
|
||||
private PipelineElement[] elements;
|
||||
private Map<String, PipelineElement> nameLookup;
|
||||
private IPipelineConsumer first;
|
||||
|
||||
private Quad unpacker = new Quad();
|
||||
|
||||
private BakedPipeline( PipelineElement[] elements )
|
||||
{
|
||||
this.elements = elements;
|
||||
this.nameLookup = Arrays.stream( elements ).collect( Collectors.toMap( e -> e.name, e -> e ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to create a BakedPipeline.
|
||||
*
|
||||
* @return The builder.
|
||||
*/
|
||||
public static Builder builder()
|
||||
{
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to reset the pipeline for the next quad.
|
||||
* MUST be called between quads.
|
||||
*
|
||||
* @param format The format.
|
||||
*/
|
||||
public void reset( VertexFormat format )
|
||||
{
|
||||
this.reset( CachedFormat.lookup( format ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to reset the pipeline for the next quad.
|
||||
* MUST be called between quads.
|
||||
*
|
||||
* @param format The format.
|
||||
*/
|
||||
public void reset( CachedFormat format )
|
||||
{
|
||||
this.unpacker.reset( format );
|
||||
for( PipelineElement element : this.elements )
|
||||
{
|
||||
element.reset( format );
|
||||
}
|
||||
this.first = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an element from the pipeline.
|
||||
*
|
||||
* @param name The name of the element.
|
||||
* @param clazz The Class of the element, used to safe cast.
|
||||
*
|
||||
* @return The element.
|
||||
*/
|
||||
public <T extends IPipelineConsumer> T getElement( String name, Class<T> clazz )
|
||||
{
|
||||
PipelineElement element = this.nameLookup.get( name );
|
||||
if( element != null )
|
||||
{
|
||||
if( !clazz.isAssignableFrom( element.consumer.getClass() ) )
|
||||
{
|
||||
throw new IllegalArgumentException( "Element with name " + name + " is not assignable from reference class." );
|
||||
}
|
||||
return clazz.cast( element.consumer );
|
||||
}
|
||||
throw new IllegalArgumentException( "Element with name " + name + " does not exist." );
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to enable an element on the pipeline with the specified name.
|
||||
*
|
||||
* @param name The elements name.
|
||||
*/
|
||||
public void enableElement( String name )
|
||||
{
|
||||
this.setElementState( name, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to disable an element on the pipeline with the specified name.
|
||||
*
|
||||
* @param name The elements name.
|
||||
*/
|
||||
public void disableElement( String name )
|
||||
{
|
||||
this.setElementState( name, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to set the state of an element on the pipeline.
|
||||
*
|
||||
* @param name The name of the element.
|
||||
* @param enabled The state to set it to.
|
||||
*/
|
||||
public void setElementState( String name, boolean enabled )
|
||||
{
|
||||
PipelineElement element = this.nameLookup.get( name );
|
||||
if( element != null )
|
||||
{
|
||||
element.isEnabled = enabled;
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException( "Element with name " + name + " does not exist." );
|
||||
}
|
||||
|
||||
/**
|
||||
* Call when you are ready to use the pipeline.
|
||||
* This builds the internal state of the Elements getting things ready to transform.
|
||||
*
|
||||
* @param collector The IVertexConsumer that should collect the transformed quad.
|
||||
*/
|
||||
public void prepare( IVertexConsumer collector )
|
||||
{
|
||||
IPipelineConsumer next = null;
|
||||
for( PipelineElement element : this.elements )
|
||||
{
|
||||
if( element.isEnabled )
|
||||
{
|
||||
if( this.first == null )
|
||||
{
|
||||
this.first = element.consumer;
|
||||
}
|
||||
else
|
||||
{
|
||||
next.setParent( element.consumer );
|
||||
}
|
||||
next = element.consumer;
|
||||
}
|
||||
}
|
||||
next.setParent( collector );
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexFormat getVertexFormat()
|
||||
{
|
||||
this.check();
|
||||
return this.first.getVertexFormat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setQuadTint( int tint )
|
||||
{
|
||||
this.check();
|
||||
this.unpacker.setQuadTint( tint );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setQuadOrientation( EnumFacing orientation )
|
||||
{
|
||||
this.check();
|
||||
this.unpacker.setQuadOrientation( orientation );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplyDiffuseLighting( boolean diffuse )
|
||||
{
|
||||
this.check();
|
||||
this.unpacker.setApplyDiffuseLighting( diffuse );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTexture( TextureAtlasSprite texture )
|
||||
{
|
||||
this.check();
|
||||
this.unpacker.setTexture( texture );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put( int element, float... data )
|
||||
{
|
||||
this.check();
|
||||
this.unpacker.put( element, data );
|
||||
if( this.unpacker.full )
|
||||
{
|
||||
this.onFull();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put( Quad quad )
|
||||
{
|
||||
this.check();
|
||||
this.unpacker.put( quad );
|
||||
}
|
||||
|
||||
private void check()
|
||||
{
|
||||
if( this.first == null )
|
||||
{
|
||||
throw new IllegalStateException( "Pipeline used before prepare was called." );
|
||||
}
|
||||
}
|
||||
|
||||
private void onFull()
|
||||
{
|
||||
this.first.setInputQuad( this.unpacker );
|
||||
this.first.put( this.unpacker );
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal class, used to hold a PipelineElement's state.
|
||||
*/
|
||||
public static class PipelineElement<T extends IPipelineConsumer>
|
||||
{
|
||||
|
||||
public String name;
|
||||
public boolean defaultState;
|
||||
public T consumer;
|
||||
public boolean isEnabled;
|
||||
|
||||
public void reset( CachedFormat format )
|
||||
{
|
||||
this.isEnabled = this.defaultState;
|
||||
this.consumer.setParent( null );
|
||||
this.consumer.reset( format );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The builder associated with the BakedPipeline.
|
||||
* You must create a BakedPipeline with this,
|
||||
* once created a pipeline cannot be modified,
|
||||
* modifying should not be needed as you can enable
|
||||
* and disable elements with ease.
|
||||
*/
|
||||
public static class Builder
|
||||
{
|
||||
|
||||
private LinkedList<PipelineElement> elements = new LinkedList<>();
|
||||
|
||||
/**
|
||||
* Inserts an element to the front of the list, Useful if you have a more complex system
|
||||
* and each system need to be independent from each other, but this element must be first.
|
||||
*
|
||||
* @param name The name to identify this element, used as an identifier when setting state, and retrieving the
|
||||
* element.
|
||||
* @param factory The factory used to create the Transformer.
|
||||
*
|
||||
* @return The same builder.
|
||||
*/
|
||||
public Builder addFirst( String name, IPipelineElementFactory<?> factory )
|
||||
{
|
||||
return this.addFirst( name, factory, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an element to the front of the list, Useful if you have a more complex system
|
||||
* and each system need to be independent from each other, but this element must be first.
|
||||
*
|
||||
* @param name The name to identify this element, used as an identifier when setting state, and retrieving the
|
||||
* element.
|
||||
* @param factory The factory used to create the Transformer.
|
||||
* @param defaultState The default state for this element.
|
||||
*
|
||||
* @return The same builder.
|
||||
*/
|
||||
public Builder addFirst( String name, IPipelineElementFactory<?> factory, boolean defaultState )
|
||||
{
|
||||
return this.addFirst( name, factory, defaultState, e ->
|
||||
{
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an element to the front of the list, Useful if you have a more complex system
|
||||
* and each system need to be independent from each other, but this element must be first.
|
||||
*
|
||||
* @param name The name to identify this element, used as an identifier when setting state, and retrieving the
|
||||
* element.
|
||||
* @param factory The factory used to create the Transformer.
|
||||
* @param defaultState The default state for this element.
|
||||
* @param defaultsSetter A callback used to set any defaults on the transformer.
|
||||
*
|
||||
* @return The same builder.
|
||||
*/
|
||||
public <T extends IPipelineConsumer> Builder addFirst( String name, IPipelineElementFactory<T> factory, boolean defaultState, Consumer<T> defaultsSetter )
|
||||
{
|
||||
PipelineElement<T> element = this.makeElement( name, factory, defaultState );
|
||||
defaultsSetter.accept( element.consumer );
|
||||
this.elements.addFirst( element );
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an element at the end of the transform list, Suitable for 99% of cases.
|
||||
*
|
||||
* @param name The name to identify this element, used as an identifier when setting state, and retrieving the
|
||||
* element.
|
||||
* @param factory The factory used to create the Transformer.
|
||||
*
|
||||
* @return The same builder.
|
||||
*/
|
||||
public Builder addElement( String name, IPipelineElementFactory<?> factory )
|
||||
{
|
||||
return this.addElement( name, factory, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an element at the end of the transform list, Suitable for 99% of cases.
|
||||
*
|
||||
* @param name The name to identify this element, used as an identifier when setting state, and retrieving the
|
||||
* element.
|
||||
* @param factory The factory used to create the Transformer.
|
||||
* @param defaultState The default state for this element.
|
||||
*
|
||||
* @return The same builder.
|
||||
*/
|
||||
public Builder addElement( String name, IPipelineElementFactory<?> factory, boolean defaultState )
|
||||
{
|
||||
return this.addElement( name, factory, defaultState, e ->
|
||||
{
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an element at the end of the transform list, Suitable for 99% of cases.
|
||||
*
|
||||
* @param name The name to identify this element, used as an identifier when setting state, and retrieving the
|
||||
* element.
|
||||
* @param factory The factory used to create the Transformer.
|
||||
* @param defaultState The default state for this element.
|
||||
* @param defaultsSetter A callback used to set any defaults on the transformer.
|
||||
*
|
||||
* @return The same builder.
|
||||
*/
|
||||
public <T extends IPipelineConsumer> Builder addElement( String name, IPipelineElementFactory<T> factory, boolean defaultState, Consumer<T> defaultsSetter )
|
||||
{
|
||||
PipelineElement<T> element = this.makeElement( name, factory, defaultState );
|
||||
defaultsSetter.accept( element.consumer );
|
||||
this.elements.add( element );
|
||||
return this;
|
||||
}
|
||||
|
||||
// Internal method, used to construct the PipelineElement class.
|
||||
private <T extends IPipelineConsumer> PipelineElement<T> makeElement( String name, IPipelineElementFactory<T> factory, boolean defaultState )
|
||||
{
|
||||
if( this.elements.stream().anyMatch( p -> p.name.equals( name ) ) )
|
||||
{
|
||||
throw new IllegalArgumentException( "Unable to add element with duplicate name: " + name );
|
||||
}
|
||||
PipelineElement<T> element = new PipelineElement<>();
|
||||
element.name = name;
|
||||
element.consumer = factory.create();
|
||||
element.defaultState = defaultState;
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this once you are finished to build your BakedPipeline!
|
||||
*
|
||||
* @return The new Pipeline.
|
||||
*/
|
||||
public BakedPipeline build()
|
||||
{
|
||||
return new BakedPipeline( this.elements.toArray( new PipelineElement[0] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* This file is part of CodeChickenLib.
|
||||
* Copyright (c) 2018, covers1624, All rights reserved.
|
||||
*
|
||||
* CodeChickenLib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CodeChickenLib is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with CodeChickenLib. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.thirdparty.codechicken.lib.model.pipeline;
|
||||
|
||||
|
||||
import net.minecraftforge.client.model.pipeline.IVertexConsumer;
|
||||
|
||||
import appeng.thirdparty.codechicken.lib.model.CachedFormat;
|
||||
import appeng.thirdparty.codechicken.lib.model.ISmartVertexConsumer;
|
||||
import appeng.thirdparty.codechicken.lib.model.Quad;
|
||||
import appeng.thirdparty.codechicken.lib.model.pipeline.transformers.QuadReInterpolator;
|
||||
|
||||
|
||||
/**
|
||||
* Anything implementing this may be used in the BakedPipeline.
|
||||
*
|
||||
* @author covers1624
|
||||
*/
|
||||
public interface IPipelineConsumer extends ISmartVertexConsumer
|
||||
{
|
||||
|
||||
/**
|
||||
* The quad at the start of the transformation.
|
||||
* This is useful for obtaining the vertex data before any transformations have been applied,
|
||||
* such as interpolation, See {@link QuadReInterpolator}.
|
||||
* When overriding this make sure you call setInputQuad on your parent consumer too.
|
||||
*
|
||||
* @param quad The quad.
|
||||
*/
|
||||
void setInputQuad( Quad quad );
|
||||
|
||||
/**
|
||||
* Resets the Consumer to the new format.
|
||||
* This should resize any internal arrays if needed, ready for the new vertex data.
|
||||
*
|
||||
* @param format The format to reset to.
|
||||
*/
|
||||
void reset( CachedFormat format );
|
||||
|
||||
/**
|
||||
* Sets the parent consumer.
|
||||
* This consumer may choose to not pipe any data,
|
||||
* that's fine, but if it does, it MUST pipe the data to the one provided here.
|
||||
*
|
||||
* @param parent The parent.
|
||||
*/
|
||||
void setParent( IVertexConsumer parent );
|
||||
}
|
||||
Vendored
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* This file is part of CodeChickenLib.
|
||||
* Copyright (c) 2018, covers1624, All rights reserved.
|
||||
*
|
||||
* CodeChickenLib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CodeChickenLib is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with CodeChickenLib. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.thirdparty.codechicken.lib.model.pipeline;
|
||||
|
||||
|
||||
/**
|
||||
* @author covers1624
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface IPipelineElementFactory<T extends IPipelineConsumer>
|
||||
{
|
||||
|
||||
T create();
|
||||
}
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* This file is part of CodeChickenLib.
|
||||
* Copyright (c) 2018, covers1624, All rights reserved.
|
||||
*
|
||||
* CodeChickenLib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CodeChickenLib is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with CodeChickenLib. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.thirdparty.codechicken.lib.model.pipeline;
|
||||
|
||||
|
||||
import javax.annotation.OverridingMethodsMustInvokeSuper;
|
||||
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.client.model.pipeline.IVertexConsumer;
|
||||
|
||||
import appeng.thirdparty.codechicken.lib.model.CachedFormat;
|
||||
import appeng.thirdparty.codechicken.lib.model.ISmartVertexConsumer;
|
||||
import appeng.thirdparty.codechicken.lib.model.Quad;
|
||||
|
||||
|
||||
/**
|
||||
* Base class for a simple QuadTransformer.
|
||||
* Operates on BakedQuads.
|
||||
* QuadTransformers can be piped into each other at no performance penalty.
|
||||
*
|
||||
* @author covers1624
|
||||
*/
|
||||
public abstract class QuadTransformer implements IVertexConsumer, ISmartVertexConsumer, IPipelineConsumer
|
||||
{
|
||||
|
||||
protected CachedFormat format;
|
||||
protected IVertexConsumer consumer;
|
||||
protected Quad quad;
|
||||
|
||||
/**
|
||||
* Used for the BakedPipeline.
|
||||
*/
|
||||
protected QuadTransformer()
|
||||
{
|
||||
this.quad = new Quad();
|
||||
}
|
||||
|
||||
public QuadTransformer( IVertexConsumer consumer )
|
||||
{
|
||||
this( consumer.getVertexFormat(), consumer );
|
||||
}
|
||||
|
||||
public QuadTransformer( VertexFormat format, IVertexConsumer consumer )
|
||||
{
|
||||
this( CachedFormat.lookup( format ), consumer );
|
||||
}
|
||||
|
||||
public QuadTransformer( CachedFormat format, IVertexConsumer consumer )
|
||||
{
|
||||
this.format = format;
|
||||
this.consumer = consumer;
|
||||
this.quad = new Quad( format );
|
||||
}
|
||||
|
||||
@Override
|
||||
@OverridingMethodsMustInvokeSuper
|
||||
public void reset( CachedFormat format )
|
||||
{
|
||||
this.format = format;
|
||||
this.quad.reset( format );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParent( IVertexConsumer parent )
|
||||
{
|
||||
this.consumer = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
@OverridingMethodsMustInvokeSuper
|
||||
public void setInputQuad( Quad quad )
|
||||
{
|
||||
if( this.consumer instanceof IPipelineConsumer )
|
||||
{
|
||||
( (IPipelineConsumer) this.consumer ).setInputQuad( quad );
|
||||
}
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
@Override
|
||||
public VertexFormat getVertexFormat()
|
||||
{
|
||||
return this.format.format;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setQuadTint( int tint )
|
||||
{
|
||||
this.quad.setQuadTint( tint );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setQuadOrientation( EnumFacing orientation )
|
||||
{
|
||||
this.quad.setQuadOrientation( orientation );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplyDiffuseLighting( boolean diffuse )
|
||||
{
|
||||
this.quad.setApplyDiffuseLighting( diffuse );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTexture( TextureAtlasSprite texture )
|
||||
{
|
||||
this.quad.setTexture( texture );
|
||||
}
|
||||
// @formatter:on
|
||||
|
||||
@Override
|
||||
public void put( int element, float... data )
|
||||
{
|
||||
this.quad.put( element, data );
|
||||
if( this.quad.full )
|
||||
{
|
||||
this.onFull();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put( Quad quad )
|
||||
{
|
||||
this.quad.put( quad );
|
||||
this.onFull();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to transform the vertices.
|
||||
*
|
||||
* @return If the transformer should pipe the quad.
|
||||
*/
|
||||
public abstract boolean transform();
|
||||
|
||||
public void onFull()
|
||||
{
|
||||
if( this.transform() )
|
||||
{
|
||||
this.quad.pipe( this.consumer );
|
||||
}
|
||||
}
|
||||
|
||||
// Should be small enough.
|
||||
private final static double EPSILON = 0.00001;
|
||||
|
||||
public static boolean epsComp( float a, float b )
|
||||
{
|
||||
if( a == b )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Math.abs( a - b ) < EPSILON;
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* This file is part of CodeChickenLib.
|
||||
* Copyright (c) 2018, covers1624, All rights reserved.
|
||||
*
|
||||
* CodeChickenLib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CodeChickenLib is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with CodeChickenLib. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.thirdparty.codechicken.lib.model.pipeline.transformers;
|
||||
|
||||
|
||||
import net.minecraftforge.client.model.pipeline.IVertexConsumer;
|
||||
|
||||
import appeng.thirdparty.codechicken.lib.model.Quad.Vertex;
|
||||
import appeng.thirdparty.codechicken.lib.model.pipeline.IPipelineElementFactory;
|
||||
import appeng.thirdparty.codechicken.lib.model.pipeline.QuadTransformer;
|
||||
|
||||
|
||||
/**
|
||||
* This transformer simply overrides the alpha of the quad.
|
||||
* Only operates if the format has color.
|
||||
*
|
||||
* @author covers1624
|
||||
*/
|
||||
public class QuadAlphaOverride extends QuadTransformer
|
||||
{
|
||||
|
||||
public static final IPipelineElementFactory<QuadAlphaOverride> FACTORY = QuadAlphaOverride::new;
|
||||
|
||||
private float alphaOverride;
|
||||
|
||||
QuadAlphaOverride()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public QuadAlphaOverride( IVertexConsumer consumer, float alphaOverride )
|
||||
{
|
||||
super( consumer );
|
||||
this.alphaOverride = alphaOverride;
|
||||
}
|
||||
|
||||
public QuadAlphaOverride setAlphaOverride( float alphaOverride )
|
||||
{
|
||||
this.alphaOverride = alphaOverride;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean transform()
|
||||
{
|
||||
if( this.format.hasColor )
|
||||
{
|
||||
for( Vertex v : this.quad.vertices )
|
||||
{
|
||||
v.color[3] = this.alphaOverride;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Vendored
+83
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* This file is part of CodeChickenLib.
|
||||
* Copyright (c) 2018, covers1624, All rights reserved.
|
||||
*
|
||||
* CodeChickenLib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CodeChickenLib is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with CodeChickenLib. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.thirdparty.codechicken.lib.model.pipeline.transformers;
|
||||
|
||||
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraftforge.client.model.pipeline.IVertexConsumer;
|
||||
|
||||
import appeng.thirdparty.codechicken.lib.model.Quad.Vertex;
|
||||
import appeng.thirdparty.codechicken.lib.model.pipeline.IPipelineElementFactory;
|
||||
import appeng.thirdparty.codechicken.lib.model.pipeline.QuadTransformer;
|
||||
|
||||
|
||||
/**
|
||||
* This transformer simply clamps the vertices inside the provided box.
|
||||
* You probably want to Re-Interpolate the UV's, Color, and Lmap, see {@link QuadReInterpolator}
|
||||
*
|
||||
* @author covers1624
|
||||
*/
|
||||
public class QuadClamper extends QuadTransformer
|
||||
{
|
||||
|
||||
public static IPipelineElementFactory<QuadClamper> FACTORY = QuadClamper::new;
|
||||
|
||||
private AxisAlignedBB clampBounds;
|
||||
|
||||
QuadClamper()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public QuadClamper( IVertexConsumer parent, AxisAlignedBB bounds )
|
||||
{
|
||||
super( parent );
|
||||
this.clampBounds = bounds;
|
||||
}
|
||||
|
||||
public void setClampBounds( AxisAlignedBB bounds )
|
||||
{
|
||||
this.clampBounds = bounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean transform()
|
||||
{
|
||||
int s = this.quad.orientation.ordinal() >> 1;
|
||||
|
||||
this.quad.clamp( this.clampBounds );
|
||||
|
||||
// Check if the quad would be invisible and cull it.
|
||||
Vertex[] vertices = this.quad.vertices;
|
||||
float x1 = vertices[0].dx( s );
|
||||
float x2 = vertices[1].dx( s );
|
||||
float x3 = vertices[2].dx( s );
|
||||
float x4 = vertices[3].dx( s );
|
||||
|
||||
float y1 = vertices[0].dy( s );
|
||||
float y2 = vertices[1].dy( s );
|
||||
float y3 = vertices[2].dy( s );
|
||||
float y4 = vertices[3].dy( s );
|
||||
|
||||
// These comparisons are safe as we are comparing clamped values.
|
||||
boolean flag1 = x1 == x2 && x2 == x3 && x3 == x4;
|
||||
boolean flag2 = y1 == y2 && y2 == y3 && y3 == y4;
|
||||
return !flag1 && !flag2;
|
||||
}
|
||||
}
|
||||
Vendored
+219
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* This file is part of CodeChickenLib.
|
||||
* Copyright (c) 2018, covers1624, All rights reserved.
|
||||
*
|
||||
* CodeChickenLib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CodeChickenLib is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with CodeChickenLib. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.thirdparty.codechicken.lib.model.pipeline.transformers;
|
||||
|
||||
|
||||
import static net.minecraft.util.EnumFacing.AxisDirection.NEGATIVE;
|
||||
import static net.minecraft.util.EnumFacing.AxisDirection.POSITIVE;
|
||||
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumFacing.AxisDirection;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
|
||||
import appeng.thirdparty.codechicken.lib.model.Quad.Vertex;
|
||||
import appeng.thirdparty.codechicken.lib.model.pipeline.IPipelineElementFactory;
|
||||
import appeng.thirdparty.codechicken.lib.model.pipeline.QuadTransformer;
|
||||
|
||||
|
||||
/**
|
||||
* This transformer is a little complicated.
|
||||
* Basically a Facade / Cover can use this to 'kick' the edges
|
||||
* in of quads to fix z-Fighting in the corners.
|
||||
* Use it by specifying the side of the block you are on,
|
||||
* the bitmask for where the other Facades / Cover's are,
|
||||
* the bounding box of the facade, NOT the hole piece,
|
||||
* and the thickness of your Facade / Cover, this is used
|
||||
* as the kick amount.
|
||||
*
|
||||
* @author covers1624
|
||||
*/
|
||||
public class QuadCornerKicker extends QuadTransformer
|
||||
{
|
||||
|
||||
// The factory for pipeline creation.
|
||||
public static final IPipelineElementFactory<QuadCornerKicker> FACTORY = QuadCornerKicker::new;
|
||||
|
||||
// Simple horizonal lookups.
|
||||
public static int[][] horizonals = new int[][] {
|
||||
// Around Y axis, NSWE.
|
||||
{ 2, 3, 4, 5 }, //
|
||||
{ 2, 3, 4, 5 }, //
|
||||
|
||||
// Around Z axis, DUWE.
|
||||
{ 0, 1, 4, 5 }, //
|
||||
{ 0, 1, 4, 5 }, //
|
||||
|
||||
// Around X axis, DUNS.
|
||||
{ 0, 1, 2, 3 }, //
|
||||
{ 0, 1, 2, 3 }
|
||||
};
|
||||
|
||||
private int mySide;
|
||||
private int facadeMask;
|
||||
private AxisAlignedBB box;
|
||||
private double thickness;
|
||||
|
||||
QuadCornerKicker()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set's the side this Facade / Cover is attached to.
|
||||
*
|
||||
* @param side The side.
|
||||
*/
|
||||
public void setSide( int side )
|
||||
{
|
||||
this.mySide = side;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bitmask of Facades / Covers in the blockspace.
|
||||
* This is as simple as, mask = (1 << side)
|
||||
*
|
||||
* @param mask The mask.
|
||||
*/
|
||||
public void setFacadeMask( int mask )
|
||||
{
|
||||
this.facadeMask = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bounding box of the Facade / Cover,
|
||||
* this should be the full box, not just a piece
|
||||
* of the hole's 'ring'.
|
||||
*
|
||||
* @param box The BoundingBox.
|
||||
*/
|
||||
public void setBox( AxisAlignedBB box )
|
||||
{
|
||||
this.box = box;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the amount to kick the vertex in by,
|
||||
* this is your facades thickness.
|
||||
*
|
||||
* @param thickness The thickness.
|
||||
*/
|
||||
public void setThickness( double thickness )
|
||||
{
|
||||
this.thickness = thickness;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean transform()
|
||||
{
|
||||
|
||||
int side = this.quad.orientation.ordinal();
|
||||
if( side != this.mySide && side != ( this.mySide ^ 1 ) )
|
||||
{
|
||||
for( int hoz : horizonals[this.mySide] )
|
||||
{
|
||||
if( side != hoz && side != ( hoz ^ 1 ) )
|
||||
{
|
||||
if( ( this.facadeMask & ( 1 << hoz ) ) != 0 )
|
||||
{
|
||||
Corner corner = Corner.fromSides( this.mySide ^ 1, side, hoz );
|
||||
for( Vertex vertex : this.quad.vertices )
|
||||
{
|
||||
float x = vertex.vec[0];
|
||||
float y = vertex.vec[1];
|
||||
float z = vertex.vec[2];
|
||||
if( epsComp( x, corner.pX( this.box ) ) && epsComp( y, corner.pY( this.box ) ) && epsComp( z, corner.pZ( this.box ) ) )
|
||||
{
|
||||
Vec3i vec = EnumFacing.VALUES[hoz].getDirectionVec();
|
||||
x -= vec.getX() * this.thickness;
|
||||
y -= vec.getY() * this.thickness;
|
||||
z -= vec.getZ() * this.thickness;
|
||||
vertex.vec[0] = x;
|
||||
vertex.vec[1] = y;
|
||||
vertex.vec[2] = z;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public enum Corner
|
||||
{
|
||||
|
||||
MIN_X_MIN_Y_MIN_Z( NEGATIVE, NEGATIVE, NEGATIVE ),
|
||||
MIN_X_MIN_Y_MAX_Z( NEGATIVE, NEGATIVE, POSITIVE ),
|
||||
MIN_X_MAX_Y_MIN_Z( NEGATIVE, POSITIVE, NEGATIVE ),
|
||||
MIN_X_MAX_Y_MAX_Z( NEGATIVE, POSITIVE, POSITIVE ),
|
||||
|
||||
MAX_X_MIN_Y_MIN_Z( POSITIVE, NEGATIVE, NEGATIVE ),
|
||||
MAX_X_MIN_Y_MAX_Z( POSITIVE, NEGATIVE, POSITIVE ),
|
||||
MAX_X_MAX_Y_MIN_Z( POSITIVE, POSITIVE, NEGATIVE ),
|
||||
MAX_X_MAX_Y_MAX_Z( POSITIVE, POSITIVE, POSITIVE );
|
||||
|
||||
private AxisDirection xAxis;
|
||||
private AxisDirection yAxis;
|
||||
private AxisDirection zAxis;
|
||||
|
||||
private static final int[] sideMask = { 0, 2, 0, 1, 0, 4 };
|
||||
|
||||
Corner( AxisDirection xAxis, AxisDirection yAxis, AxisDirection zAxis )
|
||||
{
|
||||
this.xAxis = xAxis;
|
||||
this.yAxis = yAxis;
|
||||
this.zAxis = zAxis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to find what corner is at the 3 sides.
|
||||
* This method assumes you pass in the X axis side, Y axis side, and Z axis side,
|
||||
* it will NOT complain about an invalid side, you will just get garbage data.
|
||||
* This method also does not care what order the 3 axes are in.
|
||||
*
|
||||
* @param sideA Side one.
|
||||
* @param sideB Side two.
|
||||
* @param sideC Side three.
|
||||
*
|
||||
* @return The corner at the 3 sides.
|
||||
*/
|
||||
public static Corner fromSides( int sideA, int sideB, int sideC )
|
||||
{
|
||||
// <3 Chicken-Bones.
|
||||
return values()[sideMask[sideA] | sideMask[sideB] | sideMask[sideC]];
|
||||
}
|
||||
|
||||
public float pX( AxisAlignedBB box )
|
||||
{
|
||||
return (float) ( this.xAxis == NEGATIVE ? box.minX : box.maxX );
|
||||
}
|
||||
|
||||
public float pY( AxisAlignedBB box )
|
||||
{
|
||||
return (float) ( this.yAxis == NEGATIVE ? box.minY : box.maxY );
|
||||
}
|
||||
|
||||
public float pZ( AxisAlignedBB box )
|
||||
{
|
||||
return (float) ( this.zAxis == NEGATIVE ? box.minZ : box.maxZ );
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+128
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* This file is part of CodeChickenLib.
|
||||
* Copyright (c) 2018, covers1624, All rights reserved.
|
||||
*
|
||||
* CodeChickenLib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CodeChickenLib is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with CodeChickenLib. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.thirdparty.codechicken.lib.model.pipeline.transformers;
|
||||
|
||||
|
||||
import static net.minecraft.util.EnumFacing.AxisDirection.POSITIVE;
|
||||
|
||||
import net.minecraft.util.EnumFacing.AxisDirection;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraftforge.client.model.pipeline.IVertexConsumer;
|
||||
|
||||
import appeng.thirdparty.codechicken.lib.model.Quad.Vertex;
|
||||
import appeng.thirdparty.codechicken.lib.model.pipeline.IPipelineElementFactory;
|
||||
import appeng.thirdparty.codechicken.lib.model.pipeline.QuadTransformer;
|
||||
|
||||
|
||||
/**
|
||||
* This transformer strips quads that are on faces.
|
||||
* Simply set the bounds for the faces, and the strip mask.
|
||||
*
|
||||
* @author covers1624
|
||||
*/
|
||||
public class QuadFaceStripper extends QuadTransformer
|
||||
{
|
||||
|
||||
public static final IPipelineElementFactory<QuadFaceStripper> FACTORY = QuadFaceStripper::new;
|
||||
|
||||
private AxisAlignedBB bounds;
|
||||
private int mask;
|
||||
|
||||
QuadFaceStripper()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public QuadFaceStripper( IVertexConsumer parent, AxisAlignedBB bounds, int mask )
|
||||
{
|
||||
super( parent );
|
||||
this.bounds = bounds;
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* The bounds of the faces,
|
||||
* used as the .. bounds, if all vertices of a quad
|
||||
* lay on the bounds, it is up for stripping.
|
||||
*
|
||||
* @param bounds The bounds.
|
||||
*/
|
||||
public void setBounds( AxisAlignedBB bounds )
|
||||
{
|
||||
this.bounds = bounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* The mask to strip edges.
|
||||
* This is an opt in system,
|
||||
* the mask is simple 'mask = (1 << side)'.
|
||||
*
|
||||
* @param mask The mask.
|
||||
*/
|
||||
public void setMask( int mask )
|
||||
{
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean transform()
|
||||
{
|
||||
if( this.mask == 0 )
|
||||
{
|
||||
return true;// No mask, nothing changes.
|
||||
}
|
||||
// If the bit for this quad is set, then check if we should strip.
|
||||
if( ( this.mask & ( 1 << this.quad.orientation.ordinal() ) ) != 0 )
|
||||
{
|
||||
AxisDirection dir = this.quad.orientation.getAxisDirection();
|
||||
Vertex[] vertices = this.quad.vertices;
|
||||
switch( this.quad.orientation.getAxis() )
|
||||
{
|
||||
case X:
|
||||
{
|
||||
float bound = (float) ( dir == POSITIVE ? this.bounds.maxX : this.bounds.minX );
|
||||
float x1 = vertices[0].vec[0];
|
||||
float x2 = vertices[1].vec[0];
|
||||
float x3 = vertices[2].vec[0];
|
||||
float x4 = vertices[3].vec[0];
|
||||
return x1 != x2 || x2 != x3 || x3 != x4 || x4 != bound;
|
||||
}
|
||||
case Y:
|
||||
{
|
||||
float bound = (float) ( dir == POSITIVE ? this.bounds.maxY : this.bounds.minY );
|
||||
float y1 = vertices[0].vec[1];
|
||||
float y2 = vertices[1].vec[1];
|
||||
float y3 = vertices[2].vec[1];
|
||||
float y4 = vertices[3].vec[1];
|
||||
return y1 != y2 || y2 != y3 || y3 != y4 || y4 != bound;
|
||||
}
|
||||
case Z:
|
||||
{
|
||||
float bound = (float) ( dir == POSITIVE ? this.bounds.maxZ : this.bounds.minZ );
|
||||
float z1 = vertices[0].vec[2];
|
||||
float z2 = vertices[1].vec[2];
|
||||
float z3 = vertices[2].vec[2];
|
||||
float z4 = vertices[3].vec[2];
|
||||
return z1 != z2 || z2 != z3 || z3 != z4 || z4 != bound;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Vendored
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* This file is part of CodeChickenLib.
|
||||
* Copyright (c) 2018, covers1624, All rights reserved.
|
||||
*
|
||||
* CodeChickenLib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CodeChickenLib is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with CodeChickenLib. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.thirdparty.codechicken.lib.model.pipeline.transformers;
|
||||
|
||||
|
||||
import appeng.thirdparty.codechicken.lib.math.InterpHelper;
|
||||
import appeng.thirdparty.codechicken.lib.model.CachedFormat;
|
||||
import appeng.thirdparty.codechicken.lib.model.Quad;
|
||||
import appeng.thirdparty.codechicken.lib.model.Quad.Vertex;
|
||||
import appeng.thirdparty.codechicken.lib.model.pipeline.IPipelineElementFactory;
|
||||
import appeng.thirdparty.codechicken.lib.model.pipeline.QuadTransformer;
|
||||
|
||||
|
||||
/**
|
||||
* This transformer Re-Interpolates the Color, UV's and LightMaps.
|
||||
* Use this after all transformations that translate vertices in the pipeline.
|
||||
*
|
||||
* This Transformation can only be used in the BakedPipeline.
|
||||
*
|
||||
* @author covers1624
|
||||
*/
|
||||
public class QuadReInterpolator extends QuadTransformer
|
||||
{
|
||||
|
||||
public static final IPipelineElementFactory<QuadReInterpolator> FACTORY = QuadReInterpolator::new;
|
||||
|
||||
private Quad interpCache = new Quad();
|
||||
private InterpHelper interpHelper = new InterpHelper();
|
||||
|
||||
QuadReInterpolator()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset( CachedFormat format )
|
||||
{
|
||||
super.reset( format );
|
||||
this.interpCache.reset( format );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputQuad( Quad quad )
|
||||
{
|
||||
super.setInputQuad( quad );
|
||||
quad.resetInterp( this.interpHelper, quad.orientation.ordinal() >> 1 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean transform()
|
||||
{
|
||||
int s = this.quad.orientation.ordinal() >> 1;
|
||||
if( this.format.hasColor || this.format.hasUV || this.format.hasLightMap )
|
||||
{
|
||||
this.interpCache.copyFrom( this.quad );
|
||||
this.interpHelper.setup();
|
||||
for( Vertex v : this.quad.vertices )
|
||||
{
|
||||
this.interpHelper.locate( v.dx( s ), v.dy( s ) );
|
||||
if( this.format.hasColor )
|
||||
{
|
||||
v.interpColorFrom( this.interpHelper, this.interpCache.vertices );
|
||||
}
|
||||
if( this.format.hasUV )
|
||||
{
|
||||
v.interpUVFrom( this.interpHelper, this.interpCache.vertices );
|
||||
}
|
||||
if( this.format.hasLightMap )
|
||||
{
|
||||
v.interpLightMapFrom( this.interpHelper, this.interpCache.vertices );
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Vendored
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* This file is part of CodeChickenLib.
|
||||
* Copyright (c) 2018, covers1624, All rights reserved.
|
||||
*
|
||||
* CodeChickenLib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CodeChickenLib is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with CodeChickenLib. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.thirdparty.codechicken.lib.model.pipeline.transformers;
|
||||
|
||||
|
||||
import net.minecraftforge.client.model.pipeline.IVertexConsumer;
|
||||
|
||||
import appeng.thirdparty.codechicken.lib.model.Quad.Vertex;
|
||||
import appeng.thirdparty.codechicken.lib.model.pipeline.IPipelineElementFactory;
|
||||
import appeng.thirdparty.codechicken.lib.model.pipeline.QuadTransformer;
|
||||
|
||||
|
||||
/**
|
||||
* This transformer tints quads..
|
||||
* Feed it the output of BlockColors.colorMultiplier.
|
||||
*
|
||||
* @author covers1624
|
||||
*/
|
||||
public class QuadTinter extends QuadTransformer
|
||||
{
|
||||
|
||||
public static final IPipelineElementFactory<QuadTinter> FACTORY = QuadTinter::new;
|
||||
|
||||
private int tint;
|
||||
|
||||
QuadTinter()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public QuadTinter( IVertexConsumer consumer, int tint )
|
||||
{
|
||||
super( consumer );
|
||||
this.tint = tint;
|
||||
}
|
||||
|
||||
public QuadTinter setTint( int tint )
|
||||
{
|
||||
this.tint = tint;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean transform()
|
||||
{
|
||||
// Nuke tintIndex.
|
||||
this.quad.tintIndex = -1;
|
||||
if( this.format.hasColor )
|
||||
{
|
||||
float r = ( this.tint >> 0x10 & 0xFF ) / 255F;
|
||||
float g = ( this.tint >> 0x08 & 0xFF ) / 255F;
|
||||
float b = ( this.tint & 0xFF ) / 255F;
|
||||
for( Vertex v : this.quad.vertices )
|
||||
{
|
||||
v.color[0] *= r;
|
||||
v.color[1] *= g;
|
||||
v.color[2] *= b;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user