204 lines
4.4 KiB
Go
204 lines
4.4 KiB
Go
|
|
package skin_renderer
|
||
|
|
|
||
|
|
import (
|
||
|
|
"image"
|
||
|
|
"image/color"
|
||
|
|
"image/png"
|
||
|
|
"os"
|
||
|
|
"testing"
|
||
|
|
)
|
||
|
|
|
||
|
|
// createTestSkin 创建一个测试用的 64x64 皮肤图像
|
||
|
|
func createTestSkin() []byte {
|
||
|
|
img := image.NewRGBA(image.Rect(0, 0, 64, 64))
|
||
|
|
|
||
|
|
// 填充一些测试颜色
|
||
|
|
// 头部区域 (8,8) - (16,16)
|
||
|
|
for y := 8; y < 16; y++ {
|
||
|
|
for x := 8; x < 16; x++ {
|
||
|
|
img.Set(x, y, image.White)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 躯干区域 (20,20) - (28,32)
|
||
|
|
for y := 20; y < 32; y++ {
|
||
|
|
for x := 20; x < 28; x++ {
|
||
|
|
img.Set(x, y, image.Black)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 编码为 PNG
|
||
|
|
f, _ := os.CreateTemp("", "test_skin_*.png")
|
||
|
|
defer os.Remove(f.Name())
|
||
|
|
defer f.Close()
|
||
|
|
|
||
|
|
png.Encode(f, img)
|
||
|
|
f.Seek(0, 0)
|
||
|
|
|
||
|
|
data, _ := os.ReadFile(f.Name())
|
||
|
|
return data
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestSkinRenderer_Render(t *testing.T) {
|
||
|
|
skinData := createTestSkin()
|
||
|
|
if len(skinData) == 0 {
|
||
|
|
t.Skip("无法创建测试皮肤")
|
||
|
|
}
|
||
|
|
|
||
|
|
renderer := NewSkinRenderer(7.0, false, -45, -25)
|
||
|
|
result, err := renderer.Render(skinData, false)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("渲染失败: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if result == nil {
|
||
|
|
t.Fatal("渲染结果为空")
|
||
|
|
}
|
||
|
|
|
||
|
|
bounds := result.Bounds()
|
||
|
|
if bounds.Dx() == 0 || bounds.Dy() == 0 {
|
||
|
|
t.Error("渲染结果尺寸为零")
|
||
|
|
}
|
||
|
|
|
||
|
|
t.Logf("渲染结果尺寸: %dx%d", bounds.Dx(), bounds.Dy())
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestSkinRenderer_RenderHeadOnly(t *testing.T) {
|
||
|
|
skinData := createTestSkin()
|
||
|
|
if len(skinData) == 0 {
|
||
|
|
t.Skip("无法创建测试皮肤")
|
||
|
|
}
|
||
|
|
|
||
|
|
renderer := NewSkinRenderer(15.0, true, 45, -25)
|
||
|
|
result, err := renderer.Render(skinData, false)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("渲染头像失败: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if result == nil {
|
||
|
|
t.Fatal("渲染结果为空")
|
||
|
|
}
|
||
|
|
|
||
|
|
bounds := result.Bounds()
|
||
|
|
t.Logf("头像渲染结果尺寸: %dx%d", bounds.Dx(), bounds.Dy())
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestMinecraft_RenderSkin(t *testing.T) {
|
||
|
|
skinData := createTestSkin()
|
||
|
|
if len(skinData) == 0 {
|
||
|
|
t.Skip("无法创建测试皮肤")
|
||
|
|
}
|
||
|
|
|
||
|
|
mc := NewMinecraft()
|
||
|
|
result, err := mc.RenderSkin(skinData, 7.0, false)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("RenderSkin 失败: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if result == nil {
|
||
|
|
t.Fatal("渲染结果为空")
|
||
|
|
}
|
||
|
|
|
||
|
|
bounds := result.Bounds()
|
||
|
|
t.Logf("完整皮肤渲染结果尺寸: %dx%d", bounds.Dx(), bounds.Dy())
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestMinecraft_Render2DAvatar(t *testing.T) {
|
||
|
|
skinData := createTestSkin()
|
||
|
|
if len(skinData) == 0 {
|
||
|
|
t.Skip("无法创建测试皮肤")
|
||
|
|
}
|
||
|
|
|
||
|
|
mc := NewMinecraft()
|
||
|
|
result, err := mc.Render2DAvatar(skinData, 15.0)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("Render2DAvatar 失败: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if result == nil {
|
||
|
|
t.Fatal("渲染结果为空")
|
||
|
|
}
|
||
|
|
|
||
|
|
bounds := result.Bounds()
|
||
|
|
t.Logf("2D头像渲染结果尺寸: %dx%d", bounds.Dx(), bounds.Dy())
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestMinecraft_Render3DAvatar(t *testing.T) {
|
||
|
|
skinData := createTestSkin()
|
||
|
|
if len(skinData) == 0 {
|
||
|
|
t.Skip("无法创建测试皮肤")
|
||
|
|
}
|
||
|
|
|
||
|
|
mc := NewMinecraft()
|
||
|
|
result, err := mc.Render3DAvatar(skinData, 15.0)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("Render3DAvatar 失败: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if result == nil {
|
||
|
|
t.Fatal("渲染结果为空")
|
||
|
|
}
|
||
|
|
|
||
|
|
bounds := result.Bounds()
|
||
|
|
t.Logf("3D头像渲染结果尺寸: %dx%d", bounds.Dx(), bounds.Dy())
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestPoint_Project(t *testing.T) {
|
||
|
|
p := NewPoint(1, 2, 3)
|
||
|
|
|
||
|
|
var minX, maxX, minY, maxY float64
|
||
|
|
|
||
|
|
// 测试 45 度旋转
|
||
|
|
cosAlpha := 0.9063077870366499 // cos(-25°)
|
||
|
|
sinAlpha := -0.42261826174069944 // sin(-25°)
|
||
|
|
cosOmega := 0.7071067811865476 // cos(45°)
|
||
|
|
sinOmega := 0.7071067811865476 // sin(45°)
|
||
|
|
|
||
|
|
p.Project(cosAlpha, sinAlpha, cosOmega, sinOmega, &minX, &maxX, &minY, &maxY)
|
||
|
|
|
||
|
|
x, y, z := p.GetDestCoord()
|
||
|
|
t.Logf("投影结果: x=%.2f, y=%.2f, z=%.2f", x, y, z)
|
||
|
|
|
||
|
|
if !p.IsProjected() {
|
||
|
|
t.Error("点应该标记为已投影")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestPolygon_AddToImage(t *testing.T) {
|
||
|
|
// 创建一个简单的正方形多边形
|
||
|
|
p1 := NewPoint(0, 0, 0)
|
||
|
|
p2 := NewPoint(10, 0, 0)
|
||
|
|
p3 := NewPoint(10, 10, 0)
|
||
|
|
p4 := NewPoint(0, 10, 0)
|
||
|
|
|
||
|
|
var minX, maxX, minY, maxY float64
|
||
|
|
p1.Project(1, 0, 1, 0, &minX, &maxX, &minY, &maxY)
|
||
|
|
p2.Project(1, 0, 1, 0, &minX, &maxX, &minY, &maxY)
|
||
|
|
p3.Project(1, 0, 1, 0, &minX, &maxX, &minY, &maxY)
|
||
|
|
p4.Project(1, 0, 1, 0, &minX, &maxX, &minY, &maxY)
|
||
|
|
|
||
|
|
poly := NewPolygon([4]*Point{p1, p2, p3, p4}, color.RGBA{R: 255, G: 255, B: 255, A: 255})
|
||
|
|
|
||
|
|
img := image.NewRGBA(image.Rect(0, 0, 100, 100))
|
||
|
|
poly.AddToImage(img, minX, minY, 5.0)
|
||
|
|
|
||
|
|
// 检查是否有像素被绘制
|
||
|
|
hasPixels := false
|
||
|
|
for y := 0; y < 100; y++ {
|
||
|
|
for x := 0; x < 100; x++ {
|
||
|
|
c := img.RGBAAt(x, y)
|
||
|
|
if c.A > 0 {
|
||
|
|
hasPixels = true
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if hasPixels {
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if !hasPixels {
|
||
|
|
t.Error("多边形应该在图像上绘制了像素")
|
||
|
|
}
|
||
|
|
}
|