COM3D2

package
v1.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 29, 2025 License: BSD-3-Clause Imports: 20 Imported by: 0

Documentation

Index

Constants

View Source
const (
	LocalRotationX = 0
	LocalRotationY = 1
	LocalRotationZ = 2
	LocalRotationW = 3
)

PropertyIndex 表示属性索引,用于标识属性的类型。 最高位为 6,含义如下:

View Source
const (
	MenuSignature   = "CM3D2_MENU"
	MenuVersion     = 1000
	MateSignature   = "CM3D2_MATERIAL"
	MateVersion     = 2001
	PMatSignature   = "CM3D2_PMATERIAL"
	PMatVersion     = 1000
	ColSignature    = "CM3D21_COL"
	ColVersion      = 24301
	PhySignature    = "CM3D21_PHY"
	PhyVersion      = 24301
	PskSignature    = "CM3D21_PSK"
	PskVersion      = 24301
	TexSignature    = "CM3D2_TEX"
	TexVersion      = 1010
	AnmSignature    = "CM3D2_ANIM"
	AnmVersion      = 1001
	ModelSignature  = "CM3D2_MESH"
	ModelVersion    = 2001
	PresetSignature = "CM3D2_PRESET"
	PresetVersion   = 24301
	SaveSignature   = "COM3D2_SAVE"
	SaveVersion     = 24301
)
View Source
const (
	SkinThicknessSignature = "SkinThickness"
	SkinThicknessVersion   = 100
)
View Source
const (
	PresetPropertyListSignature = "CM3D2_MPROP_LIST"
	PresetPropertyListVersion   = 24301
	PresetPropertySignature     = "CM3D2_MPROP"
	PresetPropertyVersion       = 24301
	MultiColorSignature         = "CM3D2_MULTI_COL"
	MultiColorVersion           = 24301
	BodyPropertySignature       = "CM3D2_MAID_BODY"
	BodyPropertyVersion         = 24301
)
View Source
const (
	ShadowCastingModeOff         = "Off"         // 不投射阴影
	ShadowCastingModeOn          = "On"          // 投射阴影
	ShadowCastingModeTwoSided    = "TwoSided"    // 双面投射阴影
	ShadowCastingModeShadowsOnly = "ShadowsOnly" // 只投射阴影
)

阴影投射方式,对应 Unity 的 ShadowCastingMode

View Source
const (
	PartialMode_StaticOrCurve int32 = 0 // C#里的 StaticOrCurve,静态或曲线模式
	PartialMode_Partial       int32 = 1 // C#里的 Partial,按骨骼设置模式
	PartialMode_FromBoneName  int32 = 2 // C#里的 FromBoneName,旧自动按骨骼名设置模式
)

PartialMode 枚举

View Source
const (
	FreezeAxis_None int32 = 0
	FreezeAxis_X    int32 = 1
	FreezeAxis_Y    int32 = 2
	FreezeAxis_Z    int32 = 3
)

FreezeAxis 枚举

View Source
const (
	PresetTypeWear = 0 // 衣服
	PresetTypeBody = 1 // 身体
	PresetTypeAll  = 2 // 全部
)

预设类型常量

View Source
const (
	RGB24  int32 = 3
	ARGB32 int32 = 5
	DXT1   int32 = 10
	DXT5   int32 = 12
)

From unity 5.6.4 COM3D2 supported only

View Source
const (
	EndTag = "end"
)

Variables

View Source
var (
	NeiKey = []byte{
		0xAA, 0xC9, 0xD2, 0x35,
		0x22, 0x87, 0x20, 0xF2,
		0x40, 0xC5, 0x61, 0x7C,
		0x01, 0xDF, 0x66, 0x54,
	} // 加密密钥
)
View Source
var (
	NeiSignature = []byte{0x77, 0x73, 0x76, 0xFF}
)

Functions

func ConvertImageToTexAndWrite

func ConvertImageToTexAndWrite(inputPath string, texName string, compress bool, forcePNG bool, outputPath string) error

ConvertImageToTexAndWrite 将任意 ImageMagick 支持的文件格式转换为 tex 格式,并写出 依赖外部库 ImageMagick,且有 Path 环境变量可以直接调用 magick 命令 如果 forcePNG 为 true,且 compress 为 false,则 tex 的数据位是原始 PNG 数据或转换为 PNG 如果 forcePNG 为 false,且 compress 为 false,那么检查输入格式是否是 PNG 或 JPG,如果是则数据位直接使用原始图片,否则如果原始格式有损且无透明通道则转换为 JPG,否则转换为 PNG 如果 forcePNG 为 true,且 compress 为 true,那么 compress 标识会被忽略,结果同 forcePNG 为 true,且 compress 为 false 如果 forcePNG 为 false,且 compress 为 true,那么会对结果进行 DXT 压缩,数据位为 DDS 数据,根据有无透明通道选择 DXT1 或 DXT5 如果要生成 1011 版本的 tex(纹理图集),需要在图片目录下有一个同名的 .uv.csv 文件(例如 foo.png 对应 foo.png.uv.csv),文件内容为矩形数组 x, y, w, h 一行一组 否则生成 1010 版本的 tex

func ConvertTexToImageAndWrite

func ConvertTexToImageAndWrite(tex *Tex, outputPath string, forcePNG bool) error

ConvertTexToImageAndWrite 将 .tex 文件转换为图像文件,并写出 依赖外部库 ImageMagick,且有 Path 环境变量可以直接调用 magick 命令 如果 forcePNG 为 false 那么根据输出路径的后缀名决定输出格式,如果输出路径没有后缀,则根据图像格式来判断,如果是有损格式且没有透明通道,则保存为 JPG,否则保存为 PNG 如果 forcePNG 为 true 则强制保存为 PNG,不考虑图像格式和透明通道 如果是 1011 版本的 tex(纹理图集),则还会生成一个 .uv.csv 文件(例如 foo.png 对应 foo.png.uv.csv),文件内容为矩形数组 x, y, w, h 一行一组 如果输出是 .tex 则原样写出

func WriteAnimationCurve

func WriteAnimationCurve(writer *stream.BinaryWriter, ac AnimationCurve) error

WriteAnimationCurve 写出 AnimationCurve:先写 int(个数),然后依次写 time,value,inTangent,outTangent

Types

type AnimationCurve

type AnimationCurve struct {
	Keyframes []Keyframe `json:"Keyframes"`
}

AnimationCurve 用于存储 Keyframe 数组

func ReadAnimationCurve

func ReadAnimationCurve(reader *stream.BinaryReader) (AnimationCurve, error)

ReadAnimationCurve 读取 AnimationCurve:先读 int(个数),若为 0 则返回空

type Anm

type Anm struct {
	Signature    string          `json:"Signature"`              // CM3D2_ANIM
	Version      int32           `json:"Version"`                // 1001
	BoneCurves   []BoneCurveData `json:"BoneCurves"`             // 所有骨骼的动画曲线数据
	BustKeyLeft  bool            `json:"BustKeyLeft,omitempty"`  // 左胸部动画开关
	BustKeyRight bool            `json:"BustKeyRight,omitempty"` // 右胸部动画开关
}

Anm 整体描述一个 .anm 文件的结构

func ReadAnm

func ReadAnm(r io.Reader) (*Anm, error)

ReadAnm 读取并解析一个 .anm 文件,返回 Anm 结构。

func (Anm) Dump

func (a Anm) Dump(w io.Writer) error

Dump 将 Anm 结构写到 w 中,生成符合 CM3D2_ANIM 格式的二进制数据。

type BodyProperty added in v1.3.0

type BodyProperty struct {
	Signature string `json:"Signature"` // "CM3D2_MAID_BODY"
	Version   int32  `json:"Version"`   // 版本号

}

BodyProperty 表示身体属性

type Bone

type Bone struct {
	Name        string     `json:"Name"`            // 骨骼名称
	HasScale    bool       `json:"HasScale"`        // 是否有缩放
	ParentIndex int32      `json:"ParentIndex"`     // 父骨骼索引
	Position    Vector3    `json:"Position"`        // 骨骼位置
	Rotation    Quaternion `json:"Rotation"`        // 骨骼旋转
	Scale       *Vector3   `json:"Scale,omitempty"` // 骨骼缩放(版本 2001 +)
}

Bone 表示骨骼数据

type BoneAttachPos added in v1.3.0

type BoneAttachPos struct {
	Enable      bool                  `json:"Enable"`                // 是否启用
	PosRotScale PositionRotationScale `json:"PositionRotationScale"` // 位置、旋转、缩放
}

BoneAttachPos 表示骨骼附着位置

type BoneAttachPosEntry added in v1.3.0

type BoneAttachPosEntry struct {
	RID           int32         `json:"RID"`           // C# KeyValuePair<int, BoneAttachPos>.Key
	BoneAttachPos BoneAttachPos `json:"BoneAttachPos"` // C# ...Value
}

type BoneCurveData

type BoneCurveData struct {
	BonePath       string          `json:"BonePath"`       // 骨骼路径(如"Bip01/Bip01 Spine/Bip01 Spine0a/Bip01 Spine1")
	PropertyCurves []PropertyCurve `json:"PropertyCurves"` // 该骨骼的所有属性动画曲线
}

BoneCurveData 存储某个骨骼(或节点)对应的一组曲线信息

type BoneLengthEntry added in v1.3.0

type BoneLengthEntry struct {
	RID     int32              `json:"RID"`
	Lengths map[string]float32 `json:"Lengths"`
}

type BoneValue

type BoneValue struct {
	BoneName string  `json:"BoneName"`
	Value    float32 `json:"Value"`
}

BoneValue 存储一个骨骼名称与对应 float 值

type BoneWeight

type BoneWeight struct {
	BoneIndex0 uint16  `json:"BoneIndex0"` // 骨骼索引
	BoneIndex1 uint16  `json:"BoneIndex1"`
	BoneIndex2 uint16  `json:"BoneIndex2"`
	BoneIndex3 uint16  `json:"BoneIndex3"`
	Weight0    float32 `json:"Weight0"` // 权重
	Weight1    float32 `json:"Weight1"`
	Weight2    float32 `json:"Weight2"`
	Weight3    float32 `json:"Weight3"`
}

BoneWeight 表示骨骼权重

type Col

type Col struct {
	Signature string      `json:"Signature"` // "CM3D21_COL"
	Version   int32       `json:"Version"`   // 24201 这个版本每次更新都会更改,但无结构更改
	Colliders []ICollider `json:"Colliders"` // 碰撞器列表
}

func ReadCol

func ReadCol(r io.Reader) (*Col, error)

ReadCol 从二进制流里读取一个 Col

func (*Col) Dump

func (c *Col) Dump(w io.Writer) error

Dump 把 Col 写出到 w 中

func (*Col) UnmarshalJSON

func (c *Col) UnmarshalJSON(data []byte) error

UnmarshalJSON 为 Col 实现自定义 UnmarshalJSON 因为 Col 的 ICollider 字段是一个接口切片,需要根据 typeName 字段来决定反序列化为哪个具体类型

type ColProperty

type ColProperty struct {
	TypeName string     `json:"TypeName" default:"col"`
	PropName string     `json:"PropName"`
	Color    [4]float32 `json:"Color"` // RGBA
}

func (*ColProperty) GetTypeName

func (c *ColProperty) GetTypeName() string

func (*ColProperty) Read

func (c *ColProperty) Read(reader *stream.BinaryReader) error

func (*ColProperty) Write

func (c *ColProperty) Write(writer *stream.BinaryWriter) error

type Command

type Command struct {
	Command string   `json:"Command"`
	Args    []string `json:"Args"`
}

Command 对应 .menu 中的命令

type DynamicBoneCollider

type DynamicBoneCollider struct {
	TypeName string                   `json:"TypeName" default:"dbc"` // 碰撞器类型,仅标记,不序列化 "dbc"
	Base     *DynamicBoneColliderBase `json:"Base"`                   // 基类

	Radius float32 `json:"Radius"` // 碰撞器半径
	Height float32 `json:"Height"` // 碰撞器高度
}

DynamicBoneCollider 对应 "dbc"

func (*DynamicBoneCollider) GetTypeName

func (dbc *DynamicBoneCollider) GetTypeName() string

func (*DynamicBoneCollider) Read

func (dbc *DynamicBoneCollider) Read(reader *stream.BinaryReader, version int32) error

func (*DynamicBoneCollider) Write

func (dbc *DynamicBoneCollider) Write(writer *stream.BinaryWriter, version int32) error

type DynamicBoneColliderBase

type DynamicBoneColliderBase struct {
	TypeName      string     `json:"TypeName"  default:"base"` // 碰撞器类型,仅标记,不序列化 "base"
	ParentName    string     `json:"ParentName"`               // 父级 Transform (骨骼)名称
	SelfName      string     `json:"SelfName"`                 // 当前 Transform 名称
	LocalPosition [3]float32 `json:"LocalPosition"`            // 局部坐标系中的位置 (x,y,z)
	LocalRotation [4]float32 `json:"LocalRotation"`            // 局部坐标系中的旋转 (四元数)
	LocalScale    [3]float32 `json:"LocalScale"`               // 局部坐标系中的缩放 (x,y,z)

	Direction int32      `json:"Direction"` // 碰撞体方向,指定哪一个轴是胶囊碰撞器的高(0=x, 1=y, 2=z)
	Center    [3]float32 `json:"Center"`    // 碰撞体中心偏移
	Bound     int32      `json:"Bound"`     // 碰撞约束边界类型 (0=Outside, 1=Inside)
}

DynamicBoneColliderBase 基类

func (*DynamicBoneColliderBase) GetTypeName

func (base *DynamicBoneColliderBase) GetTypeName() string

func (*DynamicBoneColliderBase) Read

func (base *DynamicBoneColliderBase) Read(reader *stream.BinaryReader, version int32) error

func (*DynamicBoneColliderBase) Write

func (base *DynamicBoneColliderBase) Write(writer *stream.BinaryWriter, version int32) error

type DynamicBoneMuneCollider

type DynamicBoneMuneCollider struct {
	TypeName string                   `json:"TypeName" default:"dbm"` // 碰撞器类型,仅标记,不序列化 "dbm"
	Base     *DynamicBoneColliderBase `json:"Base"`                   // 基类

	Radius          float32    `json:"Radius"`          // 碰撞器半径
	Height          float32    `json:"Height"`          // 碰撞器高度
	ScaleRateMulMax float32    `json:"ScaleRateMulMax"` // 最大缩放倍率
	CenterRateMax   [3]float32 `json:"CenterRateMax"`   // 最大中心偏移(x,y,z)
}

DynamicBoneMuneCollider 对应 "dbm"

func (*DynamicBoneMuneCollider) GetTypeName

func (c *DynamicBoneMuneCollider) GetTypeName() string

func (*DynamicBoneMuneCollider) Read

func (c *DynamicBoneMuneCollider) Read(reader *stream.BinaryReader, version int32) error

func (*DynamicBoneMuneCollider) Write

func (c *DynamicBoneMuneCollider) Write(writer *stream.BinaryWriter, version int32) error

type DynamicBonePlaneCollider

type DynamicBonePlaneCollider struct {
	TypeName string                   `json:"TypeName" default:"dpc"` // 碰撞器类型,仅标记,不序列化 "dpc"
	Base     *DynamicBoneColliderBase `json:"Base"`                   // 基类
}

DynamicBonePlaneCollider 对应 "dpc" 在 C# 中并无其它独立字段,只继承基类。

func (*DynamicBonePlaneCollider) GetTypeName

func (dpc *DynamicBonePlaneCollider) GetTypeName() string

func (*DynamicBonePlaneCollider) Read

func (dpc *DynamicBonePlaneCollider) Read(reader *stream.BinaryReader, version int32) error

func (*DynamicBonePlaneCollider) Write

func (dpc *DynamicBonePlaneCollider) Write(writer *stream.BinaryWriter, version int32) error

type FProperty

type FProperty struct {
	TypeName string  `json:"TypeName" default:"f"`
	PropName string  `json:"PropName"`
	Number   float32 `json:"Number"`
}

func (*FProperty) GetTypeName

func (f *FProperty) GetTypeName() string

func (*FProperty) Read

func (f *FProperty) Read(reader *stream.BinaryReader) error

func (*FProperty) Write

func (f *FProperty) Write(writer *stream.BinaryWriter) error

type ICollider

type ICollider interface {
	GetTypeName() string
	Read(reader *stream.BinaryReader, version int32) error
	Write(writer *stream.BinaryWriter, version int32) error
}

ICollider 是所有Collider的接口,不同具体类型各自实现。 注意在每个 struct 中保存 TypeName 是故意的,否则前端类型推断困难,实际不写入二进制。

type Keyframe

type Keyframe struct {
	Time       float32 `json:"Time"`
	Value      float32 `json:"Value"`
	InTangent  float32 `json:"InTangent"`
	OutTangent float32 `json:"OutTangent"`
}

Keyframe 与 UnityEngine.Keyframe 对应

type Keyword

type Keyword struct {
	Key   string `json:"Key"`
	Value bool   `json:"Value"`
}

type KeywordProperty

type KeywordProperty struct {
	TypeName string    `json:"TypeName" default:"keyword"`
	PropName string    `json:"PropName"`
	Count    int32     `json:"Count"`
	Keywords []Keyword `json:"Keywords"`
}

func (*KeywordProperty) GetTypeName

func (f *KeywordProperty) GetTypeName() string

func (*KeywordProperty) Read

func (f *KeywordProperty) Read(reader *stream.BinaryReader) error

func (*KeywordProperty) Write

func (f *KeywordProperty) Write(writer *stream.BinaryWriter) error

type MatPropSave added in v1.3.0

type MatPropSave struct {
	MatId    int32  `json:"MatId"`    // 材质编号
	PropName string `json:"PropName"` // 属性名称
	TypeName string `json:"TypeName"` // 类型名称
	Value    string `json:"Value"`    // 属性值
}

MatPropSave 表示材质属性保存

type MatPropSaveEntry added in v1.3.0

type MatPropSaveEntry struct {
	RID         int32       `json:"RID"`
	MatPropSave MatPropSave `json:"MatPropSave"`
}

type Mate

type Mate struct {
	Signature string    `json:"Signature"` // CM3D2_MATERIAL
	Version   int32     `json:"Version"`   // 1000 or 2000
	Name      string    `json:"Name"`
	Material  *Material `json:"Material"`
}

Mate 对应 .mate 文件的整体结构

func ReadMate

func ReadMate(r io.Reader) (*Mate, error)

ReadMate 从 r 中读取一个 .mate 文件,返回 Mate 结构

func (*Mate) Dump

func (m *Mate) Dump(w io.Writer) error

Dump 将 Mate 写出到 w 中

type Material

type Material struct {
	Name           string     `json:"Name"`
	ShaderName     string     `json:"ShaderName"`
	ShaderFilename string     `json:"ShaderFilename"`
	Properties     []Property `json:"Properties"`
}

Material 及其属性解析

func (*Material) Dump

func (m *Material) Dump(writer *stream.BinaryWriter) error

Dump 将 Material 写出到 w 中。

func (*Material) UnmarshalJSON

func (m *Material) UnmarshalJSON(data []byte) error

UnmarshalJSON 为 Material 实现自定义 UnmarshalJSON 因为 Material 的 Properties 字段是一个接口切片,需要根据 typeName 字段来决定反序列化为哪个具体类型

type Matrix4x4

type Matrix4x4 [16]float32

Matrix4x4 表示4x4矩阵

type Menu struct {
	Signature   string    `json:"Signature"` // "CM3D2_MENU"
	Version     int32     `json:"Version"`
	SrcFileName string    `json:"SrcFileName"`
	ItemName    string    `json:"ItemName"`
	Category    string    `json:"Category"`
	InfoText    string    `json:"InfoText"`
	BodySize    int32     `json:"BodySize"`
	Commands    []Command `json:"Commands"`
}

Menu 对应 .menu 文件的结构

func ReadMenu

func ReadMenu(r io.Reader) (*Menu, error)

ReadMenu 从 r 中读取一个 .menu 文件结构

func (m *Menu) Dump(w io.Writer) error

Dump 把 Menu 写出到 w 中

func (m *Menu) UpdateBodySize() error

UpdateBodySize 根据当前的 Commands 列表计算 BodySize。

  • 每个命令占用 1 字节记录 ArgCount。
  • 对于每个字符串参数,先计算其 UTF-8 编码后字节数 encodedLength,然后 加上 7BitEncoded 编码 encodedLength 所需的字节数,再加上 encodedLength 本身。
  • 最后再加上 1 个字节的结束标志。

type MissingCollider

type MissingCollider struct {
	TypeName string `json:"TypeName" default:"missing"` // 碰撞器类型,仅标记,不序列化 "missing"
}

MissingCollider 对应 "missing"

func (*MissingCollider) GetTypeName

func (m *MissingCollider) GetTypeName() string

func (*MissingCollider) Read

func (m *MissingCollider) Read(reader *stream.BinaryReader, version int32) error

func (*MissingCollider) Write

func (m *MissingCollider) Write(writer *stream.BinaryWriter, version int32) error

type Model

type Model struct {
	Signature         string         `json:"Signature"`                   // "CM3D2_MESH"
	Version           int32          `json:"Version"`                     // 2001
	Name              string         `json:"Name"`                        // 模型名称
	RootBoneName      string         `json:"RootBoneName"`                // 根骨骼名称
	ShadowCastingMode *string        `json:"ShadowCastingMode,omitempty"` // 定义如何投射阴影,Unity 的 ShadowCastingMode 的字符串表示(版本 2104 +且小于 2200)
	Bones             []*Bone        `json:"Bones"`                       // 骨骼数据
	VertCount         int32          `json:"VertCount"`                   // 顶点数量
	SubMeshCount      int32          `json:"SubMeshCount"`                // 子网格数量
	BoneCount         int32          `json:"BoneCount"`                   // 骨骼数量
	BoneNames         []string       `json:"BoneNames"`                   // 骨骼名称列表
	BindPoses         []Matrix4x4    `json:"BindPoses"`                   // 绑定姿势
	Vertices          []Vertex       `json:"Vertices"`                    // 顶点数据
	Tangents          []Quaternion   `json:"Tangents,omitempty"`          // 切线数据
	BoneWeights       []BoneWeight   `json:"BoneWeights"`                 // 骨骼权重数据
	SubMeshes         [][]int32      `json:"SubMeshes"`                   // 子网格索引列表
	Materials         []*Material    `json:"Materials"`                   // 材质数据
	MorphData         []*MorphData   `json:"MorphData,omitempty"`         // 形态数据
	SkinThickness     *SkinThickness `json:"SkinThickness,omitempty"`     // 皮肤厚度数据(版本 2100 +)
}

Model 对应 .model 文件 也称作 SkinMesh 皮肤网格

func ReadModel

func ReadModel(r io.Reader) (*Model, error)

ReadModel 从 r 中读取皮肤网格数据

func (*Model) Dump

func (m *Model) Dump(w io.Writer) error

type ModelMetadata added in v1.0.2

type ModelMetadata struct {
	Signature         string      `json:"Signature"`                   // "CM3D2_MESH"
	Version           int32       `json:"Version"`                     // 2001
	Name              string      `json:"Name"`                        // 模型名称
	RootBoneName      string      `json:"RootBoneName"`                // 根骨骼名称
	ShadowCastingMode *string     `json:"ShadowCastingMode,omitempty"` // 定义如何投射阴影,Unity 的 ShadowCastingMode 的字符串表示(版本 2104 +且小于 2200)
	Materials         []*Material `json:"Materials"`                   // 材质数据
}

ModelMetadata 表示模型的元数据 不包含模型的 3D 信息,只包含模型的文本信息 例如模型名称、根骨骼名称、材质名称等 用于编辑一些模型的文本属性 修改后需要与原模型文件合并

func ReadModelMetadata added in v1.4.0

func ReadModelMetadata(r io.Reader) (*ModelMetadata, error)

ReadModelMetadata 仅读取 Model 元数据,返回精简的 ModelMetadata

type MorphData

type MorphData struct {
	Name     string       `json:"Name"`               // 形态名称
	Indices  []int        `json:"Indices"`            // 顶点索引
	Vertex   []Vector3    `json:"Vertex"`             // 顶点位置
	Normals  []Vector3    `json:"Normals"`            // 顶点法线
	Tangents []Quaternion `json:"Tangents,omitempty"` // 切线(版本 2102 +)
}

MorphData 表示形态数据

func ReadMorphData

func ReadMorphData(reader *stream.BinaryReader, version int32) (*MorphData, error)

ReadMorphData 从 r 中读取形态数据

type MultiColor added in v1.3.0

type MultiColor struct {
	Signature   string       `json:"Signature"`   // "CM3D2_MULTI_COL"
	Version     int32        `json:"Version"`     // 版本号
	PartCount   int32        `json:"PartCount"`   // 颜色数量
	PartsColors []PartsColor `json:"PartsColors"` // 颜色列表
}

MultiColor 表示多颜色设置

type Nei added in v1.0.8

type Nei struct {
	Rows uint32     `json:"Rows"` // CSV 的行数
	Cols uint32     `json:"Cols"` // CSV 的列数
	Data [][]string `json:"Data"` // CSV 的数据 [行][列]
}

func ReadNei added in v1.0.8

func ReadNei(r io.Reader, neiKey []byte) (*Nei, error)

ReadNei 从 r 中读取一个 .nei 文件,并解析为 Nei 结构。 neiKey 传入 nil 则使用默认密钥

func (*Nei) Dump added in v1.0.8

func (nei *Nei) Dump(w io.Writer) error

Dump 将 nei 写出到 w 中,格式与 .Nei 兼容。

type PMat

type PMat struct {
	Signature    string  `json:"Signature"`    // "CM3D2_PMATERIAL"
	Version      int32   `json:"Version"`      // 1000
	Hash         int32   `json:"Hash"`         // 哈希值,用于缓存控制
	MaterialName string  `json:"MaterialName"` // 材质名称
	RenderQueue  float32 `json:"RenderQueue"`  // 渲染顺序
	Shader       string  `json:"Shader"`       // 着色器名称
}

PMat 对应 .PMat 文件结构

func ReadPMat

func ReadPMat(r io.Reader) (*PMat, error)

ReadPMat 从 r 中读取一个 .PMat 文件,并解析为 PMat 结构。

func (*PMat) Dump

func (p *PMat) Dump(w io.Writer, calculateHash bool) error

Dump 将 p 写出到 w 中,格式与 .PMat 兼容。

type PanierRadiusGroup

type PanierRadiusGroup struct {
	BoneName string         `json:"BoneName"`
	Radius   float32        `json:"Radius"`
	Curve    AnimationCurve `json:"Curve"`
}

PanierRadiusGroup 存储骨骼特定的半径信息

type PartsColor added in v1.3.0

type PartsColor struct {
	IsUse            bool  `json:"IsUse"`            // 是否使用
	MainHue          int32 `json:"MainHue"`          // 主色相
	MainChroma       int32 `json:"MainChroma"`       // 主色度
	MainBrightness   int32 `json:"MainBrightness"`   // 主亮度
	MainContrast     int32 `json:"MainContrast"`     // 主对比度
	ShadowRate       int32 `json:"ShadowRate"`       // 阴影比例
	ShadowHue        int32 `json:"ShadowHue"`        // 阴影色相
	ShadowChroma     int32 `json:"ShadowChroma"`     // 阴影色度
	ShadowBrightness int32 `json:"ShadowBrightness"` // 阴影亮度
	ShadowContrast   int32 `json:"ShadowContrast"`   // 阴影对比度
}

PartsColor 表示部件颜色

type Phy

type Phy struct {
	// 头部信息
	Signature string `json:"Signature"` // 1. 签名, 通常为 "CM3D21_PHY"
	Version   int32  `json:"Version"`   // 2. 版本 (例如 24102) 这个版本每次更新都会更改,但无结构更改
	RootName  string `json:"RootName"`  // 3. RootBone 名称

	// 4. Damping 阻尼相关参数
	EnablePartialDamping int32          `json:"EnablePartialDamping"` // PartialMode 枚举,模式
	PartialDamping       []BoneValue    `json:"PartialDamping"`       // 按骨骼设置的阻尼值
	Damping              float32        `json:"Damping"`              // 静态或曲线模式下的阻尼值
	DampingDistrib       AnimationCurve `json:"DampingDistrib"`       // 曲线

	// 5. Elasticity 弹性相关参数
	EnablePartialElasticity int32          `json:"EnablePartialElasticity"`
	PartialElasticity       []BoneValue    `json:"PartialElasticity"`
	Elasticity              float32        `json:"Elasticity"`
	ElasticityDistrib       AnimationCurve `json:"ElasticityDistrib"`

	// 6. Stiffness 刚度相关参数
	EnablePartialStiffness int32          `json:"EnablePartialStiffness"`
	PartialStiffness       []BoneValue    `json:"PartialStiffness"`
	Stiffness              float32        `json:"Stiffness"`
	StiffnessDistrib       AnimationCurve `json:"StiffnessDistrib"`

	// 7. Inert 惯性相关参数
	EnablePartialInert int32          `json:"EnablePartialInert"`
	PartialInert       []BoneValue    `json:"PartialInert"`
	Inert              float32        `json:"Inert"`
	InertDistrib       AnimationCurve `json:"InertDistrib"`

	// 8. 碰撞半径相关参数
	EnablePartialRadius int32          `json:"EnablePartialRadius"`
	PartialRadius       []BoneValue    `json:"PartialRadius"`
	Radius              float32        `json:"Radius"`
	RadiusDistrib       AnimationCurve `json:"RadiusDistrib"`

	// 9. 骨骼末端参数
	EndLength float32    `json:"EndLength"`
	EndOffset [3]float32 `json:"EndOffset"`

	// 10. 外力参数
	Gravity [3]float32 `json:"Gravity"`
	Force   [3]float32 `json:"Force"`

	// 10. 碰撞器相关参数
	ColliderFileName string `json:"ColliderFileName"` // 碰撞器文件名
	CollidersCount   int32  `json:"CollidersCount"`   // 碰撞器数量

	// 11.  排除骨骼
	ExclusionsCount int32 `json:"ExclusionsCount"` // 排除的骨骼数量

	// 12. 冻结轴向
	FreezeAxis int32 `json:"FreezeAxis"` // FreezeAxis 枚举
}

func ReadPhy

func ReadPhy(r io.Reader) (*Phy, error)

ReadPhy 读取 "CM3D21_PHY" 格式

func (*Phy) Dump

func (p *Phy) Dump(w io.Writer) error

Dump 写出 "CM3D21_PHY" 格式

type PositionRotationScale added in v1.3.0

type PositionRotationScale struct {
	Position Vector3    `json:"Position"` // 位置
	Rotation Quaternion `json:"Rotation"` // 旋转
	Scale    Vector3    `json:"Scale"`    // 缩放
}

PositionRotationScale 表示组合位置、旋转、缩放信息

type Preset added in v1.3.0

type Preset struct {
	Signature          string              `json:"Signature"`          // "CM3D2_PRESET"
	Version            int32               `json:"Version"`            // 版本号  大于等于 30000 的是 COM3D2.5 格式,大于等于 1560 且小于 20000 的是 CM3D2 格式,版本号介于 20000 到 30000 之间的是 COM3D2 格式
	PresetType         int32               `json:"PresetType"`         // 预设类型:0=衣服, 1=身体, 2=全部
	ThumbLength        int32               `json:"ThumbLength"`        // 略缩图数据长度
	ThumbData          []byte              `json:"ThumbData"`          // 略缩图数据,PNG格式
	PresetPropertyList *PresetPropertyList `json:"PresetPropertyList"` // 预设属性列表
	MultiColor         *MultiColor         `json:"MultiColor"`         // 颜色设置
	BodyProperty       *BodyProperty       `json:"BodyProperty"`       // 身体属性
}

Preset 表示角色预设数据

func ReadPreset added in v1.3.0

func ReadPreset(r io.Reader) (*Preset, error)

ReadPreset 从 r 中读取 Preset

func (*Preset) Dump added in v1.3.0

func (p *Preset) Dump(w io.Writer) error

type PresetMetadata added in v1.3.0

type PresetMetadata struct {
	Signature   string `json:"Signature"`   // "CM3D2_PRESET"
	Version     int32  `json:"Version"`     // 版本号
	PresetType  int32  `json:"PresetType"`  // 预设类型:0=衣服, 1=身体, 2=全部
	ThumbLength int32  `json:"ThumbLength"` // 略缩图数据长度
	ThumbData   []byte `json:"ThumbData"`   // 略缩图数据,PNG格式
}

PresetMetadata 表示仅包含略缩图的的角色预设数据,不包含实际数据

func ReadPresetMetadata added in v1.3.0

func ReadPresetMetadata(reader *stream.BinaryReader) (*PresetMetadata, error)

ReadPresetMetadata 从 r 中读取 PresetMetadata

type PresetProperty added in v1.3.0

type PresetProperty struct {
	Signature       string                               `json:"Signature"`       // "CM3D2_MPROP"
	Version         int32                                `json:"Version"`         // 版本号
	Index           int32                                `json:"Index"`           // 索引
	Name            string                               `json:"Name"`            // 名称
	Type            int32                                `json:"Type"`            // 类型
	DefaultValue    int32                                `json:"DefaultValue"`    // 默认值
	Value           int32                                `json:"Value"`           // 当前值
	TempValue       int32                                `json:"TempValue"`       // 临时值
	LinkMaxValue    int32                                `json:"LinkMaxValue"`    // 链接最大值
	FileName        string                               `json:"FileName"`        // 文件名
	FileNameRID     int32                                `json:"FileNameRID"`     // 文件名哈希值  this.strFileName.ToLower().GetHashCode();
	IsDut           bool                                 `json:"IsDut"`           // 是否使用
	Max             int32                                `json:"Max"`             // 最大值
	Min             int32                                `json:"Min"`             // 最小值
	SubProps        []SubProp                            `json:"SubProps"`        // 子属性列表
	SkinPositions   map[int]BoneAttachPosEntry           `json:"SkinPositions"`   // 皮肤位置 slotID -> (RID, BoneAttachPos)
	AttachPositions map[int]map[string]VtxAttachPosEntry `json:"AttachPositions"` // 附件位置 slotID -> name -> (RID, VtxAttachPos)
	MaterialProps   map[int]MatPropSaveEntry             `json:"MaterialProps"`   // 材质属性 slotID -> (RID, MatPropSave)
	BoneLengths     map[int]BoneLengthEntry              `json:"BoneLengths"`     // 骨骼长度 slotID -> (RID, map[name]len)
}

PresetProperty 表示单个属性

type PresetPropertyList added in v1.3.0

type PresetPropertyList struct {
	Signature        string                    `json:"Signature"`        // "CM3D2_MPROP_LIST"
	Version          int32                     `json:"Version"`          // 版本号
	PropertyCount    int32                     `json:"PropertyCount"`    // 属性数量
	PresetProperties map[string]PresetProperty `json:"PresetProperties"` // 属性映射表
}

PresetPropertyList 表示预设属性列表

type Property

type Property interface {
	GetTypeName() string
	Read(reader *stream.BinaryReader) error
	Write(writer *stream.BinaryWriter) error
}

Property 是一个接口,对应 C# 里的抽象 class Property Go 中我们用接口 + 具体 struct 来表达 注意在每个 struct 中保存 TypeName 是故意的,否则前端类型推断困难

type PropertyCreator

type PropertyCreator func() Property

PropertyCreator 定义属性创建器类型

type PropertyCurve

type PropertyCurve struct {
	PropertyIndex int        `json:"PropertyIndex"` // 属性索引 b=100 => index=0, b=101 => index=1, 最高位为 6,含义查看上方枚举
	Keyframes     []Keyframe `json:"Keyframes"`     // 该属性的所有关键帧数据
}

PropertyCurve 存储单一属性(例如 localRotation.x)的一整条 AnimationCurve

type Psk

type Psk struct {
	Signature                    string              `json:"Signature"`                    // CM3D21_PSK
	Version                      int32               `json:"Version"`                      // 24301 这个版本每次更新都会更改,但无结构更改
	PanierRadius                 float32             `json:"PanierRadius"`                 // 裙撑半径
	PanierRadiusDistrib          AnimationCurve      `json:"PanierRadiusDistrib"`          // 裙撑半径分布曲线
	PanierRadiusDistribGroups    []PanierRadiusGroup `json:"PanierRadiusDistribGroups"`    // 裙撑半径分布组
	PanierForce                  float32             `json:"PanierForce"`                  // 裙撑力度
	PanierForceDistrib           AnimationCurve      `json:"PanierForceDistrib"`           // 裙撑力度分布曲线
	PanierStressForce            float32             `json:"PanierStressForce"`            // 裙撑应力
	StressDegreeMin              float32             `json:"StressDegreeMin"`              // 最小应力度
	StressDegreeMax              float32             `json:"StressDegreeMax"`              // 最大应力度
	StressMinScale               float32             `json:"StressMinScale"`               // 最小应力缩放
	ScaleEaseSpeed               float32             `json:"ScaleEaseSpeed"`               // 缩放平滑速度
	PanierForceDistanceThreshold float32             `json:"PanierForceDistanceThreshold"` // 裙撑力度距离阈值
	CalcTime                     int32               `json:"CalcTime"`                     // 计算时间
	VelocityForceRate            float32             `json:"VelocityForceRate"`            // 速度力率
	VelocityForceRateDistrib     AnimationCurve      `json:"VelocityForceRateDistrib"`     // 速度力率分布曲线
	Gravity                      Vector3             `json:"Gravity"`                      // 重力向量
	GravityDistrib               AnimationCurve      `json:"GravityDistrib"`               // 重力分布曲线
	HardValues                   [4]float32          `json:"HardValues"`                   // 硬度值数组
}

Psk 整体描述一个 .psk 文件的结构

func ReadPsk

func ReadPsk(r io.Reader) (*Psk, error)

ReadPsk 读取并解析一个 .psk 文件,返回 Psk 结构。

func (Psk) Dump

func (p Psk) Dump(w io.Writer) error

Dump 将 Psk 结构写到 w 中,生成符合 CM3D21_PSK 格式的二进制数据。

type Quaternion

type Quaternion struct {
	X float32 `json:"X"`
	Y float32 `json:"Y"`
	Z float32 `json:"Z"`
	W float32 `json:"W"`
}

Quaternion 表示四元数

type RangeProperty

type RangeProperty struct {
	TypeName string  `json:"TypeName" default:"range"`
	PropName string  `json:"PropName"`
	Number   float32 `json:"Number"`
}

func (*RangeProperty) GetTypeName

func (ra *RangeProperty) GetTypeName() string

func (*RangeProperty) Read

func (ra *RangeProperty) Read(reader *stream.BinaryReader) error

func (*RangeProperty) Write

func (ra *RangeProperty) Write(writer *stream.BinaryWriter) error

type SkinThickness

type SkinThickness struct {
	Signature string                 `json:"Signature"` // "SkinThickness"
	Version   int32                  `json:"Version"`   // 版本号
	Use       bool                   `json:"Use"`       // 是否使用皮肤厚度
	Groups    map[string]*ThickGroup `json:"Groups"`    // 皮肤厚度组
}

SkinThickness 表示皮肤厚度数据

func ReadSkinThickness

func ReadSkinThickness(reader *stream.BinaryReader) (*SkinThickness, error)

ReadSkinThickness 从 r 中读取皮肤厚度数据

type SubProp added in v1.3.0

type SubProp struct {
	IsDut       bool    `json:"IsDut"`       // 是否使用
	FileName    string  `json:"FileName"`    // 文件名
	FileNameRID int32   `json:"FileNameRID"` // 文件名哈希值
	TexMulAlpha float32 `json:"TexMulAlpha"` // 纹理乘法透明度
}

SubProp 表示子属性

type Tex

type Tex struct {
	Signature     string    `json:"Signature"`     // 一般是 "CM3D2_TEX"
	Version       int32     `json:"Version"`       // 版本号
	TextureName   string    `json:"TextureName"`   // 纹理文件名
	Rects         []TexRect `json:"Rects"`         // 如果版本 >= 1011 才会有,纹理图集使用
	Width         int32     `json:"Width"`         // 版本 >= 1010 才会有,否则可能需要从 data 解析
	Height        int32     `json:"Height"`        // 版本 >= 1010 才会有,否则可能需要从 data 解析
	TextureFormat int32     `json:"TextureFormat"` // 读取到的原始格式枚举,Go 参考顶部常量
	Data          []byte    `json:"Data"`          // DDS/Bitmap 原始二进制数据
}

func ConvertImageToTex

func ConvertImageToTex(inputPath string, texName string, compress bool, forcePNG bool) (*Tex, error)

ConvertImageToTex 将任意 ImageMagick 支持的文件格式转换为 tex 格式,但不写出 依赖外部库 ImageMagick,且有 Path 环境变量可以直接调用 magick 命令 如果 forcePNG 为 true,且 compress 为 false,则 tex 的数据位是原始 PNG 数据或转换为 PNG 如果 forcePNG 为 false,且 compress 为 false,那么检查输入格式是否是 PNG 或 JPG,如果是则数据位直接使用原始图片,否则如果原始格式有损且无透明通道则转换为 JPG,否则转换为 PNG 如果 forcePNG 为 true,且 compress 为 true,那么 compress 标识会被忽略,结果同 forcePNG 为 true,且 compress 为 false 如果 forcePNG 为 false,且 compress 为 true,那么会对结果进行 DXT 压缩,数据位为 DDS 数据,根据有无透明通道选择 DXT1 或 DXT5 如果要生成 1011 版本的 tex(纹理图集),需要在图片目录下有一个同名的 .uv.csv 文件(例如 foo.png 对应 foo.png.uv.csv),文件内容为矩形数组 x, y, w, h 一行一组 否则生成 1010 版本的 tex

func ReadTex

func ReadTex(r io.Reader) (*Tex, error)

ReadTex 从二进制流中读取 Tex 数据。 需要数据流是 .tex 格式

func (*Tex) Dump

func (t *Tex) Dump(w io.Writer) error

Dump 将 Tex 数据写入二进制流。 输出的数据流是 .tex 格式

type Tex2DSubProperty

type Tex2DSubProperty struct {
	Name   string     `json:"Name"`
	Path   string     `json:"Path"`
	Offset [2]float32 `json:"Offset"` // (x, y)
	Scale  [2]float32 `json:"Scale"`  // (x, y)
}

type TexOffsetProperty

type TexOffsetProperty struct {
	TypeName string  `json:"TypeName" default:"tex_offset"`
	PropName string  `json:"PropName"`
	OffsetX  float32 `json:"OffsetX"`
	OffsetY  float32 `json:"OffsetY"`
}

func (*TexOffsetProperty) GetTypeName

func (to *TexOffsetProperty) GetTypeName() string

func (*TexOffsetProperty) Read

func (to *TexOffsetProperty) Read(reader *stream.BinaryReader) error

func (*TexOffsetProperty) Write

func (to *TexOffsetProperty) Write(writer *stream.BinaryWriter) error

type TexProperty

type TexProperty struct {
	TypeName string            `json:"TypeName" default:"tex"`
	PropName string            `json:"PropName"`
	SubTag   string            `json:"SubTag"`
	Tex2D    *Tex2DSubProperty `json:"Tex2D"`
	TexRT    *TexRTSubProperty `json:"TexRT"`
}

func (*TexProperty) GetTypeName

func (t *TexProperty) GetTypeName() string

func (*TexProperty) Read

func (t *TexProperty) Read(reader *stream.BinaryReader) error

func (*TexProperty) Write

func (t *TexProperty) Write(writer *stream.BinaryWriter) error

type TexRTSubProperty

type TexRTSubProperty struct {
	DiscardedStr1 string `json:"DiscardedStr1"`
	DiscardedStr2 string `json:"DiscardedStr2"`
}

type TexRect

type TexRect struct {
	X float32 `json:"X"`
	Y float32 `json:"Y"`
	W float32 `json:"W"`
	H float32 `json:"H"`
}

func ConvertTexToImage

func ConvertTexToImage(tex *Tex, forcePNG bool) (imgData []byte, format string, rects []TexRect, err error)

ConvertTexToImage 将 Tex 数据转换为图像数据,但不写出 依赖外部库 ImageMagick,且有 Path 环境变量可以直接调用 magick 命令 如果 forcePNG 为 false 那么如果图像数据位是 JPG 或 PNG 则直接返回数据为,否则根据有没有透明通道保存为 JPG 或 PNG 如果 forcePNG 为 true 则强制保存为 PNG,不考虑图像格式和透明通道 如果是 1011 版本的 tex(纹理图集),则还会返回 rects

type TexScaleProperty

type TexScaleProperty struct {
	TypeName string  `json:"TypeName" default:"tex_scale"`
	PropName string  `json:"PropName"`
	ScaleX   float32 `json:"ScaleX"`
	ScaleY   float32 `json:"ScaleY"`
}

func (*TexScaleProperty) GetTypeName

func (ts *TexScaleProperty) GetTypeName() string

func (*TexScaleProperty) Read

func (ts *TexScaleProperty) Read(reader *stream.BinaryReader) error

func (*TexScaleProperty) Write

func (ts *TexScaleProperty) Write(writer *stream.BinaryWriter) error

type ThickDefPerAngle

type ThickDefPerAngle struct {
	AngleDegree     int32   `json:"AngleDegree"`     // 角度
	VertexIndex     int32   `json:"VertexIndex"`     // 顶点索引
	DefaultDistance float32 `json:"DefaultDistance"` // 默认距离
}

ThickDefPerAngle 表示每个角度的皮肤厚度定义

type ThickGroup

type ThickGroup struct {
	GroupName       string        `json:"GroupName"`       // 组名称
	StartBoneName   string        `json:"StartBoneName"`   // 起始骨骼名称
	EndBoneName     string        `json:"EndBoneName"`     // 结束骨骼名称
	StepAngleDegree int32         `json:"StepAngleDegree"` // 角度步长
	Points          []*ThickPoint `json:"Points"`          // 皮肤厚度点
}

ThickGroup 表示皮肤厚度组

type ThickPoint

type ThickPoint struct {
	TargetBoneName         string              `json:"TargetBoneName"`         // 目标骨骼名称
	RatioSegmentStartToEnd float32             `json:"RatioSegmentStartToEnd"` // 起始到结束的比例
	DistanceParAngle       []*ThickDefPerAngle `json:"DistanceParAngle"`       // 距离和角度定义
}

ThickPoint 表示皮肤厚度点

type VecProperty

type VecProperty struct {
	TypeName string     `json:"TypeName" default:"vec"`
	PropName string     `json:"PropName"`
	Vector   [4]float32 `json:"Vector"`
}

func (*VecProperty) GetTypeName

func (v *VecProperty) GetTypeName() string

func (*VecProperty) Read

func (v *VecProperty) Read(reader *stream.BinaryReader) error

func (*VecProperty) Write

func (v *VecProperty) Write(writer *stream.BinaryWriter) error

type Vector2

type Vector2 struct {
	X float32 `json:"X"`
	Y float32 `json:"Y"`
}

Vector2 表示二维向量或UV坐标

type Vector3

type Vector3 struct {
	X float32 `json:"X"`
	Y float32 `json:"Y"`
	Z float32 `json:"Z"`
}

Vector3 表示三维向量

type Vertex

type Vertex struct {
	Position Vector3  `json:"Position"`           // 顶点位置
	Normal   Vector3  `json:"Normal"`             // 顶点法线
	UV       Vector2  `json:"UV"`                 // 顶点 UV 坐标(版本 2101 +)
	UV2      *Vector2 `json:"UV2,omitempty"`      // 顶点 UV2 坐标
	UV3      *Vector2 `json:"UV3,omitempty"`      // 顶点 UV3 坐标
	UV4      *Vector2 `json:"UV4,omitempty"`      // 顶点 UV4 坐标
	Unknown1 *Vector2 `json:"Unknown1,omitempty"` // 顶点未知 1 坐标
	Unknown2 *Vector2 `json:"Unknown2,omitempty"` // 顶点未知 2 坐标
	Unknown3 *Vector2 `json:"Unknown3,omitempty"` // 顶点未知 3 坐标
	Unknown4 *Vector2 `json:"Unknown4,omitempty"` // 顶点未知 4 坐标
}

Vertex 表示顶点数据

type VtxAttachPos added in v1.3.0

type VtxAttachPos struct {
	Enable      bool                  `json:"Enable"`                // 是否启用
	VtxCount    int32                 `json:"VtxCount"`              // 顶点数量
	VtxIdx      int32                 `json:"VtxIdx"`                // 顶点索引
	PosRotScale PositionRotationScale `json:"PositionRotationScale"` // 位置、旋转、缩放
}

VtxAttachPos 表示顶点附着位置

type VtxAttachPosEntry added in v1.3.0

type VtxAttachPosEntry struct {
	RID          int32        `json:"RID"`
	VtxAttachPos VtxAttachPos `json:"VtxAttachPos"`
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL