diff --git a/MUNGA_L4/L4VIDEO.cpp b/MUNGA_L4/L4VIDEO.cpp index 6e6d6eb..a1c7c85 100644 --- a/MUNGA_L4/L4VIDEO.cpp +++ b/MUNGA_L4/L4VIDEO.cpp @@ -7047,6 +7047,63 @@ void mPresentationCamera = False; } +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Give the pilot a vehicle to look at. Their own is built insideEntity - a +// cockpit and no hull - so on the podium they would be the one empty spot. +// Drop those renderables and build the entity again with Disconnected_Eye +// set, which is what makes NotifyOfNewInterestingEntity choose outsideEntity. +// +// Tearing renderables down and rebuilding is the same path the interest +// manager takes every time something drops out of range mid-race, so it is +// well travelled. The eye renderable goes with them, which is fine: the +// presentation camera supplies the view once the podium is up. +// +void + DPLRenderer::ShowViewpointFromOutside() +{ + Check(this); + + Entity *viewpoint = GetLinkedEntity(); + if (viewpoint == NULL) + { + DEBUG_STREAM << "WinnersCircle: no viewpoint entity to turn around\n" + << std::flush; + return; + } + + // + // Add the exterior alongside what is already there rather than tearing + // the entity down and rebuilding it. The teardown path is safe for + // scenery going out of range, but not for the viewpoint entity: it is + // never uninteresting, the eye renderable goes with it, and doing it + // mid-mission stops the scene rendering altogether. + // + // This is what NotifyOfNewInterestingEntity does, minus the teardown + // and with the view type forced. + // + Check(application); + ResourceFile *resource_file = application->GetResourceFile(); + Check(resource_file); + ResourceDescription *video_resource = resource_file->SearchList( + viewpoint->GetResourceID(), + ResourceDescription::VideoModelResourceType); + + if (video_resource == NULL) + { + DEBUG_STREAM << "WinnersCircle: own vehicle has no exterior model\n" + << std::flush; + return; + } + + video_resource->Lock(); + MakeEntityRenderables(viewpoint, video_resource, outsideEntity); + video_resource->Unlock(); + + DEBUG_STREAM << "WinnersCircle: own vehicle given an exterior\n" + << std::flush; +} + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Come up out of the black. SetFogStyle(winnersCircleFogStyle) has already diff --git a/MUNGA_L4/L4VIDEO.h b/MUNGA_L4/L4VIDEO.h index 5b2e3b2..6d0fa8d 100644 --- a/MUNGA_L4/L4VIDEO.h +++ b/MUNGA_L4/L4VIDEO.h @@ -343,6 +343,16 @@ public: //------------------------------------------------------------------ void StartPresentationFadeIn(Scalar seconds); + //------------------------------------------------------------------ + // Rebuild the viewpoint entity - the pilot's own vehicle - as an + // exterior. It is normally built insideEntity, which is a cockpit + // and no hull, so from any camera that is not in it you see nothing + // where your own vehicle should be. Disconnected_Eye is the engine's + // own switch for this: "so higher level renderers can fix the eye in + // one spot and watch the viewpoint entity drive around." + //------------------------------------------------------------------ + void ShowViewpointFromOutside(); + unsigned int* MakeBitSliceStorage(); void SortAndReloadNameBitmaps(); diff --git a/RP_L4/RPL4APP.cpp b/RP_L4/RPL4APP.cpp index c43b5ef..d70c501 100644 --- a/RP_L4/RPL4APP.cpp +++ b/RP_L4/RPL4APP.cpp @@ -215,6 +215,15 @@ void return; } + // + //--------------------------------------------------------------------- + // Your own vehicle is built as a cockpit with no hull, so from any + // camera outside it there is nothing where you should be - on the stand + // you would be the one empty spot. Turn it inside out before the shot. + //--------------------------------------------------------------------- + // + dpl_renderer->ShowViewpointFromOutside(); + // //--------------------------------------------------------------------- // The name plates are drawn per rank slot, so they have to be re-sorted