Cockpit: authentic eyepoint + canopy lattice render (task #55)
The first-person cockpit now shows by default and matches gameplay footage (verified on the Madcat). Two decomp-verified reconstructions: EYEPOINT (FUN_004579a8 + caller part_014.c:5525, FUN_004c22c4): - eye offset = siteeyepoint GetBaseOffset (not GetSegmentToEntity, not the upright hack), parented on the PARENT segment DCS (btl4vid.cpp) - live view = affine INVERSE of the eye world matrix (L4VIDRND Execute) -- replaces the hand-rolled LookAtRH whose +Z-forward/+Y-up row guess aimed some mechs into the canopy; combine order fixed to baseOffset * R - chase camera basis + aim boresight re-expressed for the inverse convention (row2 = back); boresight now derives from the view matrix (the stale rows aimed the pick ray at the sky = no target, no discharge) CANOPY (*_COP.BGF, dpl_Punchize geogroups): - every shell is an open strut lattice (38-59% boundary edges, all 12 mechs); rendered single-sided with per-face INWARD winding (l/r torso patches are mirrored, so no global winding works) the struts are the dark frame and the openings show the world - frame colour = the 'softer' ramp near its dark end (texture-less unlit ramp; BLXSKIN.BMF has no texture -- the old "punch texels" theory was wrong) - scoped by filename (meshIsCop); wrong drop-punch + view-cut paths removed - BT_FORCE_MODEL=<name> forces the player mech for per-mech bring-up KB: new context/cockpit-view.md topic; punch split corrected in bgf-format; gotchas 14 (LookAt axis guess) + 15 (per-patch edge namespaces); env gates + eye/punch addresses in decomp-reference. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
7b0b4f64ab
commit
abaa145b6f
@@ -401,25 +401,18 @@ HierarchicalDrawComponent*
|
||||
EulerAngles *eye_rot =
|
||||
(EulerAngles *)entity->GetAttributePointer("EyepointRotation"); // @0051d29d
|
||||
//
|
||||
// Mount the eye at the eyepoint's REST position but with a clean
|
||||
// UPRIGHT forward basis, parented on the tree ROOT: riding the
|
||||
// live joint chain fed the camera the site's authored tilt + the
|
||||
// torso pose (a permanently canted horizon). The authentic pitch
|
||||
// /yaw came from the gyro-driven eye-joint chain (deferred); until
|
||||
// that lands, the cockpit view = eyepoint position + mech yaw.
|
||||
// AUTHENTIC eye (decomp FUN_004579a8 @part_007.c:9274-9325; caller part_014.c:5525-5566):
|
||||
// the eye offset matrix is the siteeyepoint segment's LOCAL rest transform (GetBaseOffset,
|
||||
// segment+0x74 -- already in offset_matrix above), and the eye is parented on its PARENT
|
||||
// segment's draw component (parent_DCS) -- NOT the root, NOT the full GetSegmentToEntity,
|
||||
// NOT an upright hack. World orientation + all live motion (torso twist, gait) come from
|
||||
// the parent-chain composition, exactly as the decomp's dpl_AddDCSToDCS hierarchy does;
|
||||
// EyepointRotation is combined in Execute as baseOffset * R, and VIEW = inverse(eyeWorld)
|
||||
// (FUN_004c22c4 @part_013.c:11788) -- so the look/up axes fall out of the eye's own basis
|
||||
// with no per-mech forward-axis assumption.
|
||||
//
|
||||
AffineMatrix restToEntity = segment->GetSegmentToEntity();
|
||||
Point3D eyePos;
|
||||
eyePos = restToEntity; // rest translation (W row)
|
||||
LinearMatrix eyeBasis(True);
|
||||
eyeBasis(0,0) = -1.0f; eyeBasis(0,1) = 0.0f; eyeBasis(0,2) = 0.0f; // X row
|
||||
eyeBasis(1,0) = 0.0f; eyeBasis(1,1) = 1.0f; eyeBasis(1,2) = 0.0f; // Y row (up)
|
||||
eyeBasis(2,0) = 0.0f; eyeBasis(2,1) = 0.0f; eyeBasis(2,2) = -1.0f; // Z row (look = mech forward)
|
||||
eyeBasis(3,0) = (Scalar)eyePos.x;
|
||||
eyeBasis(3,1) = (Scalar)eyePos.y;
|
||||
eyeBasis(3,2) = (Scalar)eyePos.z;
|
||||
mEyeCockpit = new DPLEyeRenderable(
|
||||
entity, eyeBasis, this_root, eye_rot);
|
||||
entity, offset_matrix, parent_DCS, eye_rot);
|
||||
if (type == insideEntity) // true inside build: it IS the camera
|
||||
mCamera = mEyeCockpit;
|
||||
dbg_eye = 1;
|
||||
@@ -633,10 +626,16 @@ HierarchicalDrawComponent*
|
||||
// recomputed up (local +Y) = forward x right
|
||||
float yx = zy*xz - zz*xy, yy = zz*xx - zx*xz, yz = zx*xy - zy*xx;
|
||||
|
||||
// CAMERA-BASIS CONVENTION (task #56 follow-through): the view is now the
|
||||
// authentic VIEW = inverse(eyeWorld) (DPLEyeRenderable::Execute), under
|
||||
// which the camera looks along -Z of its own basis -- so the basis rows
|
||||
// are right/up/BACK, not right/up/look. This chase matrix was authored
|
||||
// for the old LookAt (row2 = look); convert by a 180-degree turn about
|
||||
// local Y (negate the X and Z rows -- determinant stays +1).
|
||||
LinearMatrix debugOffset; // identity
|
||||
debugOffset(0,0) = xx; debugOffset(0,1) = xy; debugOffset(0,2) = xz; // X row
|
||||
debugOffset(0,0) = -xx; debugOffset(0,1) = -xy; debugOffset(0,2) = -xz; // X row (right, flipped)
|
||||
debugOffset(1,0) = yx; debugOffset(1,1) = yy; debugOffset(1,2) = yz; // Y row (up)
|
||||
debugOffset(2,0) = zx; debugOffset(2,1) = zy; debugOffset(2,2) = zz; // Z row (look)
|
||||
debugOffset(2,0) = -zx; debugOffset(2,1) = -zy; debugOffset(2,2) = -zz; // Z row (BACK = -look)
|
||||
debugOffset(3,0) = camPx; debugOffset(3,1) = camPy; debugOffset(3,2) = camPz; // W row (pos)
|
||||
|
||||
mEyeChase = new DPLEyeRenderable(entity, debugOffset, this_root, NULL);
|
||||
@@ -2037,6 +2036,7 @@ BTL4VideoRenderer::BTL4VideoRenderer(
|
||||
mViewInside = 0;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// ApplyViewSkeleton -- select + load each body segment's displayed mesh for the
|
||||
// given view (inside = SkeletonType_A / outside = the mech's own skeletonType),
|
||||
@@ -2083,11 +2083,13 @@ int
|
||||
gstate = viewpoint->damageZones[zone_index]->GetGraphicState();
|
||||
CString *nm = segment->GetVideoObjectName(
|
||||
(EntitySegment::SkeletonType)render_tree.viewSkeleton, gstate);
|
||||
// The cockpit interior shell (blx_cop -- the canopy frame around the
|
||||
// eyepoint) currently renders as a black enclosure; keep it hidden until
|
||||
// its interior rendering is sorted (BT_INSIDE_COCKPIT=1 shows it).
|
||||
// The cockpit canopy shell (*_cop -- the frame around the eyepoint) SHOWS by
|
||||
// default: with the authentic eye (baseOffset + parent-segment DCS + inverse
|
||||
// view) and the loader's single-sided dark-ramp treatment it renders as the
|
||||
// dark frame with the world through the openings (task #55, verified vs
|
||||
// gameplay footage). BT_HIDE_COCKPIT=1 hides it (diagnostic).
|
||||
if (inside && nm != NULL && strstr((const char *)*nm, "_cop") != NULL
|
||||
&& !getenv("BT_INSIDE_COCKPIT"))
|
||||
&& getenv("BT_HIDE_COCKPIT"))
|
||||
nm = NULL;
|
||||
d3d_OBJECT *obj = NULL;
|
||||
if (nm != NULL)
|
||||
|
||||
Reference in New Issue
Block a user