Skip to content

Commit

Permalink
more char work (#462)
Browse files Browse the repository at this point in the history
* charcollide and charcuff

* begin chardriver stuff

* chardriver work

* chardriver work

* chareyes got hands

* more char stuff

* charhair work

* charhair work

* charlipsync work

* charlipsync/driver
  • Loading branch information
rjkiv authored Jan 18, 2025
1 parent d894514 commit 31fddf5
Show file tree
Hide file tree
Showing 33 changed files with 1,738 additions and 444 deletions.
314 changes: 157 additions & 157 deletions config/SZBE69/symbols.txt

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion config/SZBE69_B8/objects.json
Original file line number Diff line number Diff line change
Expand Up @@ -948,7 +948,10 @@
"system/char/CharDriverMidi.cpp": "NonMatching",
"system/char/CharEyeDartRuleset.cpp": "Matching",
"system/char/CharEyes.cpp": "NonMatching",
"system/char/CharFaceServo.cpp": "NonMatching",
"system/char/CharFaceServo.cpp": {
"status": "Equivalent",
"comment": "Poll and ScaleAdd check out in retail"
},
"system/char/CharForeTwist.cpp": {
"status": "Equivalent",
"comment": "Poll checks out in retail"
Expand Down
2 changes: 2 additions & 0 deletions src/system/bandobj/BandCharacter.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "bandobj/BandCharacter.h"
#include "bandobj/BandHeadShaper.h"
#include "bandobj/BandWardrobe.h"
#include "char/CharCollide.h"
#include "char/CharServoBone.h"
#include "char/CharClipDriver.h"
#include "char/CharClipGroup.h"
Expand Down Expand Up @@ -385,6 +386,7 @@ void BandCharacter::SyncObjects(){
}
}

unk5e0.sort(ByRadius());
// iVar4 = *(int *)(this + 0x5e4);
// if ((iVar4 != 0) && (*(int *)(iVar4 + 4) != 0)) {
// piVar12 = *(int **)(iVar4 + 8);
Expand Down
2 changes: 1 addition & 1 deletion src/system/bandobj/BandHeadShaper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ void BandHeadShaper::AddChildBones(RndTransformable* t){
std::vector<RndTransformable*>::iterator it = std::find(unk18.begin(), unk18.end(), t);
if(it == unk18.end()){
unk18.push_back(t);
for(std::vector<RndTransformable*>::iterator child = t->TransChildren().begin(); child != t->TransChildren().end(); ++child){
for(std::vector<RndTransformable*>::const_iterator child = t->TransChildren().begin(); child != t->TransChildren().end(); ++child){
AddChildBones(*child);
}
}
Expand Down
27 changes: 23 additions & 4 deletions src/system/char/CharClipDisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@

class MsgSource;

class CharClipDisplay {
class CharClipDisplay { // size 0x68
public:
CharClipDisplay() : unk0(0), unk4(0), unk8(0), unkc(0), unk10(0), unk14(0), unk18(0), unk1c(0), unk20(0), unk64(0) {

}

MsgSource* FindSource(Hmx::Object*);
void SetClip(CharClip*, bool);
Expand All @@ -25,8 +28,24 @@ class CharClipDisplay {
float unkc;
float unk10;
float unk14;
int unk18;
int unk1c;
int unk20;
float unk18;
float unk1c;
float unk20;
char* unk24;
int unk28;
int unk2c;
int unk30;
int unk34;
int unk38;
int unk3c;
int unk40;
int unk44;
int unk48;
int unk4c;
int unk50;
int unk54;
int unk58;
int unk5c;
int unk60;
float unk64;
};
6 changes: 6 additions & 0 deletions src/system/char/CharClipDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@ class CharClipDriver {
void ScaleAdd(CharBones&, float);
void RotateTo(CharBones&, float);
CharClipDriver* DeleteClip(Hmx::Object*);
CharClipDriver* PreEvaluate(float, float, float);
float Evaluate(float, float, float);
CharClipDriver* Next() const { return mNext; }
CharClip* GetClip() const { return mClip; }

static int GetUpperFlags(int flags){
return (flags >> 0xC) & 0xF;
}

NEW_POOL_OVERLOAD(CharClipDriver)
DELETE_POOL_OVERLOAD(CharClipDriver)

Expand Down
19 changes: 17 additions & 2 deletions src/system/char/CharCollide.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ void CharCollide::Highlight(){
}
if(mMesh){
int numspheres = NumSpheres();
for(int i = 0; i < numspheres * 2; i++){
for(int i = 0; i < numspheres * 4; i++){
UtilDrawSphere(mMesh->VertAt(unk_structs[i].unk0).pos, 0.1f, Hmx::Color(0.0f, 0.0f, 1.0f));
}
}
Expand Down Expand Up @@ -107,7 +107,22 @@ BEGIN_COPYS(CharCollide)
END_COPYS

void CharCollide::Deform(){
int numSpheres = NumSpheres();
if(mMesh){
for(int i = 0; i < 8; i++){
if(unk_structs[i].unk0 >= mMesh->Verts().size()){
mMesh->Verts().size();
PathName(mMesh);
PathName(this);
return;
}
}
Sphere sc8;
Sphere sb8;
for(int i = 0; i < numSpheres; i++){

}
}
}

int CharCollide::NumSpheres(){
Expand All @@ -123,7 +138,7 @@ void CharCollide::CopyOriginalToCur(){


void CharCollide::SyncShape(){
f32 t = mCurLength[1];
float t = mCurLength[1];
if(mCurLength[0] > t){
mCurLength[0] = mCurLength[1];
}
Expand Down
33 changes: 27 additions & 6 deletions src/system/char/CharCollide.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#ifndef CHAR_CHARCOLLIDE_H
#define CHAR_CHARCOLLIDE_H
#pragma once
#include "math/Vec.h"
#include "rndobj/Trans.h"
#include "rndobj/Mesh.h"
#include "math/SHA1.h"
#include "obj/ObjPtr_p.h"

/** "Feeds the bones when executed." */
class CharCollide : public RndTransformable {
public:
enum Shape {
Expand All @@ -17,7 +18,7 @@ class CharCollide : public RndTransformable {

struct CharCollideStruct {
CharCollideStruct(){}
int unk0;
int unk0; // size?
Vector3 vec;
};

Expand All @@ -33,7 +34,7 @@ class CharCollide : public RndTransformable {
virtual void Highlight();

void CopyOriginalToCur();
float Radius() const;
float Radius() const { return mCurRadius[0]; }
Shape GetShape() const { return mShape; }
const Vector3& Axis() const;
void SyncShape();
Expand All @@ -55,6 +56,17 @@ class CharCollide : public RndTransformable {
}
return ret;
}

void SyncWorldState(){
unk1a0 = WorldXfm().v;
if(mShape >= 3 || mShape == 0){
unk194 = WorldXfm().m.x;
unk190 = 1.0f / LengthSquared(unk194);
}
if(mShape >= 3){
unk18c = 1.0f / (mCurLength[1] - mCurLength[0]);
}
}

DECLARE_REVS;
NEW_OVERLOAD;
Expand All @@ -64,21 +76,30 @@ class CharCollide : public RndTransformable {
REGISTER_OBJ_FACTORY(CharCollide)
}

/** "Type of collision" */
Shape mShape; // 0x90
int mFlags; // 0x94
ObjPtr<RndMesh, ObjectDir> mMesh; // 0x98
/** "Optional mesh that will deform, used to resize ourselves. If this is set, make sure you are not parented to any bone with scale, such as an exo bone" */
ObjPtr<RndMesh> mMesh; // 0x98
CSHA1::Digest mDigest; // 0xa4
CharCollideStruct unk_structs[8]; // 0xb8 - 0x134, inclusive
// radius0: "Radius of the sphere, or of length0 hemisphere if cigar"
// radius1: "cigar: Radius of length1 hemisphere"
float mOrigRadius[2]; // 0x138 - radius0 at 0x138, radius1 at 0x13c
// length0: "cigar: placement of radius0 hemisphere along X axis, must be < than length0, not used for sphere shapes"
// length1: "cigar: placement of radius1 hemisphere along X axis, must be >= length0"
float mOrigLength[2]; // 0x140 - length0 at 0x140, length1 at 0x144
Transform unk148; // 0x148
float mCurRadius[2]; // 0x178
float mCurLength[2]; // 0x180
/** "For spheres + cigars, finds mesh points along positive y axis (the green one), makes a better fit for spheres where only one side should be the fit, like for chest and back collision volumes" */
bool mMeshYBias; // 0x188
float unk18c;
float unk190;
Vector3 unk194;
Vector3 unk1a0;
};

#endif
struct ByRadius {
bool operator()(CharCollide* c1, CharCollide* c2) const { return c2->Radius() > c1->Radius() ? true : false; }
};
105 changes: 100 additions & 5 deletions src/system/char/CharCuff.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
#include "char/CharCuff.h"
#include "char/FileMerger.h"
#include "decomp.h"
#include "math/Rot.h"
#include "math/Trig.h"
#include "math/Vec.h"
#include "os/Debug.h"
#include "rndobj/Mesh.h"
#include "rndobj/Rnd.h"
#include "rndobj/Trans.h"
#include "utl/Symbols.h"

INIT_REVS(CharCuff)
Expand Down Expand Up @@ -29,33 +37,120 @@ float CharCuff::Eccentricity(const Vector2& v) const {

// fn_804C3D90 - highlight
void CharCuff::Highlight(){

Hmx::Color white(1,1,1,1);
for(int i = 0; i < 2; i++){
for(int j = 0; j < 32; j++){
float toSine = j * 6.2831855f / 32.0f;
Vector3 va8(Sine(toSine), Cosine(toSine), mShape[i].offset);
Vector3 vb4(Sine(toSine), Cosine(toSine), mShape[i + 1].offset);
(Vector2&)va8 *= mShape[i].radius * Eccentricity((Vector2&)va8);
(Vector2&)vb4 *= mShape[i + 1].radius * Eccentricity((Vector2&)vb4);
Vector3 vc0;
Multiply(va8, WorldXfm(), vc0);
Vector3 vcc;
Multiply(vb4, WorldXfm(), vcc);
TheRnd->DrawLine(vc0, vcc, white, false);
if(i < 2){
float toSinePlus1 = (j + 1) * 6.2831855f / 32.0f;
va8.Set(Sine(toSinePlus1), Cosine(toSinePlus1), mShape[i].offset);
(Vector2&)va8 *= mShape[i].radius * Eccentricity((Vector2&)va8);
Multiply(va8, WorldXfm(), vcc);
TheRnd->DrawLine(vc0, vcc, white, false);
}
if(i == 1){
Vector3 vd8(Sine(toSine), Cosine(toSine), mShape[i].offset);
(Vector2&)vd8 *= mOuterRadius;
Multiply(vd8, WorldXfm(), vc0);
float toSinePlus1 = (j + 1) * 6.2831855f / 32.0f;
vb4.Set(Sine(toSinePlus1), Cosine(toSinePlus1), mShape[i].offset);
(Vector2&)vb4 *= mOuterRadius;
Multiply(vb4, WorldXfm(), vcc);
TheRnd->DrawLine(vc0, vcc, white, false);
}
}
}
}

unsigned int BoneMask(std::list<RndTransformable*>& tlist, RndMesh* mesh){
for(int i = 0; i < mesh->mBones.size(); i++){

unsigned int mask = 0;
for(int i = 0; i < mesh->NumBones(); i++){
if(std::find(tlist.begin(), tlist.end(), mesh->BoneTransAt(i)) != tlist.end()){
mask |= 1 << i;
}
}
return mask;
}

void AddBoneChildren(std::list<RndTransformable*>& tlist, RndTransformable* trans){
if(trans){
if(strncmp(trans->Name(), "bone_", 5) == 0){
tlist.push_back(trans);
for(std::vector<RndTransformable*>::iterator it = trans->TransChildren().begin(); it != trans->TransChildren().end(); ++it){
for(std::vector<RndTransformable*>::const_iterator it = trans->TransChildren().begin(); it != trans->TransChildren().end(); ++it){
AddBoneChildren(tlist, *it);
}
}
}
}

void CharCuff::DeformMesh(RndMesh*, int, SyncMeshCB*){
void CharCuff::Deform(SyncMeshCB* cb, FileMerger* fm){
if(mBone){
std::list<RndMesh*> meshes;
for(ObjDirItr<CharCuff> it(Dir(), false); it != nullptr; ++it){
if(it != this){
if(it->mBone == mBone){
if(it->mOuterRadius > mOuterRadius) return;
if(mOuterRadius == it->mOuterRadius){
if(strcmp(it->Name(), Name()) > 0) return;
}
for(ObjPtrList<RndMesh>::iterator iter = it->mIgnore.begin(); iter != it->mIgnore.end(); ++iter){
meshes.push_back(*iter);
}
}
}
}
FileMerger::Merger* merger = nullptr;
if(fm){
for(int i = 0; i < fm->mMergers.size(); i++){
merger = &fm->mMergers[i];
if(
strstr(merger->mName.mStr, mCategory.mStr) &&
merger->mLoadedObjects.size() != 0 &&
merger->mLoadedObjects.front()->Dir() == Dir()
){
break;
}
}
}
if(!merger) return;
else {
std::list<RndTransformable*> transes;
AddBoneChildren(transes, mBone);
for(ObjPtrList<Hmx::Object>::iterator it = merger->mLoadedObjects.begin(); it != merger->mLoadedObjects.end(); ++it){
RndMesh* curMesh = dynamic_cast<RndMesh*>(*it);
if(curMesh){
if(std::find(meshes.begin(), meshes.end(), curMesh) == meshes.end()){
unsigned int mask = BoneMask(transes, curMesh);
if(mask != 0){
meshes.push_back(curMesh);
DeformMesh(curMesh, mask, cb);
}
}
}
}
}
}
}

void CharCuff::DeformMesh(RndMesh* mesh, int, SyncMeshCB*){
MILO_ASSERT(mesh->NumBones(), 0xF5);
Vector4_16_01 v;
v.GetW(); v.GetX(); v.GetY(); v.GetZ();
}

SAVE_OBJ(CharCuff, 0x1A2)

DECOMP_FORCEACTIVE(CharCuff, "ObjPtr_p.h", "c.Owner()", "", "f.Owner()")

BEGIN_LOADS(CharCuff)
LOAD_REVS(bs)
ASSERT_REVS(8, 0)
Expand Down
Loading

0 comments on commit 31fddf5

Please sign in to comment.