Skip to content

Commit

Permalink
Add dmtrackdef2 support for _obj
Browse files Browse the repository at this point in the history
  • Loading branch information
xackery committed Aug 25, 2024
1 parent 3814a78 commit 6f3a578
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 116 deletions.
69 changes: 55 additions & 14 deletions raw/rawfrag/dm_track_def_2.go
Original file line number Diff line number Diff line change
@@ -1,36 +1,77 @@
package rawfrag

import (
"encoding/binary"
"fmt"
"io"

"github.com/xackery/quail/model"
"github.com/xackery/encdec"
)

// WldFragDmTrackDef2 is DmTrackDef2 in libeq, Mesh Animated Vertices in openzone, DMTRACKDEF in wld, MeshAnimatedVertices in lantern
type WldFragDmTrackDef2 struct {
NameRef int32 `yaml:"name_ref"`
Flags uint32 `yaml:"flags"`
VertexCount uint16 `yaml:"vertex_count"`
FrameCount uint16 `yaml:"frame_count"`
Param1 uint16 `yaml:"param_1"` // usually contains 100
Param2 uint16 `yaml:"param_2"` // usually contains 0
Scale uint16 `yaml:"scale"`
Frames []WldFragMeshAnimatedBone `yaml:"frames"`
Size6 uint32 `yaml:"size_6"`
}

type WldFragMeshAnimatedBone struct {
Position model.Vector3 `yaml:"position"`
NameRef int32
Flags uint32
Param1 uint16
Param2 uint16
Scale uint16
Frames [][][3]int16
Size6 uint16
}

func (e *WldFragDmTrackDef2) FragCode() int {
return FragCodeDmTrackDef2
}

func (e *WldFragDmTrackDef2) Write(w io.Writer, isNewWorld bool) error {
enc := encdec.NewEncoder(w, binary.LittleEndian)
enc.Int32(e.NameRef)
enc.Uint32(e.Flags)
if len(e.Frames) < 1 {
return fmt.Errorf("no frames found")
}
enc.Uint16(uint16(len(e.Frames[0])))
enc.Uint16(uint16(len(e.Frames)))
enc.Uint16(e.Param1)
enc.Uint16(e.Param2)
enc.Uint16(e.Scale)
for _, frame := range e.Frames {
for _, vert := range frame {
enc.Int16(vert[0])
enc.Int16(vert[1])
enc.Int16(vert[2])
}
}
enc.Uint16(e.Size6)
err := enc.Error()
if err != nil {
return err
}
return nil
}

func (e *WldFragDmTrackDef2) Read(r io.ReadSeeker, isNewWorld bool) error {
dec := encdec.NewDecoder(r, binary.LittleEndian)
e.NameRef = dec.Int32()
e.Flags = dec.Uint32()
vertexCount := dec.Uint16()
frameCount := dec.Uint16()
e.Param1 = dec.Uint16()
e.Param2 = dec.Uint16()
e.Scale = dec.Uint16()
e.Frames = make([][][3]int16, frameCount)
for i := range e.Frames {
e.Frames[i] = make([][3]int16, vertexCount)
for j := range e.Frames[i] {
e.Frames[i][j][0] = dec.Int16()
e.Frames[i][j][1] = dec.Int16()
e.Frames[i][j][2] = dec.Int16()
}
}
e.Size6 = dec.Uint16()
err := dec.Error()
if err != nil {
return err
}
return nil
}
19 changes: 18 additions & 1 deletion raw/rawfrag/rawfrag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"os"
"testing"

"github.com/go-test/deep"
"github.com/xackery/encdec"
"github.com/xackery/quail/common"
"github.com/xackery/quail/pfs"
Expand Down Expand Up @@ -94,7 +95,8 @@ func TestFragment(t *testing.T) {
// 0x35 First
// 0x36 Mesh
{path: "globalelm_chr.s3d", file: "globalelm_chr.wld", fragIndex: 110},
// 0x37 MeshAnimated
// 0x37 "DmTrackDef2",
{path: "qeynos_obj.s3d", file: "qeynos_obj.wld", fragIndex: 1001},
//{path: "global_chr.s3d", file: "global_chr.wld", fragIndex: 557}, // tex coord count misaligned
//{path: "gequip.s3d", file: "gequip.wld", fragIndex: 0}, // Mesh
//{path: "gfaydark.s3d", file: "gfaydark.wld", fragIndex: 0}, // Mesh
Expand Down Expand Up @@ -169,6 +171,21 @@ func TestFragment(t *testing.T) {
t.Fatalf("frag %d 0x%x (%s) write: %s", i, reader.FragCode(), FragName(int(reader.FragCode())), err.Error())
}

reader2 := NewFrag(buf)
if reader2 == nil {
t.Fatalf("frag %d read: unsupported fragment", i)
}

err = reader2.Read(buf, false)
if err != nil {
t.Fatalf("frag %d 0x%x (%s) read: %s", i, reader.FragCode(), FragName(int(reader.FragCode())), err.Error())
}

diff := deep.Equal(reader, reader2)
if diff != nil {
t.Fatalf("frag %d 0x%x (%s) diff mismatch: %s", i, reader.FragCode(), FragName(int(reader.FragCode())), diff)
}

dstData := buf.Bytes()

if tt.isDump {
Expand Down
4 changes: 3 additions & 1 deletion raw/wld_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func TestWldFragOffsetDump(t *testing.T) {
tests := []struct {
name string
}{
{"qeynos_obj"},
//{"gequip4"},
//{"global_chr"}, // TODO: anarelion asked mesh of EYE_DMSPRITEDEF check if the eye is just massive 22 units in size, where the other units in that file are just 1-2 units in size
}
Expand Down Expand Up @@ -114,11 +115,12 @@ func TestWldRewrite(t *testing.T) {
name string
wld string
}{
{name: "qeynos_obj"},
//{name: "gequip4"},
//{name:"global_chr"}, // TODO: anarelion asked mesh of EYE_DMSPRITEDEF check if the eye is just massive 22 units in size, where the other units in that file are just 1-2 units in size
//{name: "load2", wld: "objects.wld"},
//{name: "load2", wld: "lights.wld"},
{name: "load2"},
//{name: "load2"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
29 changes: 15 additions & 14 deletions wld/wld.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,29 @@ type Wld struct {
WorldDef *WorldDef
GlobalAmbientLightDef *GlobalAmbientLightDef
Version uint32
SimpleSpriteDefs []*SimpleSpriteDef
MaterialDefs []*MaterialDef
variationMaterialDefs map[string][]*MaterialDef
MaterialPalettes []*MaterialPalette
DMSpriteDefs []*DMSpriteDef
DMSpriteDef2s []*DMSpriteDef2
ActorDefs []*ActorDef
ActorInsts []*ActorInst
AmbientLights []*AmbientLight
DMSpriteDef2s []*DMSpriteDef2
DMSpriteDefs []*DMSpriteDef
DMTrackDef2s []*DMTrackDef2
HierarchicalSpriteDefs []*HierarchicalSpriteDef
LightDefs []*LightDef
MaterialDefs []*MaterialDef
MaterialPalettes []*MaterialPalette
ParticleCloudDefs []*ParticleCloudDef
PointLights []*PointLight
Sprite3DDefs []*Sprite3DDef
TrackInstances []*TrackInstance
TrackDefs []*TrackDef
HierarchicalSpriteDefs []*HierarchicalSpriteDef
PolyhedronDefs []*PolyhedronDefinition
WorldTrees []*WorldTree
Regions []*Region
AmbientLights []*AmbientLight
Zones []*Zone
RGBTrackDefs []*RGBTrackDef
ParticleCloudDefs []*ParticleCloudDef
SimpleSpriteDefs []*SimpleSpriteDef
Sprite2DDefs []*Sprite2DDef
Sprite3DDefs []*Sprite3DDef
TrackDefs []*TrackDef
TrackInstances []*TrackInstance
variationMaterialDefs map[string][]*MaterialDef
WorldTrees []*WorldTree
Zones []*Zone
}

type WldDefinitioner interface {
Expand Down
Loading

0 comments on commit 6f3a578

Please sign in to comment.