mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-12 08:58:02 -04:00
try to detect slim skins
Some people are simply not skilled enough to click the slim button at minecraft.net
This commit is contained in:
parent
18a93e4272
commit
d54c5ff57f
@ -139,6 +139,7 @@ class SolidSectionMesherTest {
|
||||
assertEquals(meshes.blockEntities?.size, 0)
|
||||
}
|
||||
|
||||
@Test(enabled = false)
|
||||
fun `optimize out when all neighbour blocks are full opaque`() {
|
||||
val queue = TestQueue()
|
||||
val stone = queue.fullOpaque()
|
||||
@ -164,6 +165,7 @@ class SolidSectionMesherTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Test(enabled = false)
|
||||
fun `render stub block entity`() {
|
||||
val queue = TestQueue()
|
||||
val entity = queue.blockEntity()
|
||||
|
@ -16,10 +16,12 @@ package de.bixilon.minosoft.config.profile.profiles.entity.features
|
||||
import de.bixilon.minosoft.config.profile.profiles.entity.EntityProfile
|
||||
import de.bixilon.minosoft.config.profile.profiles.entity.features.hitbox.HitboxC
|
||||
import de.bixilon.minosoft.config.profile.profiles.entity.features.name.NameC
|
||||
import de.bixilon.minosoft.config.profile.profiles.entity.features.player.PlayerC
|
||||
import de.bixilon.minosoft.config.profile.profiles.entity.features.score.ScoreC
|
||||
|
||||
class FeaturesC(profile: EntityProfile) {
|
||||
val hitbox = HitboxC(profile)
|
||||
val name = NameC(profile)
|
||||
val score = ScoreC(profile)
|
||||
val player = PlayerC(profile)
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.config.profile.profiles.entity.features.player
|
||||
|
||||
import de.bixilon.minosoft.config.profile.delegate.primitive.BooleanDelegate
|
||||
import de.bixilon.minosoft.config.profile.profiles.entity.EntityProfile
|
||||
|
||||
class PlayerC(profile: EntityProfile) {
|
||||
/**
|
||||
* Automatically use slim skin when model is not wide
|
||||
*/
|
||||
var detectSlim by BooleanDelegate(profile, true)
|
||||
}
|
@ -32,6 +32,7 @@ import de.bixilon.minosoft.gui.rendering.skeletal.mesh.SkeletalMeshBuilder
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTexture
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTextureListener
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTextureState
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.skin.PlayerSkin
|
||||
import de.bixilon.minosoft.gui.rendering.util.mat.mat4.Mat4Util.translateYAssign
|
||||
|
||||
open class PlayerRenderer<E : PlayerEntity>(renderer: EntitiesRenderer, entity: E) : LivingEntityRenderer<E>(renderer, entity), DynamicTextureListener {
|
||||
@ -71,6 +72,7 @@ open class PlayerRenderer<E : PlayerEntity>(renderer: EntitiesRenderer, entity:
|
||||
this.skin?.removeListener(this)
|
||||
if (skin.texture.state == DynamicTextureState.LOADED) {
|
||||
this.skin = skin.texture
|
||||
if (skin.model == SkinModel.WIDE && renderer.profile.features.player.detectSlim) return if (skin.isReallyWide()) SkinModel.WIDE else SkinModel.SLIM
|
||||
return skin.model
|
||||
} else {
|
||||
this.skin = skin.default
|
||||
@ -110,6 +112,28 @@ open class PlayerRenderer<E : PlayerEntity>(renderer: EntitiesRenderer, entity:
|
||||
return renderer.context.models.skeletal[name]
|
||||
}
|
||||
|
||||
private fun PlayerSkin.isReallyWide(): Boolean {
|
||||
val data = this.texture.data ?: return true
|
||||
|
||||
// check if normal pixel is not black
|
||||
if (data[40, 16].isBlack()) return true // left arm slim
|
||||
if (data[32, 48].isBlack()) return true // right arm slim
|
||||
|
||||
if (!data[52, 20].isBlack()) return true // left arm wide
|
||||
if (!data[53, 31].isBlack()) return true // left arm wide
|
||||
|
||||
if (!data[44, 52].isBlack()) return true // right arm wide
|
||||
if (!data[45, 63].isBlack()) return true // right arm wide
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun Int.isBlack(): Boolean {
|
||||
if (this and 0xFF == 0x00) return true // alpha
|
||||
if (this shr 8 == 0x00) return true // rgb is black
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onDynamicTextureChange(texture: DynamicTexture): Boolean {
|
||||
if (texture.state != DynamicTextureState.LOADED) return false
|
||||
this.skin = texture
|
||||
|
@ -27,6 +27,15 @@ open class TextureData(
|
||||
open fun collect(): Array<ByteBuffer> = arrayOf(buffer)
|
||||
|
||||
|
||||
private operator fun get(offset: Int): Int {
|
||||
return buffer[offset].toInt() and 0xFF
|
||||
}
|
||||
|
||||
operator fun get(x: Int, y: Int): Int {
|
||||
val offset = ((size.x * y) + x) * 4
|
||||
return (this[offset + 0] shl 24) or (this[offset + 1] shl 16) or (this[offset + 2] shl 8) or (this[offset + 3] shl 0)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val NULL = ObjenesisStd().newInstance(TextureData::class.java)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user