- 手持非放置物品(工具/食物):实体图集物品图标小四边形(原版倾斜角, 双面、alpha test),随挥动动画平移;可放置方块仍为六面立方体 - 动物(牛/猪/羊/鸡)改为方块组合模型(身体+头+腿),按原版皮肤布局 取子矩形贴图,水平面向相机;修复动物 VAO 未捕获 EBO 导致的驱动崩溃 - 僵尸/村民/掉落物广告牌开启 alpha test(透明区域不再显黑块)
127 lines
4.5 KiB
Go
127 lines
4.5 KiB
Go
//go:build gl
|
||
|
||
// 实体可视映射:实体类型 → 贴图键/身高/动物模型(渲染.md §5.3)。
|
||
// 动物用方块组合模型(身体+头+四腿)近似原版外观;僵尸/村民用交叉广告牌;
|
||
// 掉落物用物品图标小广告牌。
|
||
package main
|
||
|
||
import (
|
||
"mc/internal/entity"
|
||
"mc/internal/item"
|
||
"mc/internal/render"
|
||
)
|
||
|
||
// entityVisual 返回实体的贴图键与身高(米)。
|
||
// 动物额外返回外观变体(0 牛 / 1 猪 / 2 羊 / 3 鸡),供方块模型选择。
|
||
func entityVisual(e *entity.Entity, items *item.Registry) (key string, height float32, variant int) {
|
||
switch e.Kind {
|
||
case entity.KindZombie:
|
||
return "entity/zombie/zombie", 1.95, -1
|
||
case entity.KindVillager:
|
||
return "entity/villager/villager", 1.95, -1
|
||
case entity.KindAnimal:
|
||
switch e.ID % 4 {
|
||
case 0:
|
||
return "entity/cow/cow_temperate", 1.4, 0
|
||
case 1:
|
||
return "entity/pig/pig_temperate", 0.9, 1
|
||
case 2:
|
||
return "entity/sheep/sheep", 1.3, 2
|
||
default:
|
||
return "entity/chicken/chicken_temperate", 0.7, 3
|
||
}
|
||
case entity.KindItemDrop:
|
||
d, ok := e.Data.(*entity.Drop)
|
||
if !ok || items == nil {
|
||
return "", 0, -1
|
||
}
|
||
def, ok := items.Get(d.Item)
|
||
if !ok {
|
||
return "", 0, -1
|
||
}
|
||
return def.Texture, 0.45, -1
|
||
default:
|
||
return "", 0, -1
|
||
}
|
||
}
|
||
|
||
// rect 构造图集 tile 内归一化子矩形。
|
||
func rect(u0, v0, u1, v1 float32) [4]float32 { return [4]float32{u0, v0, u1, v1} }
|
||
|
||
// boxPart 构造模型部件:六面统一用 side 矩形,前/后取中间条带,顶取上条带,底取下条带。
|
||
func boxPart(cx, cy, cz, w, h, d float32, side [4]float32) render.AnimalPart {
|
||
u0, v0, u1, v1 := side[0], side[1], side[2], side[3]
|
||
uw, vh := u1-u0, v1-v0
|
||
front := rect(u0+uw*0.35, v0, u0+uw*0.65, v1) // 前/后面:中间三分之一
|
||
top := rect(u0, v0, u1, v0+vh*0.3)
|
||
bottom := rect(u0, v1-vh*0.3, u1, v1)
|
||
var uv [6][4]float32
|
||
// 顺序同 cubeFaces:顶/底/东/西/南(前)/北(后)
|
||
uv[0], uv[1] = top, bottom
|
||
uv[2], uv[3] = side, side
|
||
uv[4], uv[5] = front, front
|
||
return render.AnimalPart{CX: cx, CY: cy, CZ: cz, W: w, H: h, D: d, UV: uv}
|
||
}
|
||
|
||
// animalModel 返回动物方块模型(variant:0 牛 / 1 猪 / 2 羊 / 3 鸡)。
|
||
// 贴图子矩形按原版皮肤布局:头部在纹理左侧、身体在右侧、腿在下部。
|
||
// 图集 tile 内纹理被等比拉伸成 64×64(64×32 原图纵向拉长一倍,矩形已按拉伸后比例折算)。
|
||
func animalModel(variant int) render.AnimalModel {
|
||
switch variant {
|
||
case 0: // 牛:纹理 64×64,内容在上半(v 0–0.5)
|
||
head := rect(0.02, 0.02, 0.48, 0.48)
|
||
body := rect(0.52, 0.02, 0.98, 0.48)
|
||
legs := rect(0.55, 0.30, 0.98, 0.50)
|
||
var m render.AnimalModel
|
||
m.Parts = append(m.Parts,
|
||
boxPart(0, 0.72, 0, 0.92, 0.62, 1.28, body),
|
||
boxPart(0, 1.26, 0.60, 0.56, 0.50, 0.56, head),
|
||
boxPart(-0.34, 0.24, 0.50, 0.22, 0.48, 0.22, legs),
|
||
boxPart(0.34, 0.24, 0.50, 0.22, 0.48, 0.22, legs),
|
||
boxPart(-0.34, 0.24, -0.50, 0.22, 0.48, 0.22, legs),
|
||
boxPart(0.34, 0.24, -0.50, 0.22, 0.48, 0.22, legs),
|
||
)
|
||
return m
|
||
case 1: // 猪:纹理 64×64,内容在上半
|
||
head := rect(0.14, 0.03, 0.48, 0.45)
|
||
body := rect(0.52, 0.03, 0.98, 0.45)
|
||
legs := rect(0.60, 0.30, 0.98, 0.50)
|
||
var m render.AnimalModel
|
||
m.Parts = append(m.Parts,
|
||
boxPart(0, 0.50, 0, 0.76, 0.44, 1.02, body),
|
||
boxPart(0, 0.86, 0.50, 0.50, 0.42, 0.50, head),
|
||
boxPart(-0.28, 0.15, 0.42, 0.18, 0.30, 0.18, legs),
|
||
boxPart(0.28, 0.15, 0.42, 0.18, 0.30, 0.18, legs),
|
||
boxPart(-0.28, 0.15, -0.42, 0.18, 0.30, 0.18, legs),
|
||
boxPart(0.28, 0.15, -0.42, 0.18, 0.30, 0.18, legs),
|
||
)
|
||
return m
|
||
case 2: // 羊:纹理 64×32(tile 内 v 拉长一倍)
|
||
head := rect(0.02, 0.02, 0.26, 0.40)
|
||
body := rect(0.50, 0.15, 1.00, 0.72)
|
||
legs := rect(0.62, 0.50, 0.95, 0.85)
|
||
var m render.AnimalModel
|
||
m.Parts = append(m.Parts,
|
||
boxPart(0, 0.72, 0, 0.92, 0.60, 1.26, body),
|
||
boxPart(0, 1.20, 0.60, 0.50, 0.46, 0.50, head),
|
||
boxPart(-0.33, 0.21, 0.50, 0.20, 0.42, 0.20, legs),
|
||
boxPart(0.33, 0.21, 0.50, 0.20, 0.42, 0.20, legs),
|
||
boxPart(-0.33, 0.21, -0.50, 0.20, 0.42, 0.20, legs),
|
||
boxPart(0.33, 0.21, -0.50, 0.20, 0.42, 0.20, legs),
|
||
)
|
||
return m
|
||
default: // 鸡:纹理 64×32
|
||
head := rect(0.02, 0.05, 0.28, 0.55)
|
||
body := rect(0.28, 0.10, 0.70, 0.75)
|
||
legs := rect(0.30, 0.55, 0.60, 0.80)
|
||
var m render.AnimalModel
|
||
m.Parts = append(m.Parts,
|
||
boxPart(0, 0.36, 0, 0.44, 0.40, 0.52, body),
|
||
boxPart(0, 0.66, 0.24, 0.32, 0.30, 0.32, head),
|
||
boxPart(-0.14, 0.10, 0.18, 0.09, 0.20, 0.09, legs),
|
||
boxPart(0.14, 0.10, 0.18, 0.09, 0.20, 0.09, legs),
|
||
)
|
||
return m
|
||
}
|
||
}
|