Confirm 2 functions in Source/Contents/Models/ModelActorBounds.cpp
Batch #11481 by kyoshi: 0 byte-identical, 2 confirmed by peer review. - fn_17512 C3dActorV1::UpdateBounds: logic confirmed by peer review (already on main) - fn_17513 C3dActorV2::UpdateBounds: logic confirmed by peer review (already on main) Peer-reviewed-by: Yommy, dori, cremane Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes).
This commit is contained in:
parent
9ff7206468
commit
99698b5fd7
1 changed files with 75 additions and 32 deletions
|
|
@ -17,10 +17,45 @@ namespace {
|
|||
|
||||
// INLINED
|
||||
float InverseLength(float squared) {
|
||||
const float root = SquareRoot(squared);
|
||||
return static_cast<float>(1.0 / static_cast<double>(root));
|
||||
return 1.0f / SquareRoot(squared);
|
||||
}
|
||||
|
||||
// INLINED
|
||||
__forceinline void TransformCorner(float* corner, float x, float y, float z, const float* matrix) {
|
||||
corner[0] = ((x * matrix[0] + y * matrix[3]) + z * matrix[6]) + matrix[9];
|
||||
corner[1] = ((x * matrix[1] + y * matrix[4]) + z * matrix[7]) + matrix[10];
|
||||
corner[2] = ((x * matrix[2] + y * matrix[5]) + z * matrix[8]) + matrix[11];
|
||||
}
|
||||
|
||||
// INLINED
|
||||
__forceinline void SetAxis(float* direction, const float* row) {
|
||||
direction[0] = row[0];
|
||||
direction[1] = row[1];
|
||||
direction[2] = row[2];
|
||||
const float inverse = InverseLength((direction[0] * direction[0] + direction[1] * direction[1]) + direction[2] * direction[2]);
|
||||
direction[0] = inverse * direction[0];
|
||||
direction[1] = inverse * direction[1];
|
||||
direction[2] = inverse * direction[2];
|
||||
}
|
||||
|
||||
struct BoundsCorner {
|
||||
float values[3];
|
||||
|
||||
// INLINED
|
||||
BoundsCorner() {
|
||||
values[0] = 0.0f;
|
||||
values[1] = 0.0f;
|
||||
values[2] = 0.0f;
|
||||
}
|
||||
|
||||
// INLINED
|
||||
__forceinline void Set(float x, float y, float z) {
|
||||
values[0] = x;
|
||||
values[1] = y;
|
||||
values[2] = z;
|
||||
}
|
||||
};
|
||||
|
||||
// INLINED
|
||||
float Coordinate(const float* point, const float* matrix, unsigned axis) {
|
||||
return ((point[0] * matrix[axis] + point[1] * matrix[axis + 3]) + point[2] * matrix[axis + 6]) + matrix[axis + 9];
|
||||
|
|
@ -31,24 +66,37 @@ namespace {
|
|||
__forceinline void C3dActor::FinishBounds(const float* bounds, bool modern) {
|
||||
for (unsigned axis = 0; axis < 3; ++axis) {
|
||||
this->minimum[axis] = 100000;
|
||||
}
|
||||
|
||||
for (unsigned axis = 0; axis < 3; ++axis) {
|
||||
this->maximum[axis] = -100000;
|
||||
}
|
||||
|
||||
BoundsCorner points[8];
|
||||
points[0].Set(bounds[0], bounds[1], bounds[2]);
|
||||
points[1].Set(bounds[3], bounds[1], bounds[2]);
|
||||
points[2].Set(bounds[0], bounds[4], bounds[2]);
|
||||
points[3].Set(bounds[3], bounds[4], bounds[2]);
|
||||
points[4].Set(bounds[0], bounds[1], bounds[5]);
|
||||
points[5].Set(bounds[3], bounds[1], bounds[5]);
|
||||
points[6].Set(bounds[0], bounds[4], bounds[5]);
|
||||
points[7].Set(bounds[3], bounds[4], bounds[5]);
|
||||
|
||||
for (unsigned corner = 0; corner < 8; ++corner) {
|
||||
const float point[3] = {
|
||||
bounds[(corner & 1u) ? 3 : 0], bounds[(corner == 2 || corner == 3 || corner == 6 || corner == 7) ? 4 : 1], bounds[corner >= 4 ? 5 : 2]
|
||||
};
|
||||
float* stored = this->corners[corner];
|
||||
stored[0] = Coordinate(points[corner].values, this->transform.values, 0);
|
||||
stored[1] = Coordinate(points[corner].values, this->transform.values, 1);
|
||||
stored[2] = Coordinate(points[corner].values, this->transform.values, 2);
|
||||
|
||||
for (unsigned axis = 0; axis < 3; ++axis) {
|
||||
const float value = Coordinate(point, this->transform.values, axis);
|
||||
this->corners[corner][axis] = value;
|
||||
|
||||
if (this->minimum[axis] > value) {
|
||||
this->minimum[axis] = value;
|
||||
if (this->minimum[axis] > stored[axis]) {
|
||||
this->minimum[axis] = stored[axis];
|
||||
}
|
||||
}
|
||||
|
||||
if (value > this->maximum[axis]) {
|
||||
this->maximum[axis] = value;
|
||||
for (unsigned axis = 0; axis < 3; ++axis) {
|
||||
if (stored[axis] > this->maximum[axis]) {
|
||||
this->maximum[axis] = stored[axis];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -57,6 +105,9 @@ __forceinline void C3dActor::FinishBounds(const float* bounds, bool modern) {
|
|||
const float low = Coordinate(bounds, this->transform.values, axis);
|
||||
const float high = Coordinate(bounds + 3, this->transform.values, axis);
|
||||
this->oriented.center[axis] = (modern || axis == 2 ? high + low : low + high) * 0.5f;
|
||||
}
|
||||
|
||||
for (unsigned axis = 0; axis < 3; ++axis) {
|
||||
this->oriented.halfSize[axis] = Absolute((bounds[axis + 3] - bounds[axis]) * this->scale[axis]) * 0.5f;
|
||||
}
|
||||
|
||||
|
|
@ -66,16 +117,9 @@ __forceinline void C3dActor::FinishBounds(const float* bounds, bool modern) {
|
|||
axes.AppendXRotation(Radians(this->rotation[0]));
|
||||
axes.AppendZRotation(Radians(this->rotation[2]));
|
||||
|
||||
for (unsigned axis = 0; axis < 3; ++axis) {
|
||||
float* direction = this->oriented.axes[axis];
|
||||
direction[0] = axes.values[axis * 3];
|
||||
direction[1] = axes.values[axis * 3 + 1];
|
||||
direction[2] = axes.values[axis * 3 + 2];
|
||||
const float inverse = InverseLength((direction[0] * direction[0] + direction[1] * direction[1]) + direction[2] * direction[2]);
|
||||
direction[0] = inverse * direction[0];
|
||||
direction[1] = inverse * direction[1];
|
||||
direction[2] = inverse * direction[2];
|
||||
}
|
||||
SetAxis(this->oriented.axes[0], axes.values);
|
||||
SetAxis(this->oriented.axes[1], axes.values + 3);
|
||||
SetAxis(this->oriented.axes[2], axes.values + 6);
|
||||
|
||||
for (ModelVolume* volume : this->volumes) {
|
||||
volume->transform.MakeXRotation(Radians(volume->rotation[0]));
|
||||
|
|
@ -86,16 +130,15 @@ __forceinline void C3dActor::FinishBounds(const float* bounds, bool modern) {
|
|||
matrix combined;
|
||||
combined.Compose(volume->transform, this->transform);
|
||||
|
||||
for (unsigned corner = 0; corner < 8; ++corner) {
|
||||
const float point[3] = {
|
||||
(corner == 1 || corner == 2 || corner == 5 || corner == 6) ? volume->size[0] : -volume->size[0],
|
||||
(corner == 2 || corner == 3 || corner == 6 || corner == 7) ? volume->size[1] : -volume->size[1], corner >= 4 ? volume->size[2] : -volume->size[2]
|
||||
};
|
||||
|
||||
for (unsigned axis = 0; axis < 3; ++axis) {
|
||||
volume->corners[corner][axis] = Coordinate(point, combined.values, axis);
|
||||
}
|
||||
}
|
||||
const float* size = volume->size;
|
||||
TransformCorner(volume->corners[0], -size[0], -size[1], -size[2], combined.values);
|
||||
TransformCorner(volume->corners[1], size[0], -size[1], -size[2], combined.values);
|
||||
TransformCorner(volume->corners[2], size[0], size[1], -size[2], combined.values);
|
||||
TransformCorner(volume->corners[3], -size[0], size[1], -size[2], combined.values);
|
||||
TransformCorner(volume->corners[4], -size[0], -size[1], size[2], combined.values);
|
||||
TransformCorner(volume->corners[5], size[0], -size[1], size[2], combined.values);
|
||||
TransformCorner(volume->corners[6], size[0], size[1], size[2], combined.values);
|
||||
TransformCorner(volume->corners[7], -size[0], size[1], size[2], combined.values);
|
||||
}
|
||||
|
||||
this->dirty = 1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue