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) { 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.Analyze => onAnalyze(p)
case PacketType.ChargerState => onChargerState(p) case PacketType.ChargerState => onChargerState(p)
case PacketType.ColorChange => onColorChange(p) case PacketType.ColorChange => onColorChange(p)
@ -332,14 +332,14 @@ object PacketHandler extends CommonPacketHandler {
} }
def onTextBufferPowerChange(p: PacketParser) = 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) => case Some(buffer: component.TextBuffer) =>
buffer.setRenderingEnabled(p.readBoolean()) buffer.setRenderingEnabled(p.readBoolean())
case _ => // Invalid packet. case _ => // Invalid packet.
} }
def onTextBufferInit(p: PacketParser) { 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) => case Some(buffer: li.cil.oc.common.component.TextBuffer) =>
val nbt = p.readNBT() val nbt = p.readNBT()
if (nbt.hasKey("maxWidth")) { if (nbt.hasKey("maxWidth")) {
@ -354,7 +354,7 @@ object PacketHandler extends CommonPacketHandler {
} }
def onTextBufferMulti(p: PacketParser) = 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) => case Some(buffer: component.TextBuffer) =>
try while (true) { try while (true) {
p.readPacketType() match { 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.PetRenderer
import li.cil.oc.client.renderer.TextBufferRenderCache import li.cil.oc.client.renderer.TextBufferRenderCache
import li.cil.oc.client.renderer.WirelessNetworkDebugRenderer 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.entity.DroneRenderer
import li.cil.oc.client.renderer.tileentity._ import li.cil.oc.client.renderer.tileentity._
import li.cil.oc.common.component.TextBuffer 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.common.{Proxy => CommonProxy}
import li.cil.oc.util.Audio import li.cil.oc.util.Audio
import net.minecraft.block.Block 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.Item
import net.minecraft.item.ItemStack
import net.minecraftforge.client.model.ModelLoader
import net.minecraftforge.common.MinecraftForge import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.fml.client.registry.ClientRegistry import net.minecraftforge.fml.client.registry.ClientRegistry
import net.minecraftforge.fml.client.registry.RenderingRegistry 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 net.minecraftforge.fml.common.network.NetworkRegistry
import org.lwjgl.opengl.GLContext import org.lwjgl.opengl.GLContext
import scala.collection.mutable
private[oc] class Proxy extends CommonProxy { 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) { override def preInit(e: FMLPreInitializationEvent) {
if (Loader.isModLoaded("OpenComponents")) { if (Loader.isModLoaded("OpenComponents")) {
throw new OpenComponentsPresentException() throw new OpenComponentsPresentException()
@ -50,20 +39,7 @@ private[oc] class Proxy extends CommonProxy {
MinecraftForge.EVENT_BUS.register(Textures) MinecraftForge.EVENT_BUS.register(Textures)
MinecraftForge.EVENT_BUS.register(HighlightRenderer) MinecraftForge.EVENT_BUS.register(HighlightRenderer)
ExtendedBlockModel.preInit() ModelInitialization.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)
} }
override def init(e: FMLInitializationEvent) { override def init(e: FMLInitializationEvent) {
@ -71,25 +47,7 @@ private[oc] class Proxy extends CommonProxy {
OpenComputers.channel.register(client.PacketHandler) OpenComputers.channel.register(client.PacketHandler)
val mesher = Minecraft.getMinecraft.getRenderItem.getItemModelMesher ModelInitialization.init()
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()
RenderingRegistry.registerEntityRenderingHandler(classOf[Drone], DroneRenderer) RenderingRegistry.registerEntityRenderingHandler(classOf[Drone], DroneRenderer)
@ -130,4 +88,10 @@ private[oc] class Proxy extends CommonProxy {
FMLCommonHandler.instance.bus.register(PetRenderer) FMLCommonHandler.instance.bus.register(PetRenderer)
FMLCommonHandler.instance.bus.register(TextBufferRenderCache) 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 { class ItemModel(val stack: ItemStack) extends SmartBlockModelBase {
override def getFaceQuads(side: EnumFacing) = { override def getGeneralQuads = {
val faces = mutable.ArrayBuffer.empty[BakedQuad] val faces = mutable.ArrayBuffer.empty[BakedQuad]
faces ++= bakeQuads(Middle, cableTexture, Some(EnumDyeColor.SILVER)) 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 import scala.collection.mutable
object RobotModel extends SmartBlockModelBase with ISmartItemModel { 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) 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 { class ItemModel(val stack: ItemStack) extends SmartBlockModelBase {
override def getGeneralQuads = { override def getGeneralQuads = {
val faces = mutable.ArrayBuffer.empty[BakedQuad] val faces = mutable.ArrayBuffer.empty[BakedQuad]

View File

@ -56,12 +56,12 @@ trait SmartBlockModelBase extends ISmartBlockModel with ISmartItemModel {
// Standard faces for a unit cube. // Standard faces for a unit cube.
protected final val UnitCube = Array( 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, 0, 1), new Vec3(0, 0, 0), new Vec3(1, 0, 0), new Vec3(1, 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(0, 1, 1), new Vec3(1, 1, 1), new Vec3(1, 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, 0), new Vec3(1, 0, 0), new Vec3(0, 0, 0), new Vec3(0, 1, 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, 0, 1), new Vec3(1, 0, 1), new Vec3(1, 1, 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(0, 1, 0), new Vec3(0, 0, 0), new Vec3(0, 0, 1), new Vec3(0, 1, 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(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, // Planes perpendicular to facings. Negative values mean we mirror along that,
@ -136,20 +136,36 @@ trait SmartBlockModelBase extends ISmartBlockModel with ISmartItemModel {
u = v u = v
v = (-(tmp - 0.5)) + 0.5 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 }).flatten
} }
// See FaceBakery#storeVertexData. // 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( Array(
java.lang.Float.floatToRawIntBits(x.toFloat), java.lang.Float.floatToRawIntBits(x.toFloat),
java.lang.Float.floatToRawIntBits(y.toFloat), java.lang.Float.floatToRawIntBits(y.toFloat),
java.lang.Float.floatToRawIntBits(z.toFloat), java.lang.Float.floatToRawIntBits(z.toFloat),
0xFFFFFFFF, getFaceShadeColor(face),
java.lang.Float.floatToRawIntBits(texture.getInterpolatedU(u * 16)), java.lang.Float.floatToRawIntBits(texture.getInterpolatedU(u * 16)),
java.lang.Float.floatToRawIntBits(texture.getInterpolatedV(v * 16)), java.lang.Float.floatToRawIntBits(texture.getInterpolatedV(v * 16)),
0 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]) 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) { def init(e: FMLInitializationEvent) {
OpenComputers.channel = NetworkRegistry.INSTANCE.newEventDrivenChannel("OpenComputers") OpenComputers.channel = NetworkRegistry.INSTANCE.newEventDrivenChannel("OpenComputers")
OpenComputers.channel.register(server.PacketHandler) OpenComputers.channel.register(server.PacketHandler)
@ -99,6 +93,12 @@ class Proxy {
driver.Registry.locked = true 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*) { private def registerExclusive(name: String, items: ItemStack*) {
if (OreDictionary.getOres(name).isEmpty) { if (OreDictionary.getOres(name).isEmpty) {
for (item <- items) { for (item <- items) {

View File

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