// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // * Neither the name of NVIDIA CORPORATION nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. #ifndef PHYSX_SAMPLE_APPLICATION_H #define PHYSX_SAMPLE_APPLICATION_H #include "SamplePreprocessor.h" #include "SampleApplication.h" #include "SampleCamera.h" #include "SampleCameraController.h" #include "SampleAllocator.h" #include "PxFiltering.h" #include "RawLoader.h" #include "RendererMeshContext.h" #include "PxTkFPS.h" #include "PxVisualizationParameter.h" #include "PxTkRandom.h" #include #include #include "PsHashMap.h" #include "PsUtilities.h" #include "SampleArray.h" #if PX_WINDOWS #include "task/PxTask.h" #endif #define SAMPLE_MEDIA_PATH "samples/media/" #define SAMPLE_OUTPUT_PATH "samples/media/user/" namespace physx { class PxDefaultCpuDispatcher; class PxPhysics; class PxCooking; class PxScene; class PxGeometry; class PxMaterial; class PxRigidActor; }; class RenderPhysX3Debug; class RenderBaseActor; class RenderMaterial; class RenderMeshActor; class RenderTexture; class Stepper; class Console; class PhysXSampleApplication; class PhysXSample; class InputEventBuffer; namespace Test { class TestGroup; } class PhysXSampleCreator { public: virtual ~PhysXSampleCreator() {} virtual PhysXSample* operator()(PhysXSampleApplication& app) const = 0; }; typedef PhysXSampleCreator *SampleCreator; typedef PhysXSample* (*FunctionCreator)(PhysXSampleApplication& app); // typedef PhysXSample* (*SampleCreator)(PhysXSampleApplication& app); struct SampleSetup { SampleSetup() : mName (NULL), mWidth (0), mHeight (0), mFullscreen (false) { } const char* mName; PxU32 mWidth; PxU32 mHeight; bool mFullscreen; }; // Default materials created by PhysXSampleApplication enum MaterialIndex { MATERIAL_GREY, MATERIAL_RED, MATERIAL_GREEN, MATERIAL_BLUE, MATERIAL_YELLOW, MATERIAL_FLAT, MATERIAL_COUNT, }; template void releaseAll(Container& container) { for (PxU32 i = 0; i < container.size(); ++i) container[i]->release(); container.clear(); } class PhysXSampleApplication : public SampleFramework::SampleApplication, public SampleAllocateable, public Ps::ThreadT { public: using SampleAllocateable::operator new; using SampleAllocateable::operator delete; private: friend class PhysXSample; struct PvdParameters { char ip[256]; PxU32 port; PxU32 timeout; bool useFullPvdConnection; PvdParameters() : port(5425) , timeout(10) , useFullPvdConnection(true) { Ps::strlcpy(ip, 256, "127.0.0.1"); } }; struct MenuKey { enum Enum { NONE, ESCAPE, SELECT, NAVI_UP, NAVI_DOWN, NAVI_LEFT, NAVI_RIGHT }; }; // menu events struct MenuType { enum Enum { NONE, HELP, SETTINGS, VISUALIZATIONS, TESTS }; }; struct MenuTogglableItem { MenuTogglableItem(PxU32 c, const char* n) : toggleCommand(c), toggleState(false), name(n) {} PxU32 toggleCommand; bool toggleState; const char* name; }; public: PhysXSampleApplication(const SampleFramework::SampleCommandLine& cmdline); virtual ~PhysXSampleApplication(); /////////////////////////////////////////////////////////////////////////////// // PsThread interface virtual void execute(); /////////////////////////////////////////////////////////////////////////////// // Implements SampleApplication/RendererWindow virtual void onInit(); virtual void onShutdown(); virtual float tweakElapsedTime(float dtime); virtual void onTickPreRender(float dtime); virtual void onRender(); virtual void onTickPostRender(float dtime); void onKeyDownEx(SampleFramework::SampleUserInput::KeyCode keyCode, PxU32 wParam); void onAnalogInputEvent(const SampleFramework::InputEvent& , float val); void onDigitalInputEvent(const SampleFramework::InputEvent& , bool val); void onPointerInputEvent(const SampleFramework::InputEvent&, PxU32 x, PxU32 y, PxReal dx, PxReal dy, bool val); virtual void onResize(PxU32 width, PxU32 height); void baseTickPreRender(float dtime); void baseTickPostRender(float dtime); void baseResize(PxU32 width, PxU32 height); /////////////////////////////////////////////////////////////////////////////// void customizeSample(SampleSetup&); // void onSubstep(float dtime); /////////////////////////////////////////////////////////////////////////////// void applyDefaultVisualizationSettings(); void saveCameraState(); void restoreCameraState(); // Camera functions PX_FORCE_INLINE void setDefaultCameraController() { mCurrentCameraController = &mCameraController; mCameraController = DefaultCameraController();} PX_FORCE_INLINE void resetDefaultCameraController() { mCameraController = DefaultCameraController(); } PX_FORCE_INLINE void setCameraController(CameraController* c) { mCurrentCameraController = c; } PX_FORCE_INLINE PxReal getTextAlpha1() const { return mTextAlphaHelp; } PX_FORCE_INLINE PxReal getTextAlpha2() const { return mTextAlphaDesc; } PX_FORCE_INLINE bool isPaused() const { return mPause; } PX_FORCE_INLINE Camera& getCamera() { return mCamera; } PX_FORCE_INLINE RenderPhysX3Debug* getDebugRenderer() const { return mDebugRenderer; } PX_FORCE_INLINE Ps::MutexT& getInputMutex() { return mInputMutex; } bool isConsoleActive() const; void showCursor(bool show); void setMouseCursorHiding(bool hide); void setMouseCursorRecentering(bool recenter); void handleMouseVisualization(); void updateEngine(); void setPvdParams(const SampleFramework::SampleCommandLine& cmdLine); PX_FORCE_INLINE void registerLight(SampleRenderer::RendererLight* light) { mLights.push_back(light); } void collectInputEvents(std::vector& inputEvents); const char* inputInfoMsg(const char* firstPart,const char* secondPart, PxI32 inputEventId1, PxI32 inputEventId2); const char* inputInfoMsg_Aor_BandC(const char* firstPart,const char* secondPart, PxI32 inputEventIdA, PxI32 inputEventIdB, PxI32 inputEventIdC); const char* inputMoveInfoMsg(const char* firstPart,const char* secondPart, PxI32 inputEventId1, PxI32 inputEventId2,PxI32 inputEventId3,PxI32 inputEventId4); void requestToClose() { mIsCloseRequested = true; } bool isCloseRequested() { return mIsCloseRequested; } private: PxReal mTextAlphaHelp; PxReal mTextAlphaDesc; MenuType::Enum mMenuType; std::vector mMenuVisualizations; size_t mMenuVisualizationsIndexSelected; void setMenuVisualizations(MenuTogglableItem& togglableItem); char m_Msg[512]; PxTransform mSavedView; bool mIsCloseRequested; protected: Console* mConsole; Camera mCamera; DefaultCameraController mCameraController; CameraController* mCurrentCameraController; std::vector mLights; RenderMaterial* mManagedMaterials[MATERIAL_COUNT]; RenderPhysX3Debug* mDebugRenderer; bool mPause; bool mOneFrameUpdate; bool mSwitchSample; bool mShowHelp; bool mShowDescription; bool mShowExtendedHelp; volatile bool mHideMouseCursor; InputEventBuffer* mInputEventBuffer; Ps::MutexT mInputMutex; bool mDrawScreenQuad; SampleRenderer::RendererColor mScreenQuadTopColor; SampleRenderer::RendererColor mScreenQuadBottomColor; PvdParameters mPvdParams; void updateCameraViewport(PxU32 w, PxU32 h); bool initLogo(); private: bool handleMenuKey(MenuKey::Enum menuKey); void handleSettingMenuKey(MenuKey::Enum menuKey); void refreshVisualizationMenuState(PxVisualizationParameter::Enum p); void toggleDebugRenderer(); //----------------------------------------------------------------------------- // PhysXSampleManager //----------------------------------------------------------------------------- public: static bool registerSample(SampleCreator creator, const char* fullPath) { return addSample(getSampleTreeRoot(), creator, fullPath); } bool getNextSample(); void switchSample(); protected: static Test::TestGroup* mSampleTreeRoot; static Test::TestGroup& getSampleTreeRoot(); static bool addSample(Test::TestGroup& root, SampleCreator creator, const char* fullPath); public: bool mMenuExpand; Test::TestGroup* mRunning; Test::TestGroup* mSelected; PhysXSample* mSample; const char* mDefaultSamplePath; }; const char* getSampleMediaFilename(const char* filename); PxToolkit::BasicRandom& getSampleRandom(); PxErrorCallback& getSampleErrorCallback(); //============================================================================= // macro REGISTER_SAMPLE //----------------------------------------------------------------------------- class SampleFunctionCreator : public PhysXSampleCreator { public: SampleFunctionCreator(FunctionCreator func) : mFunc(func) {} virtual PhysXSample* operator()(PhysXSampleApplication& app) const { return (*mFunc)(app); } private: FunctionCreator mFunc; }; #define SAMPLE_CREATOR(className) create##className #define SAMPLE_STARTER(className) className##Starter #define SAMPLE_CREATOR_VAR(className) g##className##creator #define REGISTER_SAMPLE(className, fullPath) \ static PhysXSample* SAMPLE_CREATOR(className)(PhysXSampleApplication& app) { \ return SAMPLE_NEW(className)(app); \ } \ static SampleFunctionCreator SAMPLE_CREATOR_VAR(className)(SAMPLE_CREATOR(className)); \ struct SAMPLE_STARTER(className) { \ SAMPLE_STARTER(className)() { \ PhysXSampleApplication::registerSample(&SAMPLE_CREATOR_VAR(className), fullPath); \ } \ } g##className##Starter; /////////////////////////////////////////////////////////////////////////////// #endif