暂存服务端渲染功能,材质渲染计划迁移至前端
This commit is contained in:
95
internal/service/skin_renderer/point.go
Normal file
95
internal/service/skin_renderer/point.go
Normal file
@@ -0,0 +1,95 @@
|
||||
// Package skin_renderer 实现 Minecraft 皮肤的 3D 渲染
|
||||
// 移植自 blessing/texture-renderer
|
||||
package skin_renderer
|
||||
|
||||
// Point 表示 3D 空间中的一个点
|
||||
type Point struct {
|
||||
// 原始坐标
|
||||
originX, originY, originZ float64
|
||||
// 投影后的坐标
|
||||
destX, destY, destZ float64
|
||||
// 是否已投影
|
||||
isProjected bool
|
||||
isPreProjected bool
|
||||
}
|
||||
|
||||
// NewPoint 创建一个新的 3D 点
|
||||
func NewPoint(x, y, z float64) *Point {
|
||||
return &Point{
|
||||
originX: x,
|
||||
originY: y,
|
||||
originZ: z,
|
||||
}
|
||||
}
|
||||
|
||||
// Project 将 3D 点投影到 2D 平面
|
||||
// 使用欧拉角旋转:alpha 为垂直旋转(X轴),omega 为水平旋转(Y轴)
|
||||
func (p *Point) Project(cosAlpha, sinAlpha, cosOmega, sinOmega float64, minX, maxX, minY, maxY *float64) {
|
||||
x := p.originX
|
||||
y := p.originY
|
||||
z := p.originZ
|
||||
|
||||
// 3D 旋转投影公式
|
||||
p.destX = x*cosOmega + z*sinOmega
|
||||
p.destY = x*sinAlpha*sinOmega + y*cosAlpha - z*sinAlpha*cosOmega
|
||||
p.destZ = -x*cosAlpha*sinOmega + y*sinAlpha + z*cosAlpha*cosOmega
|
||||
|
||||
p.isProjected = true
|
||||
|
||||
// 更新边界
|
||||
if p.destX < *minX {
|
||||
*minX = p.destX
|
||||
}
|
||||
if p.destX > *maxX {
|
||||
*maxX = p.destX
|
||||
}
|
||||
if p.destY < *minY {
|
||||
*minY = p.destY
|
||||
}
|
||||
if p.destY > *maxY {
|
||||
*maxY = p.destY
|
||||
}
|
||||
}
|
||||
|
||||
// PreProject 预投影,用于部件独立旋转(如头部、手臂)
|
||||
// dx, dy, dz 为旋转中心点
|
||||
func (p *Point) PreProject(dx, dy, dz, cosAlpha, sinAlpha, cosOmega, sinOmega float64) {
|
||||
if p.isPreProjected {
|
||||
return
|
||||
}
|
||||
|
||||
// 相对于旋转中心的坐标
|
||||
x := p.originX - dx
|
||||
y := p.originY - dy
|
||||
z := p.originZ - dz
|
||||
|
||||
// 旋转后加回偏移
|
||||
p.originX = x*cosOmega + z*sinOmega + dx
|
||||
p.originY = x*sinAlpha*sinOmega + y*cosAlpha - z*sinAlpha*cosOmega + dy
|
||||
p.originZ = -x*cosAlpha*sinOmega + y*sinAlpha + z*cosAlpha*cosOmega + dz
|
||||
|
||||
p.isPreProjected = true
|
||||
}
|
||||
|
||||
// GetDestCoord 获取投影后的坐标
|
||||
func (p *Point) GetDestCoord() (x, y, z float64) {
|
||||
return p.destX, p.destY, p.destZ
|
||||
}
|
||||
|
||||
// GetOriginCoord 获取原始坐标
|
||||
func (p *Point) GetOriginCoord() (x, y, z float64) {
|
||||
return p.originX, p.originY, p.originZ
|
||||
}
|
||||
|
||||
// IsProjected 返回是否已投影
|
||||
func (p *Point) IsProjected() bool {
|
||||
return p.isProjected
|
||||
}
|
||||
|
||||
// GetDepth 获取深度值(用于排序)
|
||||
func (p *Point) GetDepth(cosAlpha, sinAlpha, cosOmega, sinOmega float64, minX, maxX, minY, maxY *float64) float64 {
|
||||
if !p.isProjected {
|
||||
p.Project(cosAlpha, sinAlpha, cosOmega, sinOmega, minX, maxX, minY, maxY)
|
||||
}
|
||||
return p.destZ
|
||||
}
|
||||
Reference in New Issue
Block a user