<commit_before>// Copyright 2015 <NAME>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package steven

import (
	"math"

	"github.com/go-gl/mathgl/mgl32"
	"github.com/thinkofdeath/steven/entitysys"
	"github.com/thinkofdeath/steven/render"
	"github.com/thinkofdeath/steven/type/direction"
)

func (ce *clientEntities) registerModels() {
	ce.container.AddSystem(entitysys.Add, esPlayerModelAdd)
	ce.container.AddSystem(entitysys.Tick, esPlayerModelTick)

	// Generic removal
	ce.container.AddSystem(entitysys.Remove, esModelRemove)
}

func appendBox(verts []*render.StaticVertex, x, y, z, w, h, d float32, textures [6]*render.TextureInfo) []*render.StaticVertex {
	for i, face := range faceVertices {
		tex := textures[i]
		if tex == nil {
			continue
		}
		for _, v := range face.verts {
			vert := &render.StaticVertex{
				X:        float32(v.X)*w + x,
				Y:        float32(v.Y)*h + y,
				Z:        float32(v.Z)*d + z,
				TOffsetX: v.TOffsetX * 16 * int16(tex.Width),
				TOffsetY: v.TOffsetY * 16 * int16(tex.Height),
				R:        255,
				G:        255,
				B:        255,
				A:        255,
				TX:       uint16(tex.X),
				TY:       uint16(tex.Y),
				TW:       uint16(tex.Width),
				TH:       uint16(tex.Height),
				TAtlas:   int16(tex.Atlas),
			}
			verts = append(verts, vert)
		}
	}
	return verts
}

// Player

type playerModelComponent struct {
	model *render.StaticModel

	dir  float64
	time float64
}

func (p *playerModelComponent) SetModel(m *render.StaticModel) { p.model = m }
func (p *playerModelComponent) Model() *render.StaticModel     { return p.model }
func (p *playerModelComponent) SetDir(d float64)               { p.dir = d }
func (p *playerModelComponent) Dir() float64                   { return p.dir }
func (p *playerModelComponent) SetTime(t float64)              { p.time = t }
func (p *playerModelComponent) Time() float64                  { return p.time }

// Marker method
func (*playerModelComponent) playerModel() {}

type PlayerModelComponent interface {
	SetModel(m *render.StaticModel)
	Model() *render.StaticModel

	SetDir(d float64)
	Dir() float64
	SetTime(t float64)
	Time() float64

	playerModel()
}

const (
	playerModelHead = iota
	playerModelBody
	playerModelLegLeft
	playerModelLegRight
	playerModelArmLeft
	playerModelArmRight
)

func esPlayerModelAdd(p PlayerModelComponent, pl PlayerComponent) {

	uuid := pl.UUID()
	info := Client.playerList.info[uuid]
	if info == nil {
		panic("missing player info")
	}
	skin := info.skin

	hverts := appendBox(nil, -4/16.0, 0, -4/16.0, 8/16.0, 8/16.0, 8/16.0, [6]*render.TextureInfo{
		direction.North: skin.Sub(8, 8, 8, 8),
		direction.South: skin.Sub(24, 8, 8, 8),
		direction.West:  skin.Sub(0, 8, 8, 8),
		direction.East:  skin.Sub(16, 8, 8, 8),
		direction.Up:    skin.Sub(8, 0, 8, 8),
		direction.Down:  skin.Sub(16, 0, 8, 8),
	})
	hverts = appendBox(hverts, -4.1/16.0, -.1/16.0, -4.1/16.0, 8.2/16.0, 8.2/16.0, 8.2/16.0, [6]*render.TextureInfo{
		direction.North: skin.Sub(8+32, 8, 8, 8),
		direction.South: skin.Sub(24+32, 8, 8, 8),
		direction.West:  skin.Sub(0+32, 8, 8, 8),
		direction.East:  skin.Sub(16+32, 8, 8, 8),
		direction.Up:    skin.Sub(8+32, 0, 8, 8),
		direction.Down:  skin.Sub(16+32, 0, 8, 8),
	})

	bverts := appendBox(nil, -4/16.0, -6/16.0, -2/16.0, 8/16.0, 12/16.0, 4/16.0, [6]*render.TextureInfo{
		direction.North: skin.Sub(20, 20, 8, 12),
		direction.South: skin.Sub(32, 20, 8, 12),
		direction.West:  skin.Sub(16, 20, 4, 12),
		direction.East:  skin.Sub(28, 20, 4, 12),
		direction.Up:    skin.Sub(20, 16, 8, 4),
		direction.Down:  skin.Sub(28, 16, 8, 4),
	})
	bverts = appendBox(bverts, -4.1/16.0, -6.1/16.0, -2.1/16.0, 8.2/16.0, 12.2/16.0, 4.2/16.0, [6]*render.TextureInfo{
		direction.North: skin.Sub(20, 20+16, 8, 12),
		direction.South: skin.Sub(32, 20+16, 8, 12),
		direction.West:  skin.Sub(16, 20+16, 4, 12),
		direction.East:  skin.Sub(28, 20+16, 4, 12),
		direction.Up:    skin.Sub(20, 16+16, 8, 4),
		direction.Down:  skin.Sub(28, 16+16, 8, 4),
	})

	var lverts [4][]*render.StaticVertex

	for i, off := range [][4]int{
		{0, 16, 0, 32},
		{16, 48, 0, 48},
		{32, 48, 48, 48},
		{40, 16, 40, 32},
	} {
		ox, oy := off[0], off[1]
		lverts[i] = appendBox(nil, -2/16.0, -12/16.0, -2/16.0, 4/16.0, 12/16.0, 4/16.0, [6]*render.TextureInfo{
			direction.North: skin.Sub(ox+4, oy+4, 4, 12),
			direction.South: skin.Sub(ox+12, oy+4, 4, 12),
			direction.West:  skin.Sub(ox+0, oy+4, 4, 12),
			direction.East:  skin.Sub(ox+8, oy+4, 4, 12),
			direction.Up:    skin.Sub(ox+4, oy, 4, 4),
			direction.Down:  skin.Sub(ox+8, oy, 4, 4),
		})
		ox, oy = off[2], off[3]
		lverts[i] = appendBox(lverts[i], -2.1/16.0, -12.1/16.0, -2.1/16.0, 4.2/16.0, 12.2/16.0, 4.2/16.0, [6]*render.TextureInfo{
			direction.North: skin.Sub(ox+4, oy+4, 4, 12),
			direction.South: skin.Sub(ox+12, oy+4, 4, 12),
			direction.West:  skin.Sub(ox+0, oy+4, 4, 12),
			direction.East:  skin.Sub(ox+8, oy+4, 4, 12),
			direction.Up:    skin.Sub(ox+4, oy, 4, 4),
			direction.Down:  skin.Sub(ox+8, oy, 4, 4),
		})
	}

	model := render.NewStaticModel([][]*render.StaticVertex{
		playerModelHead:     hverts,
		playerModelBody:     bverts,
		playerModelLegLeft:  lverts[0],
		playerModelLegRight: lverts[1],
		playerModelArmLeft:  lverts[2],
		playerModelArmRight: lverts[3],
	})
	p.SetModel(model)<commit_msg>steven: make the hat layer slightly bigger<commit_after>// Copyright 2015 <NAME>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package steven

import (
	"math"

	"github.com/go-gl/mathgl/mgl32"
	"github.com/thinkofdeath/steven/entitysys"
	"github.com/thinkofdeath/steven/render"
	"github.com/thinkofdeath/steven/type/direction"
)

func (ce *clientEntities) registerModels() {
	ce.container.AddSystem(entitysys.Add, esPlayerModelAdd)
	ce.container.AddSystem(entitysys.Tick, esPlayerModelTick)

	// Generic removal
	ce.container.AddSystem(entitysys.Remove, esModelRemove)
}

func appendBox(verts []*render.StaticVertex, x, y, z, w, h, d float32, textures [6]*render.TextureInfo) []*render.StaticVertex {
	for i, face := range faceVertices {
		tex := textures[i]
		if tex == nil {
			continue
		}
		for _, v := range face.verts {
			vert := &render.StaticVertex{
				X:        float32(v.X)*w + x,
				Y:        float32(v.Y)*h + y,
				Z:        float32(v.Z)*d + z,
				TOffsetX: v.TOffsetX * 16 * int16(tex.Width),
				TOffsetY: v.TOffsetY * 16 * int16(tex.Height),
				R:        255,
				G:        255,
				B:        255,
				A:        255,
				TX:       uint16(tex.X),
				TY:       uint16(tex.Y),
				TW:       uint16(tex.Width),
				TH:       uint16(tex.Height),
				TAtlas:   int16(tex.Atlas),
			}
			verts = append(verts, vert)
		}
	}
	return verts
}

// Player

type playerModelComponent struct {
	model *render.StaticModel

	dir  float64
	time float64
}

func (p *playerModelComponent) SetModel(m *render.StaticModel) { p.model = m }
func (p *playerModelComponent) Model() *render.StaticModel     { return p.model }
func (p *playerModelComponent) SetDir(d float64)               { p.dir = d }
func (p *playerModelComponent) Dir() float64                   { return p.dir }
func (p *playerModelComponent) SetTime(t float64)              { p.time = t }
func (p *playerModelComponent) Time() float64                  { return p.time }

// Marker method
func (*playerModelComponent) playerModel() {}

type PlayerModelComponent interface {
	SetModel(m *render.StaticModel)
	Model() *render.StaticModel

	SetDir(d float64)
	Dir() float64
	SetTime(t float64)
	Time() float64

	playerModel()
}

const (
	playerModelHead = iota
	playerModelBody
	playerModelLegLeft
	playerModelLegRight
	playerModelArmLeft
	playerModelArmRight
)

func esPlayerModelAdd(p PlayerModelComponent, pl PlayerComponent) {

	uuid := pl.UUID()
	info := Client.playerList.info[uuid]
	if info == nil {
		panic("missing player info")
	}
	skin := info.skin

	hverts := appendBox(nil, -4/16.0, 0, -4/16.0, 8/16.0, 8/16.0, 8/16.0, [6]*render.TextureInfo{
		direction.North: skin.Sub(8, 8, 8, 8),
		direction.South: skin.Sub(24, 8, 8, 8),
		direction.West:  skin.Sub(0, 8, 8, 8),
		direction.East:  skin.Sub(16, 8, 8, 8),
		direction.Up:    skin.Sub(8, 0, 8, 8),
		direction.Down:  skin.Sub(16, 0, 8, 8),
	})
	hverts = appendBox(hverts, -4.2/16.0, -.2/16.0, -4.2/16.0, 8.4/16.0, 8.4/16.0, 8.4/16.0, [6]*render.TextureInfo{
		direction.North: skin.Sub(8+32, 8, 8, 8),
		direction.South: skin.Sub(24+32, 8, 8, 8),
		direction.West:  skin.Sub(0+32, 8, 8, 8),
		direction.East:  skin.Sub(16+32, 8, 8, 8),
		direction.Up:    skin.Sub(8+32, 0, 8, 8),
		direction.Down:  skin.Sub(16+32, 0, 8, 8),
	})

	bverts := appendBox(nil, -4/16.0, -6/16.0, -2/16.0, 8/16.0, 12/16.0, 4/16.0, [6]*render.TextureInfo{
		direction.North: skin.Sub(20, 20, 8, 12),
		direction.South: skin.Sub(32, 20, 8, 12),
		direction.West:  skin.Sub(16, 20, 4, 12),
		direction.East:  skin.Sub(28, 20, 4, 12),
		direction.Up:    skin.Sub(20, 16, 8, 4),
		direction.Down:  skin.Sub(28, 16, 8, 4),
	})
	bverts = appendBox(bverts, -4.2/16.0, -6.2/16.0, -2.2/16.0, 8.4/16.0, 12.4/16.0, 4.4/16.0, [6]*render.TextureInfo{
		direction.North: skin.Sub(20, 20+16, 8, 12),
		direction.South: skin.Sub(32, 20+16, 8, 12),
		direction.West:  skin.Sub(16, 20+16, 4, 12),
		direction.East:  skin.Sub(28, 20+16, 4, 12),
		direction.Up:    skin.Sub(20, 16+16, 8, 4),
		direction.Down:  skin.Sub(28, 16+16, 8, 4),
	})

	var lverts [4][]*render.StaticVertex

	for i, off := range [][4]int{
		{0, 16, 0, 32},
		{16, 48, 0, 48},
		{32, 48, 48, 48},
		{40, 16, 40, 32},
	} {
		ox, oy := off[0], off[1]
		lverts[i] = appendBox(nil, -2/16.0, -12/16.0, -2/16.0, 4/16.0, 12/16.0, 4/16.0, [6]*render.TextureInfo{
			direction.North: skin.Sub(ox+4, oy+4, 4, 12),
			direction.South: skin.Sub(ox+12, oy+4, 4, 12),
			direction.West:  skin.Sub(ox+0, oy+4, 4, 12),
			direction.East:  skin.Sub(ox+8, oy+4, 4, 12),
			direction.Up:    skin.Sub(ox+4, oy, 4, 4),
			direction.Down:  skin.Sub(ox+8, oy, 4, 4),
		})
		ox, oy = off[2], off[3]
		lverts[i] = appendBox(lverts[i], -2.2/16.0, -12.2/16.0, -2.2/16.0, 4.4/16.0, 12.4/16.0, 4.4/16.0, [6]*render.TextureInfo{
			direction.North: skin.Sub(ox+4, oy+4, 4, 12),
			direction.South: skin.Sub(ox+12, oy+4, 4, 12),
			direction.West:  skin.Sub(ox+0, oy+4, 4, 12),
			direction.East:  skin.Sub(ox+8, oy+4, 4, 12),
			direction.Up:    skin.Sub(ox+4, oy, 4, 4),
			direction.Down:  skin.Sub(ox+8, oy, 4, 4),
		})
	}

	model := render.NewStaticModel([][]*render.StaticVertex{
		playerModelHead:     hverts,
		playerModelBody:     bverts,
		playerModelLegLeft:  lverts[0],
		playerModelLegRight: lverts[1],
		playerModelArmLeft:  lverts[2],
		playerModelArmRight: lverts[3],
	})
	p.SetModel(model)
{'fraction_non_alphanumeric': 0.17328303180999743, 'fraction_numerical': 0.08402640829975135, 'mean_word_length': 3.1851453175457483, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3254671', 'n_tokens_mistral': 5529, 'n_tokens_neox': 4675, 'n_words': 1107}