Cable (and general) rendering improvements (fixed some orientation for AO.

This commit is contained in:
Florian Nücke 2015-02-11 17:58:18 +01:00
parent 707a5c728c
commit f547cb6f1f
10 changed files with 187 additions and 129 deletions

View File

@ -36,7 +36,7 @@ object PacketHandler extends CommonPacketHandler {
}
override def dispatch(p: PacketParser) {
p.packetType match {
if (p.player != null && p.player.getEntityWorld != null) p.packetType match {
case PacketType.Analyze => onAnalyze(p)
case PacketType.ChargerState => onChargerState(p)
case PacketType.ColorChange => onColorChange(p)
@ -332,14 +332,14 @@ object PacketHandler extends CommonPacketHandler {
}
def onTextBufferPowerChange(p: PacketParser) =
ComponentTracker.get(p.player.worldObj, p.readUTF()) match {
ComponentTracker.get(p.player.getEntityWorld, p.readUTF()) match {
case Some(buffer: component.TextBuffer) =>
buffer.setRenderingEnabled(p.readBoolean())
case _ => // Invalid packet.
}
def onTextBufferInit(p: PacketParser) {
ComponentTracker.get(p.player.worldObj, p.readUTF()) match {
ComponentTracker.get(p.player.getEntityWorld, p.readUTF()) match {
case Some(buffer: li.cil.oc.common.component.TextBuffer) =>
val nbt = p.readNBT()
if (nbt.hasKey("maxWidth")) {
@ -354,7 +354,7 @@ object PacketHandler extends CommonPacketHandler {
}
def onTextBufferMulti(p: PacketParser) =
ComponentTracker.get(p.player.worldObj, p.readUTF()) match {
ComponentTracker.get(p.player.getEntityWorld, p.readUTF()) match {
case Some(buffer: component.TextBuffer) =>
try while (true) {
p.readPacketType() match {

View File

@ -5,7 +5,7 @@ import li.cil.oc.client.renderer.HighlightRenderer
import li.cil.oc.client.renderer.PetRenderer
import li.cil.oc.client.renderer.TextBufferRenderCache
import li.cil.oc.client.renderer.WirelessNetworkDebugRenderer
import li.cil.oc.client.renderer.block.ExtendedBlockModel
import li.cil.oc.client.renderer.block.ModelInitialization
import li.cil.oc.client.renderer.entity.DroneRenderer
import li.cil.oc.client.renderer.tileentity._
import li.cil.oc.common.component.TextBuffer
@ -16,13 +16,7 @@ import li.cil.oc.common.tileentity.ServerRack
import li.cil.oc.common.{Proxy => CommonProxy}
import li.cil.oc.util.Audio
import net.minecraft.block.Block
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.ItemMeshDefinition
import net.minecraft.client.resources.model.ModelBakery
import net.minecraft.client.resources.model.ModelResourceLocation
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
import net.minecraftforge.client.model.ModelLoader
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.fml.client.registry.ClientRegistry
import net.minecraftforge.fml.client.registry.RenderingRegistry
@ -33,12 +27,7 @@ import net.minecraftforge.fml.common.event.FMLPreInitializationEvent
import net.minecraftforge.fml.common.network.NetworkRegistry
import org.lwjgl.opengl.GLContext
import scala.collection.mutable
private[oc] class Proxy extends CommonProxy {
private val meshableItems = mutable.ArrayBuffer.empty[Item]
private val itemDelegates = mutable.ArrayBuffer.empty[(String, Delegate)]
override def preInit(e: FMLPreInitializationEvent) {
if (Loader.isModLoaded("OpenComponents")) {
throw new OpenComponentsPresentException()
@ -50,20 +39,7 @@ private[oc] class Proxy extends CommonProxy {
MinecraftForge.EVENT_BUS.register(Textures)
MinecraftForge.EVENT_BUS.register(HighlightRenderer)
ExtendedBlockModel.preInit()
}
override def registerModel(instance: Delegate, id: String): Unit = {
itemDelegates += id -> instance
}
override def registerModel(instance: Item, id: String): Unit = {
meshableItems += instance
}
override def registerModel(instance: Block, id: String): Unit = {
val item = Item.getItemFromBlock(instance)
registerModel(item, id)
ModelInitialization.preInit()
}
override def init(e: FMLInitializationEvent) {
@ -71,25 +47,7 @@ private[oc] class Proxy extends CommonProxy {
OpenComputers.channel.register(client.PacketHandler)
val mesher = Minecraft.getMinecraft.getRenderItem.getItemModelMesher
val meshDefinition = new ItemMeshDefinition {
override def getModelLocation(stack: ItemStack) = {
Option(api.Items.get(stack)) match {
case Some(descriptor) => new ModelResourceLocation(Settings.resourceDomain + ":" + descriptor.name(), "inventory")
case _ => null
}
}
}
for (item <- meshableItems) {
mesher.register(item, meshDefinition)
}
meshableItems.clear()
for ((id, item) <- itemDelegates) {
val location = Settings.resourceDomain + ":" + id
mesher.register(item.parent, item.itemId, new ModelResourceLocation(location, "inventory"))
ModelBakery.addVariantName(item.parent, location)
}
itemDelegates.clear()
ModelInitialization.init()
RenderingRegistry.registerEntityRenderingHandler(classOf[Drone], DroneRenderer)
@ -130,4 +88,10 @@ private[oc] class Proxy extends CommonProxy {
FMLCommonHandler.instance.bus.register(PetRenderer)
FMLCommonHandler.instance.bus.register(TextBufferRenderCache)
}
override def registerModel(instance: Delegate, id: String) = ModelInitialization.registerModel(instance, id)
override def registerModel(instance: Item, id: String) = ModelInitialization.registerModel(instance, id)
override def registerModel(instance: Block, id: String) = ModelInitialization.registerModel(instance, id)
}

View File

@ -112,7 +112,7 @@ object CableModel extends SmartBlockModelBase with ISmartItemModel {
}
class ItemModel(val stack: ItemStack) extends SmartBlockModelBase {
override def getFaceQuads(side: EnumFacing) = {
override def getGeneralQuads = {
val faces = mutable.ArrayBuffer.empty[BakedQuad]
faces ++= bakeQuads(Middle, cableTexture, Some(EnumDyeColor.SILVER))

View File

@ -1,57 +0,0 @@
package li.cil.oc.client.renderer.block
import li.cil.oc.Constants
import li.cil.oc.Settings
import li.cil.oc.api
import net.minecraft.block.state.IBlockState
import net.minecraft.client.renderer.block.statemap.StateMapperBase
import net.minecraft.client.resources.model.ModelResourceLocation
import net.minecraft.util.RegistrySimple
import net.minecraftforge.client.event.ModelBakeEvent
import net.minecraftforge.client.model.ModelLoader
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import scala.collection.convert.WrapAsScala._
object ExtendedBlockModel {
final val CableBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Cable, "normal")
final val CableItemLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Cable, "inventory")
final val RobotBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Robot, "normal")
final val RobotItemLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Robot, "inventory")
def preInit(): Unit = {
MinecraftForge.EVENT_BUS.register(this)
registerModel(Constants.BlockName.Cable, CableBlockLocation, CableItemLocation)
registerModel(Constants.BlockName.Robot, RobotBlockLocation, RobotItemLocation)
}
private def registerModel(blockName: String, blockLocation: ModelResourceLocation, itemLocation: ModelResourceLocation): Unit = {
val descriptor = api.Items.get(blockName)
val block = descriptor.block()
val stack = descriptor.createItemStack(1)
ModelLoader.setCustomModelResourceLocation(stack.getItem, stack.getMetadata, itemLocation)
ModelLoader.setCustomStateMapper(block, new StateMapperBase {
override def getModelResourceLocation(state: IBlockState) = blockLocation
})
}
@SubscribeEvent
def onModelBake(e: ModelBakeEvent): Unit = {
val registry = e.modelRegistry.asInstanceOf[RegistrySimple]
registry.putObject(CableBlockLocation, CableModel)
registry.putObject(CableItemLocation, CableModel)
registry.putObject(RobotBlockLocation, RobotModel)
registry.putObject(RobotItemLocation, RobotModel)
registry.getKeys.collect {
case location: ModelResourceLocation =>
if (location.toString.matches("^" + Settings.resourceDomain + ":screen\\d#.*")) {
registry.putObject(location, ScreenModel)
}
}
}
}

View File

@ -0,0 +1,127 @@
package li.cil.oc.client.renderer.block
import li.cil.oc.Constants
import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.common.item.Delegate
import net.minecraft.block.Block
import net.minecraft.block.state.IBlockState
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.ItemMeshDefinition
import net.minecraft.client.renderer.block.statemap.StateMapperBase
import net.minecraft.client.resources.model.ModelBakery
import net.minecraft.client.resources.model.ModelResourceLocation
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
import net.minecraft.util.RegistrySimple
import net.minecraftforge.client.event.ModelBakeEvent
import net.minecraftforge.client.model.ModelLoader
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import scala.collection.convert.WrapAsScala._
import scala.collection.mutable
object ModelInitialization {
final val CableBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Cable, "normal")
final val CableItemLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Cable, "inventory")
final val RobotBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Robot, "normal")
final val RobotItemLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Robot, "inventory")
final val RobotAfterimageBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.RobotAfterimage, "normal")
final val RobotAfterimageItemLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.RobotAfterimage, "inventory")
private val meshableItems = mutable.ArrayBuffer.empty[Item]
private val itemDelegates = mutable.ArrayBuffer.empty[(String, Delegate)]
def preInit(): Unit = {
MinecraftForge.EVENT_BUS.register(this)
registerModel(Constants.BlockName.Cable, CableBlockLocation, CableItemLocation)
registerModel(Constants.BlockName.Robot, RobotBlockLocation, RobotItemLocation)
registerModel(Constants.BlockName.RobotAfterimage, RobotAfterimageBlockLocation, RobotAfterimageItemLocation)
}
def init(): Unit = {
registerItems(meshableItems)
registerSubItems(itemDelegates)
}
// ----------------------------------------------------------------------- //
def registerModel(instance: Delegate, id: String): Unit = {
itemDelegates += id -> instance
}
def registerModel(instance: Item, id: String): Unit = {
meshableItems += instance
}
def registerModel(instance: Block, id: String): Unit = {
val item = Item.getItemFromBlock(instance)
registerModel(item, id)
}
// ----------------------------------------------------------------------- //
private def registerModel(blockName: String, blockLocation: ModelResourceLocation, itemLocation: ModelResourceLocation): Unit = {
val descriptor = api.Items.get(blockName)
val block = descriptor.block()
val stack = descriptor.createItemStack(1)
ModelLoader.setCustomModelResourceLocation(stack.getItem, stack.getMetadata, itemLocation)
ModelLoader.setCustomStateMapper(block, new StateMapperBase {
override def getModelResourceLocation(state: IBlockState) = blockLocation
})
}
private def registerItems(items: mutable.Buffer[Item]): Unit = {
val meshDefinition = new ItemMeshDefinition {
override def getModelLocation(stack: ItemStack) = {
Option(api.Items.get(stack)) match {
case Some(descriptor) =>
val location = Settings.resourceDomain + ":" + descriptor.name()
new ModelResourceLocation(location, "inventory")
case _ => null
}
}
}
val modelMeshes = Minecraft.getMinecraft.getRenderItem.getItemModelMesher
for (item <- items) {
modelMeshes.register(item, meshDefinition)
}
items.clear()
}
private def registerSubItems(items: mutable.Buffer[(String, Delegate)]): Unit = {
val modelMeshes = Minecraft.getMinecraft.getRenderItem.getItemModelMesher
for ((id, item) <- items) {
val location = Settings.resourceDomain + ":" + id
modelMeshes.register(item.parent, item.itemId, new ModelResourceLocation(location, "inventory"))
ModelBakery.addVariantName(item.parent, location)
}
items.clear()
}
// ----------------------------------------------------------------------- //
@SubscribeEvent
def onModelBake(e: ModelBakeEvent): Unit = {
val registry = e.modelRegistry.asInstanceOf[RegistrySimple]
registry.putObject(CableBlockLocation, CableModel)
registry.putObject(CableItemLocation, CableModel)
registry.putObject(RobotBlockLocation, RobotModel)
registry.putObject(RobotItemLocation, RobotModel)
registry.putObject(RobotAfterimageBlockLocation, NullModel)
registry.putObject(RobotAfterimageItemLocation, NullModel)
val screenPattern = "^" + Settings.resourceDomain + ":screen\\d#.*"
registry.getKeys.collect {
case location: ModelResourceLocation =>
if (location.toString.matches(screenPattern)) {
registry.putObject(location, ScreenModel)
}
}
}
}

View File

@ -0,0 +1,14 @@
package li.cil.oc.client.renderer.block
import net.minecraft.block.state.IBlockState
import net.minecraft.item.ItemStack
import net.minecraftforge.client.model.ISmartItemModel
object NullModel extends SmartBlockModelBase with ISmartItemModel {
override def handleBlockState(state: IBlockState) = new Model()
override def handleItemState(stack: ItemStack) = new Model()
class Model extends SmartBlockModelBase
}

View File

@ -9,14 +9,10 @@ import scala.collection.convert.WrapAsJava.bufferAsJavaList
import scala.collection.mutable
object RobotModel extends SmartBlockModelBase with ISmartItemModel {
override def handleBlockState(state: IBlockState) = new BlockModel()
override def handleBlockState(state: IBlockState) = new NullModel.Model()
override def handleItemState(stack: ItemStack) = new ItemModel(stack)
class BlockModel extends SmartBlockModelBase {
// No faces, robots are exclusively rendered via their TESR.
}
class ItemModel(val stack: ItemStack) extends SmartBlockModelBase {
override def getGeneralQuads = {
val faces = mutable.ArrayBuffer.empty[BakedQuad]

View File

@ -56,12 +56,12 @@ trait SmartBlockModelBase extends ISmartBlockModel with ISmartItemModel {
// Standard faces for a unit cube.
protected final val UnitCube = Array(
Array(new Vec3(0, 0, 0), new Vec3(1, 0, 0), new Vec3(1, 0, 1), new Vec3(0, 0, 1)),
Array(new Vec3(0, 1, 1), new Vec3(1, 1, 1), new Vec3(1, 1, 0), new Vec3(0, 1, 0)),
Array(new Vec3(0, 1, 0), new Vec3(1, 1, 0), new Vec3(1, 0, 0), new Vec3(0, 0, 0)),
Array(new Vec3(1, 1, 1), new Vec3(0, 1, 1), new Vec3(0, 0, 1), new Vec3(1, 0, 1)),
Array(new Vec3(0, 1, 1), new Vec3(0, 1, 0), new Vec3(0, 0, 0), new Vec3(0, 0, 1)),
Array(new Vec3(1, 1, 0), new Vec3(1, 1, 1), new Vec3(1, 0, 1), new Vec3(1, 0, 0))
Array(new Vec3(0, 0, 1), new Vec3(0, 0, 0), new Vec3(1, 0, 0), new Vec3(1, 0, 1)),
Array(new Vec3(0, 1, 0), new Vec3(0, 1, 1), new Vec3(1, 1, 1), new Vec3(1, 1, 0)),
Array(new Vec3(1, 1, 0), new Vec3(1, 0, 0), new Vec3(0, 0, 0), new Vec3(0, 1, 0)),
Array(new Vec3(0, 1, 1), new Vec3(0, 0, 1), new Vec3(1, 0, 1), new Vec3(1, 1, 1)),
Array(new Vec3(0, 1, 0), new Vec3(0, 0, 0), new Vec3(0, 0, 1), new Vec3(0, 1, 1)),
Array(new Vec3(1, 1, 1), new Vec3(1, 0, 1), new Vec3(1, 0, 0), new Vec3(1, 1, 0))
)
// Planes perpendicular to facings. Negative values mean we mirror along that,
@ -136,20 +136,36 @@ trait SmartBlockModelBase extends ISmartBlockModel with ISmartItemModel {
u = v
v = (-(tmp - 0.5)) + 0.5
}
rawData(vertex.xCoord, vertex.yCoord, vertex.zCoord, texture, u, v)
rawData(vertex.xCoord, vertex.yCoord, vertex.zCoord, facing, texture, u, v)
}).flatten
}
// See FaceBakery#storeVertexData.
private def rawData(x: Double, y: Double, z: Double, texture: TextureAtlasSprite, u: Double, v: Double) = {
private def rawData(x: Double, y: Double, z: Double, face: EnumFacing, texture: TextureAtlasSprite, u: Double, v: Double) = {
Array(
java.lang.Float.floatToRawIntBits(x.toFloat),
java.lang.Float.floatToRawIntBits(y.toFloat),
java.lang.Float.floatToRawIntBits(z.toFloat),
0xFFFFFFFF,
getFaceShadeColor(face),
java.lang.Float.floatToRawIntBits(texture.getInterpolatedU(u * 16)),
java.lang.Float.floatToRawIntBits(texture.getInterpolatedV(v * 16)),
0
)
}
// See FaceBakery.
private def getFaceShadeColor(face: EnumFacing): Int = {
val brightness = getFaceBrightness(face)
val color = (brightness * 255).toInt max 0 min 255
0xFF000000 | color << 16 | color << 8 | color
}
private def getFaceBrightness(face: EnumFacing): Float = {
face match {
case EnumFacing.DOWN => 0.5f
case EnumFacing.UP => 1.0f
case EnumFacing.NORTH | EnumFacing.SOUTH => 0.8f
case EnumFacing.WEST | EnumFacing.EAST => 0.6f
}
}
}

View File

@ -75,12 +75,6 @@ class Proxy {
api.Machine.add(classOf[LuaJLuaArchitecture])
}
def registerModel(instance: Delegate, id: String): Unit = {}
def registerModel(instance: Item, id: String): Unit = {}
def registerModel(instance: Block, id: String): Unit = {}
def init(e: FMLInitializationEvent) {
OpenComputers.channel = NetworkRegistry.INSTANCE.newEventDrivenChannel("OpenComputers")
OpenComputers.channel.register(server.PacketHandler)
@ -99,6 +93,12 @@ class Proxy {
driver.Registry.locked = true
}
def registerModel(instance: Delegate, id: String): Unit = {}
def registerModel(instance: Item, id: String): Unit = {}
def registerModel(instance: Block, id: String): Unit = {}
private def registerExclusive(name: String, items: ItemStack*) {
if (OreDictionary.getOres(name).isEmpty) {
for (item <- items) {

View File

@ -32,8 +32,6 @@ import net.minecraftforge.fml.relauncher.SideOnly
import scala.collection.mutable.ArrayBuffer
class Cable extends SimpleBlock with traits.Extended {
setLightOpacity(2)
// For Immibis Microblock support.
val ImmibisMicroblocks_TransformableBlockMarker = null