Moving to source sets
This commit is contained in:
@@ -1,298 +0,0 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 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 Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.client.render.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.render.VertexFormat;
|
||||
import net.minecraft.client.render.VertexFormatElement;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.render.model.json.ModelTransformation;
|
||||
import net.minecraft.client.util.math.Vector4f;
|
||||
import net.minecraft.client.render.model.BakedQuad;
|
||||
import net.minecraft.client.render.model.json.ModelOverrideList;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
|
||||
import net.minecraftforge.client.model.pipeline.BakedQuadBuilder;
|
||||
import net.minecraftforge.client.model.pipeline.IVertexConsumer;
|
||||
import net.minecraftforge.client.model.pipeline.QuadGatheringTransformer;
|
||||
|
||||
import appeng.client.render.FacingToRotation;
|
||||
|
||||
public class AutoRotatingBakedModel implements BakedModel {
|
||||
|
||||
private final BakedModel parent;
|
||||
private final LoadingCache<AutoRotatingCacheKey, List<BakedQuad>> quadCache;
|
||||
|
||||
public AutoRotatingBakedModel(BakedModel parent) {
|
||||
this.parent = parent;
|
||||
// 6 (DUNSWE) * 6 (DUNSWE) * 7 (DUNSWE + null) = 252
|
||||
this.quadCache = CacheBuilder.newBuilder().maximumSize(252)
|
||||
.build(new CacheLoader<AutoRotatingCacheKey, List<BakedQuad>>() {
|
||||
@Override
|
||||
public List<BakedQuad> load(AutoRotatingCacheKey key) {
|
||||
return AutoRotatingBakedModel.this.getRotatedModel(key.getBlockState(), key.getSide(),
|
||||
new Random(0), key.getModelData());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private List<BakedQuad> getRotatedModel(BlockState state, Direction side, Random rand, AEModelData modelData) {
|
||||
FacingToRotation f2r = FacingToRotation.get(modelData.getForward(), modelData.getUp());
|
||||
|
||||
if (f2r.isRedundant()) {
|
||||
return AutoRotatingBakedModel.this.parent.getQuads(state, side, rand, modelData);
|
||||
}
|
||||
|
||||
List<BakedQuad> original = AutoRotatingBakedModel.this.parent.getQuads(state, f2r.resultingRotate(side), rand,
|
||||
modelData);
|
||||
List<BakedQuad> rotated = new ArrayList<>(original.size());
|
||||
for (BakedQuad quad : original) {
|
||||
BakedQuadBuilder builder = new BakedQuadBuilder();
|
||||
VertexRotator rot = new VertexRotator(f2r, quad.getFace());
|
||||
rot.setParent(builder);
|
||||
quad.pipe(rot);
|
||||
if (quad.getFace() != null) {
|
||||
builder.setQuadOrientation(f2r.rotate(quad.getFace()));
|
||||
} else {
|
||||
builder.setQuadOrientation(null);
|
||||
|
||||
}
|
||||
BakedQuad unpackedQuad = builder.build();
|
||||
|
||||
// Make a copy of it to resolve the vertex data and throw away the unpacked
|
||||
// stuff
|
||||
// This also fixes a bug in Forge's UnpackedBakedQuad, which unpacks a
|
||||
// byte-based normal like 0,0,-1
|
||||
// to 0,0,-0.99607843. We replace these normals with the proper 0,0,-1 when
|
||||
// rotation, which
|
||||
// causes a bug in the AO lighter, if an unpacked quad pipes this value back to
|
||||
// it.
|
||||
// Packing it back to the vanilla vertex format will fix this inconsistency
|
||||
// because it converts
|
||||
// the normal back to a byte-based format, which then re-applies Forge's own bug
|
||||
// when piping it
|
||||
// to the AO lighter, thus fixing our problem.
|
||||
BakedQuad packedQuad = new BakedQuad(unpackedQuad.getVertexData(), quad.getColorIndex(),
|
||||
unpackedQuad.getFace(), quad.func_187508_a(), quad.shouldApplyDiffuseLighting());
|
||||
rotated.add(packedQuad);
|
||||
}
|
||||
return rotated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useAmbientOcclusion() {
|
||||
return this.parent.useAmbientOcclusion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDepth() {
|
||||
return this.parent.hasDepth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSideLit() {
|
||||
return parent.isSideLit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltin() {
|
||||
return this.parent.isBuiltin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sprite getSprite() {
|
||||
return this.parent.getSprite();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public ModelTransformation getTransformation() {
|
||||
return parent.getTransformation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelOverrideList getOverrides() {
|
||||
return parent.getOverrides();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, Random rand) {
|
||||
return getQuads(state, side, rand, EmptyModelData.INSTANCE);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand,
|
||||
@Nonnull IModelData extraData) {
|
||||
|
||||
if (!(extraData instanceof AEModelData)) {
|
||||
return this.parent.getQuads(state, side, rand, extraData);
|
||||
}
|
||||
|
||||
AEModelData aeModelData = (AEModelData) extraData;
|
||||
|
||||
if (aeModelData.isCacheable()) {
|
||||
return quadCache.getUnchecked(new AutoRotatingCacheKey(state, aeModelData, side));
|
||||
} else {
|
||||
return this.getRotatedModel(state, side, rand, aeModelData);
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public IModelData getModelData(@Nonnull BlockRenderView world, @Nonnull BlockPos pos, @Nonnull BlockState state,
|
||||
@Nonnull IModelData tileData) {
|
||||
return this.parent.getModelData(world, pos, state, tileData);
|
||||
}
|
||||
|
||||
public static class VertexRotator extends QuadGatheringTransformer {
|
||||
private final FacingToRotation f2r;
|
||||
private final Direction face;
|
||||
|
||||
public VertexRotator(FacingToRotation f2r, Direction face) {
|
||||
this.f2r = f2r;
|
||||
this.face = face;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParent(IVertexConsumer parent) {
|
||||
super.setParent(parent);
|
||||
if (Objects.equal(this.getVertexFormat(), parent.getVertexFormat())) {
|
||||
return;
|
||||
}
|
||||
this.setVertexFormat(parent.getVertexFormat());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processQuad() {
|
||||
VertexFormat format = this.parent.getVertexFormat();
|
||||
ImmutableList<VertexFormatElement> elements = format.getElements();
|
||||
|
||||
for (int v = 0; v < 4; v++) {
|
||||
for (int e = 0; e < elements.size(); e++) {
|
||||
VertexFormatElement element = elements.get(e);
|
||||
if (element.getType() == VertexFormatElement.Usage.POSITION) {
|
||||
this.parent.put(e, this.transform(this.quadData[e][v]));
|
||||
} else if (element.getType() == VertexFormatElement.Usage.NORMAL) {
|
||||
this.parent.put(e, this.transformNormal(this.quadData[e][v]));
|
||||
} else {
|
||||
this.parent.put(e, this.quadData[e][v]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float[] transform(float[] fs) {
|
||||
switch (fs.length) {
|
||||
case 3:
|
||||
Vector4f vec = new Vector4f(fs[0], fs[1], fs[2], 1);
|
||||
vec.setX(vec.getX() - 0.5f);
|
||||
vec.setY(vec.getY() - 0.5f);
|
||||
vec.setZ(vec.getZ() - 0.5f);
|
||||
vec.transform(this.f2r.getMat());
|
||||
vec.setX(vec.getX() + 0.5f);
|
||||
vec.setY(vec.getY() + 0.5f);
|
||||
vec.setZ(vec.getZ() + 0.5f);
|
||||
return new float[] { vec.getX(), vec.getY(), vec.getZ() };
|
||||
case 4:
|
||||
Vector4f vecc = new Vector4f(fs[0], fs[1], fs[2], fs[3]);
|
||||
vecc.setX(vecc.getX() - 0.5f);
|
||||
vecc.setY(vecc.getY() - 0.5f);
|
||||
vecc.setZ(vecc.getZ() - 0.5f);
|
||||
vecc.transform(this.f2r.getMat());
|
||||
vecc.setX(vecc.getX() + 0.5f);
|
||||
vecc.setY(vecc.getY() + 0.5f);
|
||||
vecc.setZ(vecc.getZ() + 0.5f);
|
||||
return new float[] { vecc.getX(), vecc.getY(), vecc.getZ(), vecc.getW() };
|
||||
|
||||
default:
|
||||
return fs;
|
||||
}
|
||||
}
|
||||
|
||||
private float[] transformNormal(float[] fs) {
|
||||
if (this.face == null) {
|
||||
switch (fs.length) {
|
||||
case 3:
|
||||
Vector4f vec = new Vector4f(fs[0], fs[1], fs[2], 0);
|
||||
vec.transform(this.f2r.getMat());
|
||||
return new float[] { vec.getX(), vec.getY(), vec.getZ() };
|
||||
case 4:
|
||||
Vector4f vec4 = new Vector4f(fs[0], fs[1], fs[2], fs[3]);
|
||||
vec4.transform(this.f2r.getMat());
|
||||
return new float[] { vec4.getX(), vec4.getY(), vec4.getZ(), 0 };
|
||||
|
||||
default:
|
||||
return fs;
|
||||
}
|
||||
} else {
|
||||
switch (fs.length) {
|
||||
case 3:
|
||||
Vec3i vec = this.f2r.rotate(this.face).getVector();
|
||||
return new float[] { vec.getX(), vec.getY(), vec.getZ() };
|
||||
case 4:
|
||||
Vector4f veccc = new Vector4f(fs[0], fs[1], fs[2], fs[3]);
|
||||
Vec3i vecc = this.f2r.rotate(this.face).getVector();
|
||||
return new float[] { vecc.getX(), vecc.getY(), vecc.getZ(), veccc.getW() };
|
||||
|
||||
default:
|
||||
return fs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setQuadTint(int tint) {
|
||||
this.parent.setQuadTint(tint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setQuadOrientation(Direction orientation) {
|
||||
this.parent.setQuadOrientation(f2r.rotate(orientation));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplyDiffuseLighting(boolean diffuse) {
|
||||
this.parent.setApplyDiffuseLighting(diffuse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTexture(Sprite texture) {
|
||||
this.parent.setTexture(texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user