Reconstruct readable C++ and organize cohesive source subsystems
Administrative source import: native x86 compilation passed for 423 authored units. Source placement and submission states are migrated separately; this commit does not imply peer acceptance.
Previous head: 35d2a8cb36
Payload SHA256: 592f016d2730c5593bb653aa054c1e5f76a6df72c8f5a09e66f74876e2e33dee
This commit is contained in:
parent
35d2a8cb36
commit
a47d20f8be
890 changed files with 11796 additions and 16664 deletions
275
Source/Contents/Models/ModelActor.cpp
Normal file
275
Source/Contents/Models/ModelActor.cpp
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
#include "Contents/Models/ModelActor.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <windows.h>
|
||||
|
||||
namespace {
|
||||
float Radians(float degrees) {
|
||||
return (degrees / 180.0f) * 3.141592f;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AB59A0
|
||||
C3dActor::C3dActor()
|
||||
: position{}, rotation{}, scale{1, 1, 1}, offset{}, dirty(1), oriented{}, corners{}, minimum{}, maximum{}, enabled(1), renderFrame(0), occlusionEnabled(0),
|
||||
occluded(0), alpha(255), commandMode(0), color(0xFFFFFFFFu), playback(2), speed(0), shade(0) {
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AB6420
|
||||
C3dActor::~C3dActor() {
|
||||
for (ModelVolume*& volume : this->volumes) {
|
||||
delete volume;
|
||||
volume = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AB5BB0
|
||||
C3dActorV1::C3dActorV1() : root(nullptr), frame(0), animationLength(0), lastTick(0) {
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AB69C0
|
||||
// FUNCTION: fn_17473
|
||||
C3dActorV1::~C3dActorV1() {
|
||||
delete this->root;
|
||||
this->root = nullptr;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AB5C30
|
||||
C3dActorV2::C3dActorV2() : framesPerSecond(0), duration(0), startTick(GetTickCount()) {
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AB6A50
|
||||
// FUNCTION: fn_17474
|
||||
C3dActorV2::~C3dActorV2() {
|
||||
for (C3dNodeV2*& root : this->roots) {
|
||||
delete root;
|
||||
root = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AB6E90
|
||||
// FUNCTION: fn_17479
|
||||
void C3dActorV1::Assign(const C3dModelRes& resource) {
|
||||
this->shade = resource.shade;
|
||||
this->animationLength = static_cast<const C3dModelResV1&>(resource).animationLength;
|
||||
this->root = new C3dNodeV1;
|
||||
this->root->model = this;
|
||||
this->root->Initialize(*resource.nodes.front());
|
||||
this->Animate(0);
|
||||
this->UpdateBounds();
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AB6F50
|
||||
// FUNCTION: fn_17480
|
||||
void C3dActorV2::Assign(const C3dModelRes& resource) {
|
||||
const auto& modern = static_cast<const C3dModelResV2&>(resource);
|
||||
this->shade = resource.shade;
|
||||
this->framesPerSecond = modern.framesPerSecond;
|
||||
const float inverse = 1.0f / modern.framesPerSecond;
|
||||
const int milliseconds = 1000 * modern.animationLength;
|
||||
this->duration = static_cast<float>(milliseconds) * inverse;
|
||||
|
||||
for (const std::string& name : resource.rootNames) {
|
||||
auto* root = new C3dNodeV2;
|
||||
root->model = this;
|
||||
root->Initialize(*resource.FindNode(name.c_str()));
|
||||
this->roots.push_back(root);
|
||||
}
|
||||
|
||||
this->Animate(0);
|
||||
this->UpdateBounds();
|
||||
}
|
||||
|
||||
// OFFSET: 0x00ABB890
|
||||
// FUNCTION: fn_17516
|
||||
void C3dActor::UpdateTransform() {
|
||||
this->transform.SetTranslation(this->offset[0], this->offset[1], this->offset[2]);
|
||||
this->transform.Scale(this->scale[0], this->scale[1], this->scale[2]);
|
||||
this->transform.RotateY(Radians(this->rotation[1]));
|
||||
this->transform.RotateX(Radians(this->rotation[0]));
|
||||
this->transform.RotateZ(Radians(this->rotation[2]));
|
||||
this->transform.Translate(this->position);
|
||||
this->inverseTransform.Inverse(this->transform);
|
||||
this->dirty = 0;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00ABB970
|
||||
// FUNCTION: fn_17517
|
||||
void C3dActorV2::UpdateTransform() {
|
||||
this->transform.Identity();
|
||||
this->transform.values[4] = -1.0f;
|
||||
this->transform.Scale(this->scale[0], this->scale[1], this->scale[2]);
|
||||
this->transform.RotateY(Radians(this->rotation[1]));
|
||||
this->transform.RotateX(Radians(this->rotation[0]));
|
||||
this->transform.RotateZ(Radians(this->rotation[2]));
|
||||
this->transform.Translate(this->position);
|
||||
this->inverseTransform.Inverse(this->transform);
|
||||
this->dirty = 0;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00ABBA60
|
||||
// FUNCTION: fn_17519
|
||||
void C3dActorV1::Prepare(ModelLightingContext& context) {
|
||||
if (this->dirty == 1) {
|
||||
this->UpdateTransform();
|
||||
}
|
||||
|
||||
const float* previousPosition = context.position;
|
||||
const std::uint32_t* previousColor = context.color;
|
||||
const int* previousShade = context.shade;
|
||||
|
||||
context.position = this->position;
|
||||
context.color = &this->color;
|
||||
context.shade = &this->shade;
|
||||
this->root->Prepare(this->transform.values, context);
|
||||
context.position = previousPosition;
|
||||
context.color = previousColor;
|
||||
context.shade = previousShade;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00ABBAA0
|
||||
// FUNCTION: fn_17520
|
||||
void C3dActorV2::Prepare(ModelLightingContext& context) {
|
||||
if (this->dirty == 1) {
|
||||
this->UpdateTransform();
|
||||
}
|
||||
|
||||
const float* previousPosition = context.position;
|
||||
const std::uint32_t* previousColor = context.color;
|
||||
const int* previousShade = context.shade;
|
||||
|
||||
context.position = this->position;
|
||||
context.color = &this->color;
|
||||
context.shade = &this->shade;
|
||||
|
||||
for (C3dNodeV2* root : this->roots) {
|
||||
root->Prepare(this->transform.values, context);
|
||||
}
|
||||
|
||||
context.position = previousPosition;
|
||||
context.color = previousColor;
|
||||
context.shade = previousShade;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AB9070
|
||||
// FUNCTION: fn_17504
|
||||
void C3dActorV1::Animate(double frame) {
|
||||
this->root->Animate(frame);
|
||||
this->dirty = 1;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AB90A0
|
||||
// FUNCTION: fn_17505
|
||||
void C3dActorV2::Animate(double frame) {
|
||||
const float selected = static_cast<float>(static_cast<double>(this->framesPerSecond) * frame / 1000.0);
|
||||
|
||||
for (C3dNodeV2* root : this->roots) {
|
||||
root->Animate(static_cast<double>(selected));
|
||||
}
|
||||
|
||||
this->dirty = 1;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AB9010
|
||||
// FUNCTION: fn_17501
|
||||
void C3dActor::SetSpeed(float speed) {
|
||||
this->speed = speed;
|
||||
|
||||
if (speed != 0.0f) {
|
||||
this->speed = speed / 3.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AB9040
|
||||
// FUNCTION: fn_17502
|
||||
void C3dActorV2::SetSpeed(float speed) {
|
||||
this->speed = speed;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AB7860
|
||||
// FUNCTION: fn_17489
|
||||
C3dNode* C3dActorV1::Find(const char* name) {
|
||||
return this->root->Find(name);
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AB7870
|
||||
// FUNCTION: fn_17490
|
||||
C3dNode* C3dActorV2::Find(const char* name) {
|
||||
for (C3dNodeV2* root : this->roots) {
|
||||
if (C3dNode* found = root->Find(name)) {
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AB94D0
|
||||
// FUNCTION: fn_17510
|
||||
void C3dActor::CopyVolumes(const std::list<ModelVolume*>& source) {
|
||||
for (const ModelVolume* volume : source) {
|
||||
this->volumes.push_back(new ModelVolume(*volume));
|
||||
}
|
||||
}
|
||||
|
||||
bool C3dActor::Reversed() const {
|
||||
bool result = this->scale[0] >= 0.0f;
|
||||
|
||||
if (this->scale[1] >= 0.0f) {
|
||||
result = this->scale[0] < 0.0f;
|
||||
}
|
||||
|
||||
return this->scale[2] < 0.0f ? !result : result;
|
||||
}
|
||||
|
||||
void C3dActor::Fade() {
|
||||
if (this->occluded == 1) {
|
||||
if (this->alpha > 90) {
|
||||
this->alpha = static_cast<unsigned char>(this->alpha - 5);
|
||||
} else {
|
||||
this->occluded = 0;
|
||||
}
|
||||
} else if (this->alpha != 255) {
|
||||
this->alpha = static_cast<unsigned char>(this->alpha + 5);
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AB7B50
|
||||
// FUNCTION: fn_17496
|
||||
void C3dActorV1::Draw(const float* matrix, bool clip, ModelRenderContext& context) {
|
||||
if (this->dirty == 1) {
|
||||
this->UpdateTransform();
|
||||
}
|
||||
|
||||
AffineMatrix camera;
|
||||
std::memcpy(camera.values, matrix, sizeof(camera.values));
|
||||
AffineMatrix combined;
|
||||
combined.Compose(this->transform, camera);
|
||||
this->root->Draw(combined.values, this->Reversed(), clip, this->commandMode, context);
|
||||
|
||||
if (this->occlusionEnabled == 1) {
|
||||
this->Fade();
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x00AB7C40
|
||||
// FUNCTION: fn_17497
|
||||
void C3dActorV2::Draw(const float* matrix, bool clip, ModelRenderContext& context) {
|
||||
if (this->dirty == 1) {
|
||||
this->UpdateTransform();
|
||||
}
|
||||
|
||||
AffineMatrix camera;
|
||||
std::memcpy(camera.values, matrix, sizeof(camera.values));
|
||||
AffineMatrix combined;
|
||||
combined.Compose(this->transform, camera);
|
||||
const bool reversed = this->Reversed();
|
||||
|
||||
for (C3dNodeV2* root : this->roots) {
|
||||
root->Draw(combined.values, reversed, clip, this->commandMode, context);
|
||||
|
||||
if (this->occlusionEnabled == 1) {
|
||||
this->Fade();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue