Drone rendering in inventories. Not quite the same as the actual model, but good enough.

This commit is contained in:
Florian Nücke 2015-02-19 22:26:04 +01:00
parent e2625b7d6e
commit a3c592a060
7 changed files with 106 additions and 18 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

View File

@ -9,7 +9,6 @@ import net.minecraft.client.renderer.texture.TextureMap
import net.minecraft.util.ResourceLocation import net.minecraft.util.ResourceLocation
import net.minecraftforge.client.event.TextureStitchEvent import net.minecraftforge.client.event.TextureStitchEvent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import org.lwjgl.opengl.GL11
import scala.collection.mutable import scala.collection.mutable
@ -74,6 +73,7 @@ object Textures {
val UpgradeInventory = L("inventory_upgrade") val UpgradeInventory = L("inventory_upgrade")
val HologramEffect = L("hologram_effect") val HologramEffect = L("hologram_effect")
val Drone = L("drone") val Drone = L("drone")
val DroneItem = L("drone_item")
val Robot = L("robot") val Robot = L("robot")
override protected def basePath = "textures/model/%s.png" override protected def basePath = "textures/model/%s.png"

View File

@ -0,0 +1,42 @@
package li.cil.oc.client.renderer.block
import li.cil.oc.client.Textures
import net.minecraft.block.state.IBlockState
import net.minecraft.client.renderer.block.model.BakedQuad
import net.minecraft.item.ItemStack
import net.minecraft.util.Vec3
import net.minecraftforge.client.model.ISmartItemModel
import scala.collection.convert.WrapAsJava.bufferAsJavaList
import scala.collection.mutable
object DroneModel extends SmartBlockModelBase with ISmartItemModel {
override def handleBlockState(state: IBlockState) = new NullModel.Model()
override def handleItemState(stack: ItemStack) = new ItemModel(stack)
protected def droneTexture = Textures.getSprite(Textures.Model.DroneItem)
protected def Boxes = Array(
makeBox(new Vec3(1f / 16f, 7f / 16f, 1f / 16f), new Vec3(7f / 16f, 8f / 16f, 7f / 16f)),
makeBox(new Vec3(1f / 16f, 7f / 16f, 9f / 16f), new Vec3(7f / 16f, 8f / 16f, 15f / 16f)),
makeBox(new Vec3(9f / 16f, 7f / 16f, 1f / 16f), new Vec3(15f / 16f, 8f / 16f, 7f / 16f)),
makeBox(new Vec3(9f / 16f, 7f / 16f, 9f / 16f), new Vec3(15f / 16f, 8f / 16f, 15f / 16f)),
rotateBox(makeBox(new Vec3(6f / 16f, 6f / 16f, 6f / 16f), new Vec3(10f / 16f, 9f / 16f, 10f / 16f)), 45)
)
class ItemModel(val stack: ItemStack) extends SmartBlockModelBase {
override protected def textureScale = 32f
override def getGeneralQuads = {
val faces = mutable.ArrayBuffer.empty[BakedQuad]
faces ++= Boxes.flatMap(box => bakeQuads(box, Array.fill(6)(droneTexture), None))
Textures.bind(Textures.Model.DroneItem)
bufferAsJavaList(faces)
}
}
}

View File

@ -5,6 +5,7 @@ import li.cil.oc.Settings
import li.cil.oc.api import li.cil.oc.api
import li.cil.oc.common.item.CustomModel import li.cil.oc.common.item.CustomModel
import li.cil.oc.common.item.Delegate import li.cil.oc.common.item.Delegate
import li.cil.oc.common.item.Delegator
import net.minecraft.block.Block import net.minecraft.block.Block
import net.minecraft.block.state.IBlockState import net.minecraft.block.state.IBlockState
import net.minecraft.client.Minecraft import net.minecraft.client.Minecraft
@ -47,9 +48,9 @@ object ModelInitialization {
} }
def init(): Unit = { def init(): Unit = {
registerItems(meshableItems) registerItems()
registerSubItems(itemDelegates) registerSubItems()
registerSubItemsCustom(itemDelegatesCustom) registerSubItemsCustom()
} }
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
@ -83,7 +84,7 @@ object ModelInitialization {
}) })
} }
private def registerItems(items: mutable.Buffer[Item]): Unit = { private def registerItems(): Unit = {
val meshDefinition = new ItemMeshDefinition { val meshDefinition = new ItemMeshDefinition {
override def getModelLocation(stack: ItemStack) = { override def getModelLocation(stack: ItemStack) = {
Option(api.Items.get(stack)) match { Option(api.Items.get(stack)) match {
@ -96,31 +97,33 @@ object ModelInitialization {
} }
val modelMeshes = Minecraft.getMinecraft.getRenderItem.getItemModelMesher val modelMeshes = Minecraft.getMinecraft.getRenderItem.getItemModelMesher
for (item <- items) { for (item <- meshableItems) {
modelMeshes.register(item, meshDefinition) modelMeshes.register(item, meshDefinition)
} }
items.clear() meshableItems.clear()
} }
private def registerSubItems(items: mutable.Buffer[(String, Delegate)]): Unit = { private def registerSubItems(): Unit = {
val modelMeshes = Minecraft.getMinecraft.getRenderItem.getItemModelMesher val modelMeshes = Minecraft.getMinecraft.getRenderItem.getItemModelMesher
for ((id, item) <- items) { for ((id, item) <- itemDelegates) {
val location = Settings.resourceDomain + ":" + id val location = Settings.resourceDomain + ":" + id
modelMeshes.register(item.parent, item.itemId, new ModelResourceLocation(location, "inventory")) modelMeshes.register(item.parent, item.itemId, new ModelResourceLocation(location, "inventory"))
ModelBakery.addVariantName(item.parent, location) ModelBakery.addVariantName(item.parent, location)
} }
items.clear() itemDelegates.clear()
} }
private def registerSubItemsCustom(items: mutable.Buffer[Delegate with CustomModel]): Unit = { private def registerSubItemsCustom(): Unit = {
val modelMeshes = Minecraft.getMinecraft.getRenderItem.getItemModelMesher val modelMeshes = Minecraft.getMinecraft.getRenderItem.getItemModelMesher
for (item <- items) { for (item <- itemDelegatesCustom) {
modelMeshes.register(item.parent, new ItemMeshDefinition { modelMeshes.register(item.parent, new ItemMeshDefinition {
override def getModelLocation(stack: ItemStack): ModelResourceLocation = item.getModelLocation(stack) override def getModelLocation(stack: ItemStack): ModelResourceLocation = Delegator.subItem(stack) match {
case Some(subItem: CustomModel) => subItem.getModelLocation(stack)
case _ => null
}
}) })
item.registerModelLocations() item.registerModelLocations()
} }
items.clear()
} }
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
@ -136,6 +139,10 @@ object ModelInitialization {
registry.putObject(RobotAfterimageBlockLocation, NullModel) registry.putObject(RobotAfterimageBlockLocation, NullModel)
registry.putObject(RobotAfterimageItemLocation, NullModel) registry.putObject(RobotAfterimageItemLocation, NullModel)
for (item <- itemDelegatesCustom) {
item.bakeModels(e)
}
val modelOverrides = Map[String, IFlexibleBakedModel => ISmartBlockModel]( val modelOverrides = Map[String, IFlexibleBakedModel => ISmartBlockModel](
Constants.BlockName.ScreenTier1 -> (_ => ScreenModel), Constants.BlockName.ScreenTier1 -> (_ => ScreenModel),
Constants.BlockName.ScreenTier2 -> (_ => ScreenModel), Constants.BlockName.ScreenTier2 -> (_ => ScreenModel),

View File

@ -78,6 +78,8 @@ trait SmartBlockModelBase extends ISmartBlockModel with ISmartItemModel {
protected final val NoTint = -1 protected final val NoTint = -1
protected def textureScale = 1f
/** /**
* Generates a list of arrays, each containing the four vertices making up a * Generates a list of arrays, each containing the four vertices making up a
* face of the box with the specified size. * face of the box with the specified size.
@ -95,6 +97,24 @@ trait SmartBlockModelBase extends ISmartBlockModel with ISmartItemModel {
math.max(minZ, math.min(maxZ, vertex.zCoord))))) math.max(minZ, math.min(maxZ, vertex.zCoord)))))
} }
protected def rotateVector(v: Vec3, angle: Double, axis: Vec3) = {
// vrot = v * cos(angle) + (axis x v) * sin(angle) + axis * (axis dot v)(1 - cos(angle))
def scale(v: Vec3, s: Double) = new Vec3(v.xCoord * s, v.yCoord * s, v.zCoord * s)
val cosAngle = math.cos(angle)
val sinAngle = math.sin(angle)
scale(v, cosAngle).
add(scale(axis.crossProduct(v), sinAngle)).
add(scale(axis, axis.dotProduct(v) * (1 - cosAngle)))
}
protected def rotateFace(face: Array[Vec3], angle: Double, axis: Vec3, around: Vec3 = new Vec3(0.5, 0.5, 0.5)) = {
face.map(v => rotateVector(v.subtract(around), angle, axis).add(around))
}
protected def rotateBox(box: Array[Array[Vec3]], angle: Double, axis: Vec3 = new Vec3(0, 1, 0), around: Vec3 = new Vec3(0.5, 0.5, 0.5)) = {
box.map(face => rotateFace(face, angle, axis, around))
}
/** /**
* Create the BakedQuads for a set of quads defined by the specified vertices. * Create the BakedQuads for a set of quads defined by the specified vertices.
* <p/> * <p/>
@ -147,8 +167,8 @@ trait SmartBlockModelBase extends ISmartBlockModel with ISmartItemModel {
java.lang.Float.floatToRawIntBits(y.toFloat), java.lang.Float.floatToRawIntBits(y.toFloat),
java.lang.Float.floatToRawIntBits(z.toFloat), java.lang.Float.floatToRawIntBits(z.toFloat),
getFaceShadeColor(face), getFaceShadeColor(face),
java.lang.Float.floatToRawIntBits(u), java.lang.Float.floatToRawIntBits(u * textureScale),
java.lang.Float.floatToRawIntBits(v), java.lang.Float.floatToRawIntBits(v * textureScale),
0 0
) )
} }

View File

@ -2,6 +2,7 @@ package li.cil.oc.common.item
import net.minecraft.client.resources.model.ModelResourceLocation import net.minecraft.client.resources.model.ModelResourceLocation
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraftforge.client.event.ModelBakeEvent
import net.minecraftforge.fml.relauncher.Side import net.minecraftforge.fml.relauncher.Side
import net.minecraftforge.fml.relauncher.SideOnly import net.minecraftforge.fml.relauncher.SideOnly
@ -10,5 +11,8 @@ trait CustomModel {
def getModelLocation(stack: ItemStack): ModelResourceLocation def getModelLocation(stack: ItemStack): ModelResourceLocation
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
def registerModelLocations(): Unit def registerModelLocations(): Unit = {}
@SideOnly(Side.CLIENT)
def bakeModels(bakeEvent: ModelBakeEvent): Unit = {}
} }

View File

@ -2,22 +2,37 @@ package li.cil.oc.common.item
import java.util import java.util
import li.cil.oc.Constants
import li.cil.oc.Settings
import li.cil.oc.client.KeyBindings import li.cil.oc.client.KeyBindings
import li.cil.oc.client.renderer.block.DroneModel
import li.cil.oc.common.entity import li.cil.oc.common.entity
import li.cil.oc.common.item.data.MicrocontrollerData import li.cil.oc.common.item.data.MicrocontrollerData
import li.cil.oc.integration.util.NEI import li.cil.oc.integration.util.NEI
import li.cil.oc.server.agent import li.cil.oc.server.agent
import li.cil.oc.util.BlockPosition import li.cil.oc.util.BlockPosition
import li.cil.oc.util.Rarity import li.cil.oc.util.Rarity
import net.minecraft.client.resources.model.ModelResourceLocation
import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.util.EnumFacing import net.minecraft.util.EnumFacing
import net.minecraftforge.client.event.ModelBakeEvent
import net.minecraftforge.fml.relauncher.Side
import net.minecraftforge.fml.relauncher.SideOnly
class Drone(val parent: Delegator) extends Delegate { class Drone(val parent: Delegator) extends Delegate with CustomModel {
NEI.hide(this) NEI.hide(this)
showInItemList = false showInItemList = false
@SideOnly(Side.CLIENT)
override def getModelLocation(stack: ItemStack) = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.ItemName.Drone, "inventory")
@SideOnly(Side.CLIENT)
override def bakeModels(bakeEvent: ModelBakeEvent): Unit = {
bakeEvent.modelRegistry.putObject(getModelLocation(createItemStack()), DroneModel)
}
override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[String]): Unit = { override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[String]): Unit = {
if (KeyBindings.showExtendedTooltips) { if (KeyBindings.showExtendedTooltips) {
val info = new MicrocontrollerData(stack) val info = new MicrocontrollerData(stack)