// 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-2025 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. // // The macro logic in this header (and the headers CmOmniPvdAutoGenRegisterData.h and // and CmOmniPvdAutoGenSetData.h) is meant as a helper to automatically generate a // structure that stores all PVD class and attribute handles for a module, handles the // registration logic and adds methods for object creation, setting attribute // values etc. At the core of the generation logic is a user defined header file // that describes the classes and attributes as follows: // // OMNI_PVD_CLASS_BEGIN(MyClass1) // OMNI_PVD_ATTRIBUTE(MyClass1, myAttr1, PxReal, OmniPvdDataType::eFLOAT32) // OMNI_PVD_ATTRIBUTE(MyClass1, myAttr2, PxReal, OmniPvdDataType::eFLOAT32) // OMNI_PVD_CLASS_END(MyClass1) // // OMNI_PVD_CLASS_UNTYPED_BEGIN(MyClass2) // OMNI_PVD_ATTRIBUTE(MyClass2, myAttr1, PxU32, OmniPvdDataType::eUINT32) // OMNI_PVD_CLASS_END(MyClass2) // // The structure to create from this description will look somewhat like this: // // struct MyModulePvdObjectsDescriptor // { // // struct PvdMyClass1 // { // typedef MyClass1 ObjectType; // static OmniPvdObjectHandle getObjectHandle(const ObjectType& objectRef) { return reinterpret_cast(&objectRef); } // // OmniPvdClassHandle classHandle; // // void createInstance(OmniPvdWriter& writer, OmniPvdContextHandle contextHandle, const ObjectType& objectRef) const // { // writer.createObject(contextHandle, classHandle, getObjectHandle(objectRef), NULL); // } // // static void destroyInstance(OmniPvdWriter& writer, OmniPvdContextHandle contextHandle, const ObjectType& objectRef) // { // writer.destroyObject(contextHandle, getObjectHandle(objectRef)); // } // // OmniPvdAttributeHandle myAttr1; // void set_myAttr1_(OmniPvdWriter& writer, OmniPvdContextHandle contextHandle, const ObjectType& objectRef, const PxReal& value) const // { // writer.setAttribute(contextHandle, getObjectHandle(objectRef), myAttr1, reinterpret_cast(&value), getOmniPvdDataTypeSize()); // } // // OmniPvdAttributeHandle myAttr2; // void set_myAttr2_(OmniPvdWriter& writer, OmniPvdContextHandle contextHandle, const ObjectType& objectRef, const PxReal& value) const // { // writer.setAttribute(contextHandle, getObjectHandle(objectRef), myAttr2, reinterpret_cast(&value), getOmniPvdDataTypeSize()); // } // }; // PvdMyClass1 pvdMyClass1; // // // struct PvdMyClass2 // { // typedef OmniPvdObjectHandle ObjectType; // static OmniPvdObjectHandle getObjectHandle(const ObjectType& objectHandle) { return objectHandle; } // // OmniPvdClassHandle classHandle; // // void createInstance(OmniPvdWriter& writer, OmniPvdContextHandle contextHandle, const ObjectType& objectRef) const // { // writer.createObject(contextHandle, classHandle, getObjectHandle(objectRef), NULL); // } // // static void destroyInstance(OmniPvdWriter& writer, OmniPvdContextHandle contextHandle, const ObjectType& objectRef) // { // writer.destroyObject(contextHandle, getObjectHandle(objectRef)); // } // // OmniPvdAttributeHandle myAttr1; // void set_myAttr1_(OmniPvdWriter& writer, OmniPvdContextHandle contextHandle, const ObjectType& objectRef, const PxU32& value) const // { // writer.setAttribute(contextHandle, getObjectHandle(objectRef), myAttr1, reinterpret_cast(&value), getOmniPvdDataTypeSize()); // } // }; // PvdMyClass2 pvdMyClass2; // // // void myRegisterDataMethod(OmniPvdWriter& writer) // { // pvdMyClass1.classHandle = writer.registerClass("MyClass1"); // pvdMyClass1.myAttr1 = writer.registerAttribute(pvdMyClass1.classHandle, "myAttr1", OmniPvdDataType::eFLOAT32, 1); // pvdMyClass1.myAttr2 = writer.registerAttribute(pvdMyClass1.classHandle, "myAttr2", OmniPvdDataType::eFLOAT32, 1); // // pvdMyClass2.classHandle = writer.registerClass("MyClass2"); // pvdMyClass2.myAttr1 = writer.registerAttribute(pvdMyClass2.classHandle, "myAttr1", OmniPvdDataType::eUINT32, 1); // } // // }; // // Assuming the class and attribute definitions are in a file called MyModulePvdObjectDefinitions.h, // the described structure can be generated like this: // // struct MyModulePvdObjectsDescriptor // { // // #include "CmOmniPvdAutoGenCreateRegistrationStruct.h" // #include "MyModulePvdObjectDefinitions.h" // #include "CmOmniPvdAutoGenClearDefines.h" // // // custom registration data related members that are not auto-generated can go here, for example // // // void myRegisterDataMethod(OmniPvdWriter& writer) // { // #define OMNI_PVD_WRITER_VAR writer // // #include "CmOmniPvdAutoGenRegisterData.h" // #include "MyModulePvdObjectDefinitions.h" // #include "CmOmniPvdAutoGenClearDefines.h" // // // custom registration code that is not auto-generated can go here too // // #undef OMNI_PVD_WRITER_VAR // } // }; // // As can be seen, CmOmniPvdAutoGenCreateRegistrationStruct.h is responsible for generating the structs, // members and setter methods. CmOmniPvdAutoGenRegisterData.h is responsible for generating the registration // code (note that defining OMNI_PVD_WRITER_VAR is important in this context since it is used inside // CmOmniPvdAutoGenRegisterData.h) // // Note that it is the user's responsibility to include the necessary headers before applying these helpers // (for example, OmniPvdDefines.h etc.). // // Last but not least, the helpers in CmOmniPvdAutoGenSetData.h provide a way to use this structure to // set values of attributes, create class instances etc. An example usage is shown below: // // OmniPvdContextHandle contextHandle; // assuming this holds the context the objects belong to // MyClass1 myClass1Instance; // PxReal value; // assuming this holds the value to set the attribute to // // OMNI_PVD_CREATE(contextHandle, MyClass1, myClass1Instance); // OMNI_PVD_SET(contextHandle, MyClass1, myAttr1, myClass1Instance, value); // // To use these helper macros, the following things need to be defined before including CmOmniPvdAutoGenSetData.h: // // #define OMNI_PVD_GET_WRITER(writer) // OmniPvdWriter* writer = GetPvdWriterForMyModule(); // // #define OMNI_PVD_GET_REGISTRATION_DATA(regData) // MyModulePvdObjectsDescriptor* regData = GetPvdObjectsDescForMyModule(); // // #include "CmOmniPvdAutoGenSetData.h" // // GetPvdWriterForMyModule() and GetPvdObjectsDescForMyModule() just stand for the logic the user needs // to provide to access the OmniPvdWriter object and the generated description structure. In the given example, // the variables "writer" and "regData" need to be assigned but the code to do so will be user specific. // // #define OMNI_PVD_CLASS_INTERNALS \ \ OmniPvdClassHandle classHandle; \ \ void createInstance(OmniPvdWriter& writer, OmniPvdContextHandle contextHandle, const ObjectType& objectRef) const \ { \ writer.createObject(contextHandle, classHandle, getObjectHandle(objectRef), NULL); \ } \ \ static void destroyInstance(OmniPvdWriter& writer, OmniPvdContextHandle contextHandle, const ObjectType& objectRef) \ { \ writer.destroyObject(contextHandle, getObjectHandle(objectRef)); \ } // // Define a PVD class. // // Note: has to be paired with OMNI_PVD_CLASS_END // // classID: name of the class to register in PVD (note: has to be an existing C++ class) // #define OMNI_PVD_CLASS_BEGIN(classID) \ \ struct Pvd##classID \ { \ typedef classID ObjectType; \ \ static OmniPvdObjectHandle getObjectHandle(const ObjectType& objectRef) { return reinterpret_cast(&objectRef); } \ \ OMNI_PVD_CLASS_INTERNALS // // Define a PVD class that is derived from another class. // // Note: has to be paired with OMNI_PVD_CLASS_END // // classID: see OMNI_PVD_CLASS_BEGIN // baseClassID: the name of the class to derive from // #define OMNI_PVD_CLASS_DERIVED_BEGIN(classID, baseClassID) OMNI_PVD_CLASS_BEGIN(classID) // // Define a PVD class. // // Note: has to be paired with OMNI_PVD_CLASS_END // // classID: name of the class to register in PVD (note: the class does not need to match an actually existing // class but still needs to follow C++ naming conventions) // #define OMNI_PVD_CLASS_UNTYPED_BEGIN(classID) \ \ struct Pvd##classID \ { \ typedef OmniPvdObjectHandle ObjectType; \ \ static OmniPvdObjectHandle getObjectHandle(const ObjectType& objectHandle) { return objectHandle; } \ \ OMNI_PVD_CLASS_INTERNALS // // Define a PVD class that is derived from another class. // // Note: has to be paired with OMNI_PVD_CLASS_END // // classID: see OMNI_PVD_CLASS_UNTYPED_BEGIN // baseClassID: the name of the class to derive from // #define OMNI_PVD_CLASS_UNTYPED_DERIVED_BEGIN(classID, baseClassID) OMNI_PVD_CLASS_UNTYPED_BEGIN(classID) // // See OMNI_PVD_CLASS_BEGIN for more info. // #define OMNI_PVD_CLASS_END(classID) \ \ }; \ Pvd##classID pvd##classID; // // Define a PVD enum class. // // Note: has to be paired with OMNI_PVD_ENUM_END // // enumID: name of the enum class (has to follow C++ naming conventions) // #define OMNI_PVD_ENUM_BEGIN(enumID) \ \ struct Pvd##enumID \ { \ OmniPvdClassHandle classHandle; // // See OMNI_PVD_ENUM_BEGIN // #define OMNI_PVD_ENUM_END(enumID) OMNI_PVD_CLASS_END(enumID) // // Define a simple PVD attribute. // // Note: needs to be placed between a OMNI_PVD_CLASS_BEGIN, OMNI_PVD_CLASS_END // sequence // // classID: name of the class to add the attribute to (see OMNI_PVD_CLASS_BEGIN) // attributeID: name of the attribute (has to follow C++ naming conventions) // valueType: attribute data type (int, float etc.) // pvdDataType: PVD attribute data type (see OmniPvdDataType) // #define OMNI_PVD_ATTRIBUTE(classID, attributeID, valueType, pvdDataType) \ \ OmniPvdAttributeHandle attributeID; \ void set_##attributeID##_(OmniPvdWriter& writer, OmniPvdContextHandle contextHandle, const ObjectType& objectRef, const valueType& value) const \ { \ PX_ASSERT(sizeof(valueType) == getOmniPvdDataTypeSize()); \ writer.setAttribute(contextHandle, getObjectHandle(objectRef), attributeID, reinterpret_cast(&value), getOmniPvdDataTypeSize()); \ } // // Define a fixed size multi-value PVD attribute. // // Note: needs to be placed between a OMNI_PVD_CLASS_BEGIN, OMNI_PVD_CLASS_END // sequence // // The attribute is a fixed size array of values of the given pvd data type. // // entryCount: number of entries the array will hold. // // See OMNI_PVD_ATTRIBUTE for the other parameters. Note that valueType is // expected to hold a type that matches the size of the whole array, i.e., // sizeof(valueType) == entryCount * getOmniPvdDataTypeSize() // #define OMNI_PVD_ATTRIBUTE_ARRAY_FIXED_SIZE(classID, attributeID, valueType, pvdDataType, entryCount) \ \ OmniPvdAttributeHandle attributeID; \ void set_##attributeID##_(OmniPvdWriter& writer, OmniPvdContextHandle contextHandle, const ObjectType& objectRef, const valueType& value) const \ { \ const uint32_t byteSize = static_cast(sizeof(valueType)); \ PX_ASSERT(byteSize == (entryCount * getOmniPvdDataTypeSize())); \ writer.setAttribute(contextHandle, getObjectHandle(objectRef), attributeID, reinterpret_cast(&value), byteSize); \ } // // Define a variable size multi-value PVD attribute. // // Note: needs to be placed between a OMNI_PVD_CLASS_BEGIN, OMNI_PVD_CLASS_END // sequence // // The attribute is a variable size array of values of the given pvd data type. // // See OMNI_PVD_ATTRIBUTE for a parameter description. Note that valueType is expected // to define the type of a single array element, for example, int for an integer array. // #define OMNI_PVD_ATTRIBUTE_ARRAY_VARIABLE_SIZE(classID, attributeID, valueType, pvdDataType) \ \ OmniPvdAttributeHandle attributeID; \ void set_##attributeID##_(OmniPvdWriter& writer, OmniPvdContextHandle contextHandle, const ObjectType& objectRef, const valueType* values, uint32_t valueCount) const \ { \ const uint32_t byteSize = valueCount * getOmniPvdDataTypeSize(); \ writer.setAttribute(contextHandle, getObjectHandle(objectRef), attributeID, reinterpret_cast(values), byteSize); \ } // // Define a string PVD attribute. // // Note: needs to be placed between a OMNI_PVD_CLASS_BEGIN, OMNI_PVD_CLASS_END // sequence // // See OMNI_PVD_ATTRIBUTE for a parameter description. // #define OMNI_PVD_ATTRIBUTE_STRING(classID, attributeID) \ \ OmniPvdAttributeHandle attributeID; \ void set_##attributeID##_(OmniPvdWriter& writer, OmniPvdContextHandle contextHandle, const ObjectType& objectRef, const char* values, uint32_t valueCount) const \ { \ const uint32_t byteSize = valueCount; \ writer.setAttribute(contextHandle, getObjectHandle(objectRef), attributeID, reinterpret_cast(values), byteSize); \ } // // Define a unique list PVD attribute. // // Note: needs to be placed between a OMNI_PVD_CLASS_BEGIN, OMNI_PVD_CLASS_END // sequence // // See OMNI_PVD_ATTRIBUTE for a parameter description. Note that valueType is expected // to define the class the list will hold pointers to. If it shall hold pointers to // instances of class MyClass, then the valueType is MyClass. // #define OMNI_PVD_ATTRIBUTE_UNIQUE_LIST(classID, attributeID, valueType) \ \ OmniPvdAttributeHandle attributeID; \ \ void addTo_##attributeID##_(OmniPvdWriter& writer, OmniPvdContextHandle contextHandle, const ObjectType& objectRef, const valueType& value) const \ { \ const OmniPvdObjectHandle objHandle = reinterpret_cast(&value); \ const uint8_t* ptr = reinterpret_cast(&objHandle); \ writer.addToUniqueListAttribute(contextHandle, getObjectHandle(objectRef), attributeID, ptr, sizeof(OmniPvdObjectHandle)); \ } \ \ void removeFrom_##attributeID##_(OmniPvdWriter& writer, OmniPvdContextHandle contextHandle, const ObjectType& objectRef, const valueType& value) const \ { \ const OmniPvdObjectHandle objHandle = reinterpret_cast(&value); \ const uint8_t* ptr = reinterpret_cast(&objHandle); \ writer.removeFromUniqueListAttribute(contextHandle, getObjectHandle(objectRef), attributeID, ptr, sizeof(OmniPvdObjectHandle)); \ } // // Define a flag PVD attribute. // // Note: needs to be placed between a OMNI_PVD_CLASS_BEGIN, OMNI_PVD_CLASS_END // sequence // // enumType: the enum type this attribute refers to // enumID: the name of the enum class that describes the enum (see OMNI_PVD_ENUM_BEGIN) // // See OMNI_PVD_ATTRIBUTE for the other parameters. // #define OMNI_PVD_ATTRIBUTE_FLAG(classID, attributeID, enumType, enumID) \ \ OmniPvdAttributeHandle attributeID; \ void set_##attributeID##_(OmniPvdWriter& writer, OmniPvdContextHandle contextHandle, const ObjectType& objectRef, const enumType& value) const \ { \ writer.setAttribute(contextHandle, getObjectHandle(objectRef), attributeID, reinterpret_cast(&value), sizeof(enumType)); \ } // // Define an enum entry. // // Note: needs to be placed between a OMNI_PVD_ENUM_BEGIN, OMNI_PVD_ENUM_END // sequence // // enumID: name of the enum class to add an entry to (see OMNI_PVD_ENUM_BEGIN) // enumEntryID: the name of the enum entry to add to the enum class (has to follow C++ naming conventions) // value: the enum value // #define OMNI_PVD_ENUM_VALUE_EXPLICIT(enumID, enumEntryID, value) // // Define an enum entry. // // Note: needs to be placed between a OMNI_PVD_ENUM_BEGIN, OMNI_PVD_ENUM_END // sequence // // See OMNI_PVD_ENUM_VALUE_EXPLICIT for a description of the parameters. This shorter form expects the enum to // have a C++ definition of the form: // // struct // { // enum Enum // { // = ... // } // } // // such that the value can be derived using: :: // #define OMNI_PVD_ENUM_VALUE(enumID, enumEntryID) \ \ OMNI_PVD_ENUM_VALUE_EXPLICIT(enumID, enumEntryID, enumID::enumEntryID)