Implemented the sky compass.
This commit is contained in:
parent
d1ccb126b6
commit
576923a2f2
|
@ -24,12 +24,17 @@ import java.util.List;
|
|||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.state.BlockStateContainer;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.EnumBlockRenderType;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.property.ExtendedBlockState;
|
||||
import net.minecraftforge.common.property.IUnlistedProperty;
|
||||
import net.minecraftforge.common.property.PropertyFloat;
|
||||
|
||||
import appeng.block.AEBaseTileBlock;
|
||||
import appeng.helpers.ICustomCollision;
|
||||
|
@ -38,12 +43,22 @@ import appeng.tile.misc.TileSkyCompass;
|
|||
public class BlockSkyCompass extends AEBaseTileBlock implements ICustomCollision
|
||||
{
|
||||
|
||||
// Rotation is expressed as radians
|
||||
public static final PropertyFloat ROTATION = new PropertyFloat( "rotation" );
|
||||
|
||||
public BlockSkyCompass()
|
||||
{
|
||||
super( Material.IRON );
|
||||
super( Material.CIRCUITS );
|
||||
this.setTileEntity( TileSkyCompass.class );
|
||||
this.setOpaque( this.setFullSize( false ) );
|
||||
this.lightOpacity = 0;
|
||||
this.setLightOpacity( 0 );
|
||||
this.setFullSize( false );
|
||||
this.setOpaque( false );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockStateContainer createBlockState()
|
||||
{
|
||||
return new ExtendedBlockState( this, getAEStates(), new IUnlistedProperty[] { ROTATION } );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -66,7 +81,7 @@ public class BlockSkyCompass extends AEBaseTileBlock implements ICustomCollision
|
|||
public void neighborChanged( final IBlockState state, final World w, final BlockPos pos, final Block neighborBlock )
|
||||
{
|
||||
final TileSkyCompass sc = this.getTileEntity( w, pos );
|
||||
final EnumFacing up = sc.getForward();
|
||||
final EnumFacing up = sc.getUp();
|
||||
if( !this.canPlaceAt( w, pos, up.getOpposite() ) )
|
||||
{
|
||||
this.dropTorch( w, pos );
|
||||
|
@ -99,7 +114,7 @@ public class BlockSkyCompass extends AEBaseTileBlock implements ICustomCollision
|
|||
final TileSkyCompass tile = this.getTileEntity( w, pos );
|
||||
if( tile != null )
|
||||
{
|
||||
final EnumFacing forward = tile.getForward();
|
||||
final EnumFacing forward = tile.getUp();
|
||||
|
||||
double minX = 0;
|
||||
double minY = 0;
|
||||
|
@ -160,4 +175,17 @@ public class BlockSkyCompass extends AEBaseTileBlock implements ICustomCollision
|
|||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumBlockRenderType getRenderType( IBlockState state )
|
||||
{
|
||||
return EnumBlockRenderType.ENTITYBLOCK_ANIMATED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullBlock( IBlockState state )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package appeng.block.misc;
|
||||
|
||||
|
||||
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
||||
|
||||
import appeng.bootstrap.BlockRenderingCustomizer;
|
||||
import appeng.bootstrap.IBlockRendering;
|
||||
import appeng.bootstrap.IItemRendering;
|
||||
import appeng.client.render.model.SkyCompassModel;
|
||||
import appeng.client.render.tesr.SkyCompassTESR;
|
||||
|
||||
|
||||
public class SkyCompassRendering extends BlockRenderingCustomizer
|
||||
{
|
||||
|
||||
private static final ModelResourceLocation ITEM_MODEL = new ModelResourceLocation( "appliedenergistics2:sky_compass", "normal" );
|
||||
|
||||
@Override
|
||||
public void customize( IBlockRendering rendering, IItemRendering itemRendering )
|
||||
{
|
||||
rendering.tesr( new SkyCompassTESR() );
|
||||
// This disables the default smart-rotating model
|
||||
rendering.modelCustomizer( ( loc, model ) -> model );
|
||||
itemRendering.model( ITEM_MODEL );
|
||||
itemRendering.builtInModel( "models/block/builtin/sky_compass", new SkyCompassModel() );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* 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 javax.vecmath.Matrix4f;
|
||||
import javax.vecmath.Vector4f;
|
||||
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormatElement;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.client.model.pipeline.QuadGatheringTransformer;
|
||||
|
||||
|
||||
/**
|
||||
* Applies an arbitrary transformation matrix to the vertices of a quad.
|
||||
*/
|
||||
final class MatrixVertexTransformer extends QuadGatheringTransformer
|
||||
{
|
||||
|
||||
private final Matrix4f transform;
|
||||
|
||||
public MatrixVertexTransformer( Matrix4f transform )
|
||||
{
|
||||
this.transform = transform;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processQuad()
|
||||
{
|
||||
VertexFormat format = parent.getVertexFormat();
|
||||
int count = format.getElementCount();
|
||||
|
||||
for( int v = 0; v < 4; v++ )
|
||||
{
|
||||
for( int e = 0; e < count; e++ )
|
||||
{
|
||||
VertexFormatElement element = format.getElement( e );
|
||||
if( element.getUsage() == VertexFormatElement.EnumUsage.POSITION )
|
||||
{
|
||||
parent.put( e, transform( quadData[e][v] ) );
|
||||
}
|
||||
else if( element.getUsage() == VertexFormatElement.EnumUsage.NORMAL )
|
||||
{
|
||||
parent.put( e, transformNormal( quadData[e][v] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
parent.put( e, quadData[e][v] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setQuadTint( int tint )
|
||||
{
|
||||
parent.setQuadTint( tint );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setQuadOrientation( EnumFacing orientation )
|
||||
{
|
||||
parent.setQuadOrientation( orientation );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplyDiffuseLighting( boolean diffuse )
|
||||
{
|
||||
parent.setApplyDiffuseLighting( diffuse );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTexture( TextureAtlasSprite texture )
|
||||
{
|
||||
parent.setTexture( texture );
|
||||
}
|
||||
|
||||
private float[] transform( float[] fs )
|
||||
{
|
||||
switch( fs.length )
|
||||
{
|
||||
case 3:
|
||||
javax.vecmath.Vector3f vec = new javax.vecmath.Vector3f( fs[0], fs[1], fs[2] );
|
||||
vec.x -= 0.5f;
|
||||
vec.y -= 0.5f;
|
||||
vec.z -= 0.5f;
|
||||
transform.transform( vec );
|
||||
vec.x += 0.5f;
|
||||
vec.y += 0.5f;
|
||||
vec.z += 0.5f;
|
||||
return new float[] {
|
||||
vec.x,
|
||||
vec.y,
|
||||
vec.z
|
||||
};
|
||||
case 4:
|
||||
Vector4f vecc = new Vector4f( fs[0], fs[1], fs[2], fs[3] );
|
||||
vecc.x -= 0.5f;
|
||||
vecc.y -= 0.5f;
|
||||
vecc.z -= 0.5f;
|
||||
transform.transform( vecc );
|
||||
vecc.x += 0.5f;
|
||||
vecc.y += 0.5f;
|
||||
vecc.z += 0.5f;
|
||||
return new float[] {
|
||||
vecc.x,
|
||||
vecc.y,
|
||||
vecc.z,
|
||||
vecc.w
|
||||
};
|
||||
|
||||
default:
|
||||
return fs;
|
||||
}
|
||||
}
|
||||
|
||||
private float[] transformNormal( float[] fs )
|
||||
{
|
||||
Vector4f normal;
|
||||
|
||||
switch( fs.length )
|
||||
{
|
||||
case 3:
|
||||
normal = new Vector4f( fs[0], fs[1], fs[2], 0 );
|
||||
this.transform.transform( normal );
|
||||
normal.normalize();
|
||||
return new float[] {
|
||||
normal.x,
|
||||
normal.y,
|
||||
normal.z
|
||||
};
|
||||
|
||||
case 4:
|
||||
normal = new Vector4f( fs[0], fs[1], fs[2], fs[3] );
|
||||
this.transform.transform( normal );
|
||||
normal.normalize();
|
||||
return new float[] {
|
||||
normal.x,
|
||||
normal.y,
|
||||
normal.z,
|
||||
normal.w
|
||||
};
|
||||
|
||||
default:
|
||||
return fs;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
* 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.Collections;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.vecmath.AxisAngle4f;
|
||||
import javax.vecmath.Matrix4f;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
|
||||
import net.minecraft.client.renderer.block.model.ItemOverrideList;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
|
||||
import appeng.block.misc.BlockSkyCompass;
|
||||
import appeng.hooks.CompassManager;
|
||||
import appeng.hooks.CompassResult;
|
||||
|
||||
|
||||
/**
|
||||
* This baked model combines the quads of a compass base and the quads of a compass pointer, which will be rotated
|
||||
* around the Y-axis to get the compass to point in the right direction.
|
||||
*/
|
||||
public class SkyCompassBakedModel implements IBakedModel
|
||||
{
|
||||
|
||||
private final IBakedModel base;
|
||||
|
||||
private final IBakedModel pointer;
|
||||
|
||||
private float fallbackRotation = 0;
|
||||
|
||||
public SkyCompassBakedModel( IBakedModel base, IBakedModel pointer )
|
||||
{
|
||||
this.base = base;
|
||||
this.pointer = pointer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand )
|
||||
{
|
||||
float rotation = 0;
|
||||
// Get rotation from the special block state
|
||||
if( state instanceof IExtendedBlockState )
|
||||
{
|
||||
Float rotationOpt = ( (IExtendedBlockState) state ).getValue( BlockSkyCompass.ROTATION );
|
||||
if( rotationOpt != null )
|
||||
{
|
||||
rotation = rotationOpt;
|
||||
}
|
||||
}
|
||||
else if( state == null )
|
||||
{
|
||||
// This is used to render a compass pointing in a specific direction when being held in hand
|
||||
rotation = fallbackRotation;
|
||||
}
|
||||
|
||||
// Pre-compute the quad count to avoid list resizes
|
||||
List<BakedQuad> quads = new ArrayList<>();
|
||||
|
||||
quads.addAll( base.getQuads( state, side, rand ) );
|
||||
|
||||
// We'll add the pointer as "sideless"
|
||||
if( side == null )
|
||||
{
|
||||
// Set up the rotation around the Y-axis for the pointer
|
||||
Matrix4f matrix = new Matrix4f();
|
||||
matrix.setIdentity();
|
||||
matrix.setRotation( new AxisAngle4f( 0, 1, 0, rotation ) );
|
||||
|
||||
MatrixVertexTransformer transformer = new MatrixVertexTransformer( matrix );
|
||||
for( BakedQuad bakedQuad : pointer.getQuads( state, side, rand ) )
|
||||
{
|
||||
UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder( bakedQuad.getFormat() );
|
||||
|
||||
transformer.setParent( builder );
|
||||
transformer.setVertexFormat( builder.getVertexFormat() );
|
||||
bakedQuad.pipe( transformer );
|
||||
builder.setQuadOrientation( null ); // After rotation, facing a specific side cannot be guaranteed anymore
|
||||
BakedQuad q = builder.build();
|
||||
quads.add( q );
|
||||
}
|
||||
}
|
||||
|
||||
return quads;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAmbientOcclusion()
|
||||
{
|
||||
return base.isAmbientOcclusion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGui3d()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltInRenderer()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite getParticleTexture()
|
||||
{
|
||||
return base.getParticleTexture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemCameraTransforms getItemCameraTransforms()
|
||||
{
|
||||
return base.getItemCameraTransforms();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemOverrideList getOverrides()
|
||||
{
|
||||
/*
|
||||
This handles setting the rotation of the compass when being held in hand. If it's not held in hand, it'll animate using the
|
||||
spinning animation.
|
||||
*/
|
||||
return new ItemOverrideList( Collections.emptyList() )
|
||||
{
|
||||
|
||||
@Override
|
||||
public IBakedModel handleItemState( IBakedModel originalModel, ItemStack stack, World world, EntityLivingBase entity )
|
||||
{
|
||||
if( world != null && entity instanceof EntityPlayerSP )
|
||||
{
|
||||
EntityPlayer player = (EntityPlayer) entity;
|
||||
|
||||
float offRads = (float) ( player.rotationYaw / 180.0f * (float) Math.PI + Math.PI );
|
||||
|
||||
fallbackRotation = offRads + getAnimatedRotation( player.getPosition(), true );
|
||||
}
|
||||
else
|
||||
{
|
||||
fallbackRotation = getAnimatedRotation( null, false );
|
||||
}
|
||||
|
||||
return originalModel;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the effective, animated rotation for the compass given the current position of the compass.
|
||||
*/
|
||||
public static float getAnimatedRotation( @Nullable BlockPos pos, boolean prefetch )
|
||||
{
|
||||
|
||||
// Only query for a meteor position if we know our own position
|
||||
if( pos != null )
|
||||
{
|
||||
CompassResult cr = CompassManager.INSTANCE.getCompassDirection( 0, pos.getX(), pos.getY(), pos.getZ() );
|
||||
|
||||
// Prefetch meteor positions from the server for adjacent blocks so they are available more quickly when we're moving
|
||||
if( prefetch )
|
||||
{
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
for( int j = 0; j < 3; j++ )
|
||||
{
|
||||
CompassManager.INSTANCE.getCompassDirection( 0, pos.getX() + i - 1, pos.getY(), pos.getZ() + j - 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( cr.isValidResult() )
|
||||
{
|
||||
if( cr.isSpin() )
|
||||
{
|
||||
long timeMillis = System.currentTimeMillis();
|
||||
// .5 seconds per full rotation
|
||||
timeMillis %= 500;
|
||||
return timeMillis / 500.f * (float) Math.PI * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (float) cr.getRad();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long timeMillis = System.currentTimeMillis();
|
||||
// 3 seconds per full rotation
|
||||
timeMillis %= 3000;
|
||||
return timeMillis / 3000.f * (float) Math.PI * 2;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* 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.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.model.IModel;
|
||||
import net.minecraftforge.client.model.ModelLoaderRegistry;
|
||||
import net.minecraftforge.common.model.IModelState;
|
||||
import net.minecraftforge.common.model.TRSRTransformation;
|
||||
|
||||
|
||||
/**
|
||||
* The parent model for the compass baked model. Declares the dependencies for the base and pointer submodels mostly.
|
||||
*/
|
||||
public class SkyCompassModel implements IModel
|
||||
{
|
||||
|
||||
private static final ResourceLocation MODEL_BASE = new ResourceLocation( "appliedenergistics2:block/sky_compass_base" );
|
||||
|
||||
private static final ResourceLocation MODEL_POINTER = new ResourceLocation( "appliedenergistics2:block/sky_compass_pointer" );
|
||||
|
||||
private static final List<ResourceLocation> DEPENDENCIES = ImmutableList.of( MODEL_BASE, MODEL_POINTER );
|
||||
|
||||
@Override
|
||||
public Collection<ResourceLocation> getDependencies()
|
||||
{
|
||||
return DEPENDENCIES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ResourceLocation> getTextures()
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBakedModel bake( IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
|
||||
{
|
||||
IModel baseModel, pointerModel;
|
||||
try
|
||||
{
|
||||
baseModel = ModelLoaderRegistry.getModel( MODEL_BASE );
|
||||
pointerModel = ModelLoaderRegistry.getModel( MODEL_POINTER );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
throw new RuntimeException( e );
|
||||
}
|
||||
|
||||
IBakedModel bakedBase = baseModel.bake( state, format, bakedTextureGetter );
|
||||
IBakedModel bakedPointer = pointerModel.bake( state, format, bakedTextureGetter );
|
||||
return new SkyCompassBakedModel( bakedBase, bakedPointer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IModelState getDefaultState()
|
||||
{
|
||||
return TRSRTransformation.identity();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* 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.tesr;
|
||||
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher;
|
||||
import net.minecraft.client.renderer.VertexBuffer;
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraftforge.client.MinecraftForgeClient;
|
||||
import net.minecraftforge.client.model.animation.FastTESR;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
import net.minecraftforge.common.property.Properties;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
import appeng.block.misc.BlockSkyCompass;
|
||||
import appeng.client.render.model.SkyCompassBakedModel;
|
||||
import appeng.tile.misc.TileSkyCompass;
|
||||
|
||||
|
||||
@SideOnly( Side.CLIENT )
|
||||
public class SkyCompassTESR extends FastTESR<TileSkyCompass>
|
||||
{
|
||||
|
||||
private static BlockRendererDispatcher blockRenderer;
|
||||
|
||||
@Override
|
||||
public void renderTileEntityFast( TileSkyCompass te, double x, double y, double z, float partialTicks, int destroyStage, VertexBuffer buffer )
|
||||
{
|
||||
|
||||
if( !te.hasWorldObj() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( blockRenderer == null )
|
||||
{
|
||||
blockRenderer = Minecraft.getMinecraft().getBlockRendererDispatcher();
|
||||
}
|
||||
|
||||
BlockPos pos = te.getPos();
|
||||
IBlockAccess world = MinecraftForgeClient.getRegionRenderCache( te.getWorld(), pos );
|
||||
IBlockState state = world.getBlockState( pos );
|
||||
if( state.getPropertyNames().contains( Properties.StaticProperty ) )
|
||||
{
|
||||
state = state.withProperty( Properties.StaticProperty, false );
|
||||
}
|
||||
|
||||
if( state instanceof IExtendedBlockState )
|
||||
{
|
||||
IExtendedBlockState exState = (IExtendedBlockState) state;
|
||||
|
||||
IBakedModel model = blockRenderer.getBlockModelShapes().getModelForState( exState.getClean() );
|
||||
exState = exState.withProperty( BlockSkyCompass.ROTATION, getRotation( te ) );
|
||||
|
||||
buffer.setTranslation( x - pos.getX(), y - pos.getY(), z - pos.getZ() );
|
||||
|
||||
blockRenderer.getBlockModelRenderer().renderModel( world, model, exState, pos, buffer, false );
|
||||
}
|
||||
}
|
||||
|
||||
private static float getRotation( TileSkyCompass skyCompass )
|
||||
{
|
||||
float rotation;
|
||||
|
||||
if( skyCompass.getUp() == EnumFacing.UP || skyCompass.getUp() == EnumFacing.DOWN )
|
||||
{
|
||||
rotation = SkyCompassBakedModel.getAnimatedRotation( skyCompass.getPos(), false );
|
||||
}
|
||||
else
|
||||
{
|
||||
rotation = SkyCompassBakedModel.getAnimatedRotation( null, false );
|
||||
}
|
||||
|
||||
if( skyCompass.getUp() == EnumFacing.DOWN )
|
||||
{
|
||||
rotation = flipidiy( rotation );
|
||||
}
|
||||
|
||||
return rotation;
|
||||
}
|
||||
|
||||
private static float flipidiy( float rad )
|
||||
{
|
||||
float x = (float) Math.cos( rad );
|
||||
float y = (float) Math.sin( rad );
|
||||
return (float) Math.atan2( -y, x );
|
||||
}
|
||||
}
|
|
@ -52,6 +52,7 @@ import appeng.block.misc.BlockSecurityStation;
|
|||
import appeng.block.misc.BlockSkyCompass;
|
||||
import appeng.block.misc.BlockTinyTNT;
|
||||
import appeng.block.misc.BlockVibrationChamber;
|
||||
import appeng.block.misc.SkyCompassRendering;
|
||||
import appeng.block.networking.BlockCableBus;
|
||||
import appeng.block.networking.BlockController;
|
||||
import appeng.block.networking.BlockCreativeEnergyCell;
|
||||
|
@ -236,7 +237,10 @@ public final class ApiBlocks implements IBlocks
|
|||
.rendering( new SkyChestRenderingCustomizer( SkyChestType.BLOCK ) )
|
||||
.build();
|
||||
|
||||
this.skyCompass = registry.block( "sky_compass", BlockSkyCompass::new ).features( AEFeature.MeteoriteCompass ).build();
|
||||
this.skyCompass = registry.block( "sky_compass", BlockSkyCompass::new )
|
||||
.features( AEFeature.MeteoriteCompass )
|
||||
.rendering( new SkyCompassRendering() )
|
||||
.build();
|
||||
this.grindstone = registry.block( "grindstone", BlockGrinder::new ).features( AEFeature.GrindStone ).build();
|
||||
this.crank = registry.block( "crank", BlockCrank::new )
|
||||
.features( AEFeature.GrindStone )
|
||||
|
|
|
@ -30,4 +30,11 @@ public class TileSkyCompass extends AEBaseTile
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFastRenderer()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"variants": {
|
||||
"normal": { "model": "appliedenergistics2:builtin/sky_compass" }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
{
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"particle": "appliedenergistics2:blocks/sky_compass",
|
||||
"0": "appliedenergistics2:blocks/sky_compass"
|
||||
},
|
||||
"display": {
|
||||
"gui": {
|
||||
"rotation": [ 30, 225, 0 ],
|
||||
"translation": [ 0, 8, 0],
|
||||
"scale":[ 1.5, 1.5, 1.5 ]
|
||||
},
|
||||
"ground": {
|
||||
"rotation": [ 0, 0, 0 ],
|
||||
"translation": [ 0, 3, 0],
|
||||
"scale":[ 0.5, 0.5, 0.5 ]
|
||||
},
|
||||
"fixed": {
|
||||
"rotation": [ 270, 0, 0 ],
|
||||
"translation": [ 0, 0, -10.1 ],
|
||||
"scale":[ 1.5, 1.5, 1.5 ]
|
||||
},
|
||||
"thirdperson_righthand": {
|
||||
"rotation": [ 75, 45, 0 ],
|
||||
"translation": [ 0, 2.5, 2],
|
||||
"scale": [ 0.375, 0.375, 0.375 ]
|
||||
},
|
||||
"firstperson_righthand": {
|
||||
"rotation": [ 10, 0, 0 ],
|
||||
"translation": [ 0, 8, -12 ],
|
||||
"scale": [ 2, 2, 2 ]
|
||||
},
|
||||
"firstperson_lefthand": {
|
||||
"rotation": [ 10, 0, 0 ],
|
||||
"translation": [ 0, 8, -12 ],
|
||||
"scale": [ 2, 2, 2 ]
|
||||
}
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Base",
|
||||
"from": [ 6.0, 0.0, 6.0 ],
|
||||
"to": [ 10.0, 1.0, 10.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#0", "uv": [ 0.0, 4.0, 4.0, 5.0 ] },
|
||||
"east": { "texture": "#0", "uv": [ 4.0, 4.0, 8.0, 5.0 ] },
|
||||
"south": { "texture": "#0", "uv": [ 8.0, 4.0, 12.0, 5.0 ] },
|
||||
"west": { "texture": "#0", "uv": [ 12.0, 4.0, 16.0, 5.0 ] },
|
||||
"up": { "texture": "#0", "uv": [ 6.0, 0.0, 10.0, 4.0 ] },
|
||||
"down": { "texture": "#0", "uv": [ 6.0, 0.0, 10.0, 4.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Border",
|
||||
"from": [ 6.0, 1.0, 5.0 ],
|
||||
"to": [ 10.0, 2.0, 6.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#0", "uv": [ 1.0, 0.0, 5.0, 1.0 ] },
|
||||
"east": { "texture": "#0", "uv": [ 0.0, 1.0, 1.0, 2.0 ] },
|
||||
"south": { "texture": "#0", "uv": [ 5.0, 0.0, 9.0, 1.0 ] },
|
||||
"west": { "texture": "#0", "uv": [ 4.0, 0.0, 5.0, 1.0 ] },
|
||||
"up": { "texture": "#0", "uv": [ 8.0, 0.0, 12.0, 1.0 ] },
|
||||
"down": { "texture": "#0", "uv": [ 8.0, 0.0, 12.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Border",
|
||||
"from": [ 6.0, 1.0, 10.0 ],
|
||||
"to": [ 10.0, 2.0, 11.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#0", "uv": [ 1.0, 0.0, 5.0, 1.0 ] },
|
||||
"east": { "texture": "#0", "uv": [ 0.0, 1.0, 1.0, 2.0 ] },
|
||||
"south": { "texture": "#0", "uv": [ 5.0, 0.0, 9.0, 1.0 ] },
|
||||
"west": { "texture": "#0", "uv": [ 4.0, 0.0, 5.0, 1.0 ] },
|
||||
"up": { "texture": "#0", "uv": [ 8.0, 0.0, 12.0, 1.0 ] },
|
||||
"down": { "texture": "#0", "uv": [ 8.0, 0.0, 12.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Border",
|
||||
"from": [ 10.0, 1.0, 6.0 ],
|
||||
"to": [ 11.0, 2.0, 10.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#0", "uv": [ 2.0, 0.0, 3.0, 1.0 ] },
|
||||
"east": { "texture": "#0", "uv": [ 0.0, 1.0, 4.0, 2.0 ] },
|
||||
"south": { "texture": "#0", "uv": [ 5.0, 0.0, 6.0, 1.0 ] },
|
||||
"west": { "texture": "#0", "uv": [ 4.0, 0.0, 8.0, 1.0 ] },
|
||||
"up": { "texture": "#0", "uv": [ 11.0, 0.0, 12.0, 4.0 ] },
|
||||
"down": { "texture": "#0", "uv": [ 10.0, 0.0, 11.0, 4.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Border",
|
||||
"from": [ 5.0, 1.0, 6.0 ],
|
||||
"to": [ 6.0, 2.0, 10.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#0", "uv": [ 2.0, 0.0, 3.0, 1.0 ] },
|
||||
"east": { "texture": "#0", "uv": [ 0.0, 1.0, 4.0, 2.0 ] },
|
||||
"south": { "texture": "#0", "uv": [ 5.0, 0.0, 6.0, 1.0 ] },
|
||||
"west": { "texture": "#0", "uv": [ 4.0, 0.0, 8.0, 1.0 ] },
|
||||
"up": { "texture": "#0", "uv": [ 9.0, 0.0, 10.0, 4.0 ] },
|
||||
"down": { "texture": "#0", "uv": [ 10.0, 0.0, 11.0, 4.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Nibble",
|
||||
"from": [ 7.5, 1.0, 7.5 ],
|
||||
"to": [ 8.5, 2.0, 8.5 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#0", "uv": [ 4.0, 2.0, 6.0, 4.0 ] },
|
||||
"east": { "texture": "#0", "uv": [ 6.0, 2.0, 8.0, 4.0 ] },
|
||||
"south": { "texture": "#0", "uv": [ 7.0, 2.0, 9.0, 4.0 ] },
|
||||
"west": { "texture": "#0", "uv": [ 8.0, 2.0, 10.0, 4.0 ] },
|
||||
"up": { "texture": "#0", "uv": [ 10.0, 2.0, 12.0, 4.0 ] },
|
||||
"down": { "texture": "#0", "uv": [ 7.0, 2.0, 9.0, 4.0 ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"0": "appliedenergistics2:blocks/sky_compass"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Pointer",
|
||||
"from": [ 7.7, 1.0, 6 ],
|
||||
"to": [ 8.2, 1.5, 8 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#0", "uv": [ 0.0, 5.0, 16.0, 8 ] },
|
||||
"east": { "texture": "#0", "uv": [ 0.0, 5.0, 16, 8 ] },
|
||||
"south": { "texture": "#0", "uv": [ 0.0, 5.0, 16.0, 8 ] },
|
||||
"west": { "texture": "#0", "uv": [ 0.0, 5.0, 16, 8 ] },
|
||||
"up": { "texture": "#0", "uv": [ 0.0, 5.0, 16.0, 8 ] },
|
||||
"down": { "texture": "#0", "uv": [ 0.0, 5.0, 16.0, 8 ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 279 B |
Binary file not shown.
Before Width: | Height: | Size: 294 B |
Loading…
Reference in New Issue