panda3d/panda/src/physx/generateCode.py

1022 lines
36 KiB
Python

import os.path
import re
import xmltramp
docDir = "C:\\pratt\\schellGames\\physxDoxy\\2.7.3\\doc\\xml"
membersToOmit = (
"user_data",
"get_type",
"get_internal",
"load",
"create_fluid_hardware_triangle_mesh",
"get_center",
"get_extents",
"get_rot",
"physx_ray_capsule_intersect",
"is_point_in_plane_joint",
"is_point_on_line_joint",
"get_actors",
"get_actor_group_pair_array",
"get_filter_ops",
"get_island_array_from_actor",
"get_material_array",
"physx_compute_sphere",
"l_vec_base3f_obb_sqr_dist",
)
stringConversions = [
("NX_INLINE", "INLINE"),
("NX_BOOL", "bool"),
("NxI64", "PN_int64"),
("NxI32", "int"),
("NxI16", "short"),
("NxI8", "char"),
("NxU64", "PN_uint64"),
("NxU32", "unsigned int"),
("NxU16", "unsigned short"),
("NxU8", "unsigned char"),
("NxF32", "float"),
("NxF64", "double"),
("NxReal", "float"),
("NxActorGroup", "unsigned short"),
("NxCollisionGroup", "unsigned short"),
("NxMaterialIndex", "unsigned short"),
("NxSubmeshIndex", "unsigned int"),
("NxTriangleID", "unsigned int"),
("NxVec3", "LVecBase3f"),
("NxPoint", "LVecBase3f"),
("NxMat33", "LMatrix3f"),
("NxMat34", "LMatrix4f"),
("NxQuat", "LQuaternionf"),
("Nx", "Physx"),
]
reConversions = []
for pair in stringConversions:
reConversions.append( (re.compile( pair[0] ), pair[1]) )
convertFromFunctions = {
"LVecBase3f" : "PhysxManager::lVecBase3_to_nxVec3",
"LMatrix3f" : "PhysxManager::lMatrix3_to_nxMat33",
"LMatrix4f" : "PhysxManager::lMatrix4_to_nxMat34",
"LQuaternionf" : "PhysxManager::lQuaternion_to_nxQuat",
}
convertToFunctions = {
"LVecBase3f" : "PhysxManager::nxVec3_to_lVecBase3",
"LMatrix3f" : "PhysxManager::nxMat33_to_lMatrix3",
"LMatrix4f" : "PhysxManager::nxMat34_to_lMatrix4",
"LQuaternionf" : "PhysxManager::nxQuat_to_lQuaternion",
}
builtinTypes = (
"void",
"bool",
"int",
"float",
"double",
"char",
"unsigned char",
"signed char",
"unsigned int",
"signed int",
"short int",
"unsigned short int",
"signed short int",
"long int",
"signed long int",
"unsigned long int",
"long double",
)
#subClasses = {
# "PhysxBoxShape" : "PhysxShape",
# "PhysxCapsuleShape" : "PhysxShape",
# "PhysxPlaneShape" : "PhysxShape",
# "PhysxSphereShape" : "PhysxShape",
# "PhysxD6Joint" : "PhysxJoint",
# "PhysxD6JointDesc" : "PhysxJointDesc",
# "PhysxActorNode" : "PandaNode",
#}
typedWritableReferenceCountClasses = (
"BoxShape",
"CapsuleShape",
"D6Joint",
"Joint",
"PlaneShape",
"Shape",
"SphereShape",
)
classNameConversions = {
"Actor" : "ActorNode",
}
def generateClassCode( name, isStruct=False ):
underscoredName = getUnderscoredFromMixedCase( name )
if isStruct:
xmlfile = file( os.path.join( docDir, "struct_nx_%s.xml" % underscoredName ) )
else:
xmlfile = file( os.path.join( docDir, "class_nx_%s.xml" % underscoredName ) )
doc = xmltramp.seed( xmlfile )
xmlfile.close()
if hasattr( doc[0], "basecompoundref" ):
className = str( doc[0].basecompoundref ).replace( "Nx", "Physx" )
prot = doc[0].basecompoundref( "prot" )
virt = doc[0].basecompoundref( "virt" )
if virt == "virtual":
baseClassRef = "%s virtual %s" % (prot, className)
else:
baseClassRef = "%s %s" % (prot, className)
else:
baseClassRef = None
structors = {}
methods = {}
attributes = {}
for section in doc[0]["sectiondef":]:
if (section( "kind" ) == "public-func") or (section( "kind" ) == "user-defined"):
for member in section["memberdef":]:
memberName = str( member.name )
method = {}
method["type"] = str( member.type )
method["argsstring"] = str( member.argsstring )
method["const"] = member( "const" ) == "yes"
method["params"] = []
for param in member["param":]:
if hasattr( param, "type" ) and hasattr( param, "declname" ):
method["params"].append( [str( param.type ), str( param.declname )] )
if (memberName == "Nx" + name) or (memberName == "~Nx" + name):
structors[memberName] = method
else:
methods[memberName] = method
elif section( "kind" ) == "public-attrib":
for member in section["memberdef":]:
memberName = str( member.name )
variable = {}
variable["type"] = "INLINE " + str( member.type )
attributes[memberName] = variable
convertNames( structors, underscoreNames=False )
convertNames( methods )
convertNames( attributes )
filterMembers( structors )
filterMembers( methods )
filterMembers( attributes )
createHeader( name, structors, methods, attributes, baseClassRef )
createCxx( name, structors, methods, attributes )
createInline( name, structors, methods, attributes )
def convertNames( memberDict, underscoreNames=True ):
for memberName in memberDict.keys():
info = memberDict[memberName]
for key in info.keys():
if key == "type":
info[key] = convertString( info[key] )
rawType = getRawType( info[key] )
if (rawType not in builtinTypes) and ("INLINE" in info[key]):
info[key] = info[key].replace( "INLINE", "" ).strip()
if rawType.startswith( "Physx" ) and (rawType[5:] in classNameConversions):
info[key] = info[key].replace( "Physx" + rawType[5:], "Physx" + classNameConversions[rawType[5:]] ).strip()
elif key == "argsstring":
info[key] = convertString( info[key] )
elif key == "params":
for param in info[key]:
param[0] = convertString( param[0] )
param[1] = getUnderscoredFromMixedCase( convertString( param[1] ) )
rawType = getRawType( param[0] )
if (rawType not in builtinTypes) and ("INLINE" in info["type"]):
param[0] = param[0].replace( "INLINE", "" ).strip()
if rawType.startswith( "Physx" ) and (rawType[5:] in classNameConversions):
param[0] = param[0].replace( "Physx" + rawType[5:], "Physx" + classNameConversions[rawType[5:]] ).strip()
elif key == "const":
pass
else:
raise
memberDict[memberName]["originalName"] = memberName
if underscoreNames:
newMemberName = getUnderscoredFromMixedCase( convertString( memberName ) )
else:
newMemberName = convertString( memberName )
if newMemberName != memberName:
del memberDict[memberName]
memberDict[newMemberName] = info
def filterMembers( memberDict ):
for memberName in memberDict.keys():
info = memberDict[memberName]
rawType = getRawType( info["type"] )
if memberName in membersToOmit:
del memberDict[memberName]
elif rawType.startswith( "Physx" ) and (not isNameKnown( rawType[5:] )):
del memberDict[memberName]
elif info["type"].count( "*" ) > 1:
del memberDict[memberName]
elif memberDict[memberName].has_key( "params" ):
for param in memberDict[memberName]["params"]:
rawType = getRawType( param[0] )
if rawType.startswith( "Physx" ) and (not isNameKnown( rawType[5:] )):
del memberDict[memberName]
break
def convertString( s ):
for pattern, replacement in reConversions:
s = pattern.sub( replacement, s )
return s
def createHeader( name, structors, methods, attributes, baseClassRef ):
templateFile = file( "physxTemplate.h" )
templateString = templateFile.read()
templateFile.close()
lowerPattern = re.compile( "template" )
upperPattern = re.compile( "TEMPLATE" )
capsPattern = re.compile( "Template" )
typeHeaderPattern = re.compile( "//typedWritableReferenceCountHeader" )
superHeaderPattern = re.compile( "//superHeader\n" )
forwardsPattern = re.compile( "//forwardDeclarations\n" )
baseClassRefPattern = re.compile( "/\*baseclassref\*/" )
structorsPattern = re.compile( "//publicstructors" )
methodsPattern = re.compile( "//publicmethods" )
attributesPattern = re.compile( "//publicattributes" )
nxReferencePattern = re.compile( "//nxreference" )
typeInfoPattern = re.compile( "//typeinfo\n" )
nName = name
if name in classNameConversions:
name = classNameConversions[name]
if name in typedWritableReferenceCountClasses:
if baseClassRef is None:
baseClassRef = "public TypedWritableReferenceCount"
templateString = typeInfoPattern.sub( getTypeInfo( name, baseClassRef ), templateString )
else:
templateString = typeInfoPattern.sub( "", templateString )
if baseClassRef is not None:
templateString = superHeaderPattern.sub( '#include "%s.h"\n\n' % lowerFirst( baseClassRef.split()[1] ), templateString )
templateString = baseClassRefPattern.sub( ": %s " % baseClassRef, templateString )
else:
templateString = superHeaderPattern.sub( "", templateString )
templateString = baseClassRefPattern.sub( "", templateString )
templateString = lowerPattern.sub( lowerFirst( name ), templateString )
templateString = upperPattern.sub( name.upper(), templateString )
templateString = capsPattern.sub( name, templateString )
templateString = forwardsPattern.sub( getForwardDeclarations( name, structors, methods, attributes, baseClassRef ), templateString )
templateString = structorsPattern.sub( getMethodHeaders( structors ), templateString )
templateString = methodsPattern.sub( getMethodHeaders( methods ), templateString )
templateString = attributesPattern.sub( getAttributeHeaders( attributes ), templateString )
if name in avoidPointerNames:
templateString = nxReferencePattern.sub( " Nx%s %s;" % (nName, "n" + nName), templateString )
else:
templateString = nxReferencePattern.sub( " Nx%s *%s;" % (nName, "n" + nName), templateString )
outputFile = file( "generated/physx" + name + ".h", "w" )
outputFile.write( templateString )
outputFile.close()
def getIncludes( name, structors, methods, attributes, baseClassRef=None ):
rawTypes = []
for method in structors.values() + methods.values():
for param in method["params"]:
rawTypes.append( getRawType( param[0] ) )
for member in methods.values() + attributes.values():
rawTypes.append( getRawType( member["type"] ) )
if baseClassRef is not None:
for part in baseClassRef.split():
rawTypes.append( part )
includeDict = {}
for rawType in rawTypes:
if rawType.startswith( "Physx" ) and isBuiltName( rawType[5:] ) and (rawType[5:] != name):
includeDict['#include "%s.h"\n' % (rawType[0].lower() + rawType[1:])] = True
elif rawType.startswith( "L" ):
includeDict['#include "luse.h"\n'] = True
includes = includeDict.keys()
includes.sort()
return "".join( includes )
def getForwardDeclarations( name, structors, methods, attributes, baseClassRef=None ):
rawTypes = []
for method in structors.values() + methods.values():
for param in method["params"]:
rawTypes.append( getRawType( param[0] ) )
for member in methods.values() + attributes.values():
rawTypes.append( getRawType( member["type"] ) )
if baseClassRef is not None:
baseClass = baseClassRef.split()[1]
else:
baseClass = None
forwardDict = {} # use a dictionary to avoid duplicates
for rawType in rawTypes:
if rawType.startswith( "Physx" ) and isBuiltName( rawType[5:] ) and (rawType[5:] != name) and (rawType != baseClass):
forwardDict["class %s;\n" % rawType] = True
forwards = forwardDict.keys()
forwards.sort()
if len( forwards ) > 0:
return "".join( forwards ) + "\n"
else:
return ""
def getMethodHeaders( methodDict ):
s = ""
names = methodDict.keys()
names.sort()
for name in names:
method = methodDict[name]
s += " "
if method["type"] != "":
s += "%s " % method["type"]
s += "%s(%s)" % (name, getParamString( method["params"] ))
if method["const"]:
s += " const"
s += ";\n"
return s
def getAttributeHeaders( attributeDict ):
getters = ""
setters = ""
names = attributeDict.keys()
names.sort()
for name in names:
attribute = attributeDict[name]
type = attribute["type"]
rawType = getRawType( type )
if (rawType not in builtinTypes) and (not type.endswith( "*" )) and (not convertFromFunctions.has_key( rawType )) and (rawType not in enumerations.keys()):
type += " &"
getters += " %s get_%s() const;\n" % (type, name)
if "INLINE" in type:
setters += " INLINE void set_%s(%s value);\n" % (name, type.replace( "INLINE", "" ).strip())
else:
setters += " void set_%s(%s value);\n" % (name, type.replace( "INLINE", "" ).strip())
if getters != "":
return "%s\n%s" % (getters, setters)
else:
return ""
def getTypeInfo( className, baseClassRef ):
typeInfoString = """
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
%(superName)s::init_type();
register_type(_type_handle, "Physx%(className)s",
%(superName)s::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {
init_type();
return get_class_type();
}
private:
static TypeHandle _type_handle;
"""
content = {}
content["className"] = className
content["superName"] = baseClassRef.split()[1]
return typeInfoString % content
def createCxx( name, structors, methods, attributes ):
templateFile = file( "physxTemplate.cxx" )
templateString = templateFile.read()
templateFile.close()
lowerPattern = re.compile( "template" )
upperPattern = re.compile( "TEMPLATE" )
capsPattern = re.compile( "Template" )
includesPattern = re.compile( "//includes" )
typeHandlePattern = re.compile( "//typehandle" )
structorsPattern = re.compile( "//publicstructors\n" )
methodsPattern = re.compile( "//publicmethods\n" )
attributesPattern = re.compile( "//publicattributes\n" )
pName = name
if name in classNameConversions:
pName = classNameConversions[name]
if pName in typedWritableReferenceCountClasses:
templateString = typeHandlePattern.sub( "TypeHandle Physx%s::_type_handle;\n" % pName, templateString )
else:
templateString = typeHandlePattern.sub( "", templateString )
templateString = lowerPattern.sub( lowerFirst( pName ), templateString )
templateString = upperPattern.sub( pName.upper(), templateString )
templateString = capsPattern.sub( pName, templateString )
templateString = includesPattern.sub( getIncludes( name, structors, methods, attributes ), templateString )
templateString = structorsPattern.sub( getMethodSource( name, structors, doInline=False, doCode=False ), templateString )
templateString = methodsPattern.sub( getMethodSource( name, methods, doInline=False, doCode=True ), templateString )
templateString = attributesPattern.sub( getAttributeSource( name, attributes, doInline=False ), templateString )
outputFile = file( "generated/physx" + pName + ".cxx", "w" )
outputFile.write( templateString )
outputFile.close()
def createInline( name, structors, methods, attributes ):
templateFile = file( "physxTemplate.I" )
templateString = templateFile.read()
templateFile.close()
lowerPattern = re.compile( "template" )
upperPattern = re.compile( "TEMPLATE" )
capsPattern = re.compile( "Template" )
structorsPattern = re.compile( "//publicstructors\n" )
methodsPattern = re.compile( "//publicmethods\n" )
attributesPattern = re.compile( "//publicattributes\n" )
pName = name
if name in classNameConversions:
pName = classNameConversions[name]
templateString = lowerPattern.sub( lowerFirst( pName ), templateString )
templateString = upperPattern.sub( pName.upper(), templateString )
templateString = capsPattern.sub( pName, templateString )
templateString = structorsPattern.sub( getMethodSource( name, structors, doInline=True, doCode=False ), templateString )
templateString = methodsPattern.sub( getMethodSource( name, methods, doInline=True, doCode=True ), templateString )
templateString = attributesPattern.sub( getAttributeSource( name, attributes, doInline=True ), templateString )
outputFile = file( "generated/physx" + pName + ".I", "w" )
outputFile.write( templateString )
outputFile.close()
def getMethodSource( className, methodDict, doInline=False, doCode=True ):
if className in avoidPointerNames:
attribOperator = "."
else:
attribOperator = "->"
pClassName = className
if className in classNameConversions:
pClassName = classNameConversions[className]
result = ""
methodString = """////////////////////////////////////////////////////////////////////
// Function : %(name)s
// Access : Published
// Description :
////////////////////////////////////////////////////////////////////
%(type)s%(class)s::
%(name)s%(params)s%(const)s {
%(code)s
}
"""
names = methodDict.keys()
names.sort()
for name in names:
method = methodDict[name]
if (("INLINE" in method["type"]) and doInline) or (("INLINE" not in method["type"]) and (not doInline)):
content = {}
content["name"] = name
if method["type"] != "":
content["type"] = "%s " % method["type"]
else:
content["type"] = ""
content["class"] = "Physx" + pClassName
content["params"] = "(%s)" % getParamString( method["params"] )
if method["const"]:
content["const"] = " const"
else:
content["const"] = ""
nxObject = "n" + className
nxMethodName = method["originalName"]
callerParamString = getCallerParamString( method["params"] )
if name.startswith( "create" ):
content["code"] = ' throw "Not Implemented";'
elif doCode:
if method.has_key( "code" ):
content["code"] = method["code"] % nxObject
elif ("void" in method["type"]) and ("*" not in method["type"]):
content["code"] = " %s%s%s(%s);" % (nxObject, attribOperator, nxMethodName, callerParamString)
else:
inner = "%s%s%s(%s)" % (nxObject, attribOperator, nxMethodName, callerParamString)
content["code"] = " return %s;" % wrapValue( method["type"], inner, isReturnValue=True )
if className not in avoidPointerNames:
if ("void" in method["type"]) and ("*" not in method["type"]):
content["code"] = (" nassertv(%s != NULL);\n\n" % nxObject) + content["code"]
elif ("bool" in method["type"]) and ("*" not in method["type"]):
content["code"] = (" nassertr(%s != NULL, false);\n\n" % nxObject) + content["code"]
elif ("float" in method["type"]) and ("*" not in method["type"]):
content["code"] = (" nassertr(%s != NULL, -1.0f);\n\n" % nxObject) + content["code"]
elif ("unsigned int" in method["type"]) and ("*" not in method["type"]):
content["code"] = (" nassertr(%s != NULL, -1);\n\n" % nxObject) + content["code"]
elif ("unsigned short" in method["type"]) and ("*" not in method["type"]):
content["code"] = (" nassertr(%s != NULL, -1);\n\n" % nxObject) + content["code"]
elif ("LVecBase3f" in method["type"]) and ("*" not in method["type"]):
content["code"] = (" nassertr(%s != NULL, *((LVecBase3f *)NULL));\n\n" % nxObject) + content["code"]
elif ("LMatrix3f" in method["type"]) and ("*" not in method["type"]):
content["code"] = (" nassertr(%s != NULL, *((LMatrix3f *)NULL));\n\n" % nxObject) + content["code"]
elif ("LMatrix4f" in method["type"]) and ("*" not in method["type"]):
content["code"] = (" nassertr(%s != NULL, *((LMatrix4f *)NULL));\n\n" % nxObject) + content["code"]
elif ("LQuaternionf" in method["type"]) and ("*" not in method["type"]):
content["code"] = (" nassertr(%s != NULL, *((LQuaternionf *)NULL));\n\n" % nxObject) + content["code"]
elif ("PhysxScene" in method["type"]) and ("*" not in method["type"]):
content["code"] = (" nassertr(%s != NULL, *((PhysxScene *)NULL));\n\n" % nxObject) + content["code"]
elif ("PhysxJointState" in method["type"]) and ("*" not in method["type"]):
content["code"] = (" nassertr(%s != NULL, physx_js_unbound);\n\n" % nxObject) + content["code"]
elif "*" in method["type"]:
content["code"] = (" nassertr(%s != NULL, NULL);\n\n" % nxObject) + content["code"]
else:
content["code"] = ""
result += methodString % content
return result
def getAttributeSource( className, attributeDict, doInline=False ):
if className in avoidPointerNames:
attribOperator = "."
else:
attribOperator = "->"
methodDict = {}
for name in attributeDict.keys():
type = attributeDict[name]["type"]
rawType = getRawType( type )
if (rawType not in builtinTypes) and (not type.endswith( "*" )) and (not convertFromFunctions.has_key( rawType )) and (rawType not in enumerations.keys()):
type += " &"
setterValue = wrapValue( type, "value", isReturnValue=False )
getter = {
"type" : type,
"const" : True,
"params" : [],
"code" : " return %%s%s%s;" % (attribOperator, attributeDict[name]["originalName"]),
"originalName" : getMixedCaseFromUnderscored( "get_" + name ),
}
setter = {
"type" : "void",
"const" : False,
"params" : [[type.replace( "INLINE", "" ).strip(), "value"]],
"code" : " %%s%s%s = %s;" % (attribOperator, attributeDict[name]["originalName"], setterValue),
"originalName" : getMixedCaseFromUnderscored( "set_" + name ),
}
methodDict["get_" + name] = getter
methodDict["set_" + name] = setter
if "INLINE" in type:
setter["type"] = "INLINE void"
if convertFromFunctions.has_key( rawType ):
valueString = "%%s%s%s" % (attribOperator, attributeDict[name]["originalName"])
getter["code"] = " return %s;" % getConvertedValue( type, valueString, False )
getter["type"] = type
elif rawType in enumerations.keys():
valueString = "%%s%s%s" % (attribOperator, attributeDict[name]["originalName"])
getter["code"] = " return %s;" % wrapValue( rawType, valueString, isReturnValue=True )
elif rawType.startswith( "Physx" ) and isBuiltName( rawType[5:] ):
getter["code"] = ' throw "Not Implemented"; // return %%s%s%s;' % (attribOperator, attributeDict[name]["originalName"])
return getMethodSource( className, methodDict, doInline=doInline, doCode=True )
def getParamString( params ):
items = ["%s %s" % (param[0], param[1]) for param in params]
return ", ".join( items )
def getCallerParamString( params ):
items = []
for param in params:
items.append( wrapValue( param[0], param[1] ) )
return ", ".join( items )
def wrapValue( type, valueString, isReturnValue=False ):
rawType = getRawType( type )
if rawType in builtinTypes:
return valueString
elif (not isReturnValue) and convertFromFunctions.has_key( rawType ):
return getConvertedValue( type, valueString, not isReturnValue )
elif isReturnValue and convertToFunctions.has_key( rawType ):
return getConvertedValue( type, valueString, not isReturnValue )
elif rawType.startswith( "Physx" ) and isBuiltName( rawType[5:] ):
if isReturnValue:
if "*" in type:
return "(%s *)(%s->userData)" % (rawType, valueString)
else:
return "*((%s *)(%s.userData))" % (rawType, valueString)
else:
if "*" in type:
if rawType[5:] in avoidPointerNames:
return "&(%s->%s)" % (valueString, "n" + rawType[5:])
else:
return "%s->%s" % (valueString, "n" + rawType[5:])
else:
if rawType[5:] in avoidPointerNames:
return "%s.%s" % (valueString, "n" + rawType[5:])
else:
return "*(%s.%s)" % (valueString, "n" + rawType[5:])
elif rawType in enumerations.keys():
if isReturnValue:
return "(%s)%s" % (rawType, valueString)
else:
return "(%s)%s" % ("Nx" + rawType[5:], valueString)
else:
return valueString
def isNameKnown( name ):
if name in allBuiltNames:
return True
elif name in classNameConversions.values():
return True
elif enumerations.has_key( "Physx" + name ):
return True
else:
return False
def isBuiltName( name ):
return (name in allBuiltNames) or (name in classNameConversions.values())
def getUnderscoredFromMixedCase( name ):
return re.sub( r"(?<=[a-z])[A-Z]|(?<!^)[A-Z](?=[a-z])", r"_\g<0>", name ).lower()
def getMixedCaseFromUnderscored( name ):
return re.sub( r"_([a-z])", lambda m: (m.group( 1 ).upper()), name )
def lowerFirst( name ):
return name[0].lower() + name[1:]
def getRawType( type ):
rawType = type.replace( "const", "" )
rawType = rawType.replace( "INLINE", "" )
rawType = rawType.strip( " *&" )
return rawType
def getConvertedValue( type, valueString, convertFrom=True ):
rawType = getRawType( type )
if convertFrom:
func = convertFromFunctions[rawType]
else:
func = convertToFunctions[rawType]
if "*" in type:
return "&%s(*%s)" % (func, valueString)
else:
return "%s(%s)" % (func, valueString)
def generateEnumerationFile():
global enumerations
enumerations = {}
locations = {}
for group in ("cloth", "fluids", "foundation", "physics", "softbody"):
getEnumerations( group, enumerations, locations )
enumerationContent = []
enumerationContentForInterrogate = []
names = enumerations.keys()
names.sort()
for name in names:
if name not in ["PhysxMemoryType"]:
enumerationContent.append( "enum %s {\n" % name )
enumerationContentForInterrogate.append( "enum %s {\n" % name )
nonInitializedItems, namesToInitializers = enumerations[name]
for nxValue in nonInitializedItems:
parts = nxValue.split( "_" )[1:]
parts = ["physx"] + [part.lower() for part in parts]
physxValue = "_".join( parts )
enumerationContent.append( " %s = %s,\n" % (physxValue, nxValue) )
enumerationContentForInterrogate.append( " %s,\n" % physxValue )
for nxValue in namesToInitializers.keys():
parts = nxValue.split( "_" )[1:]
parts = ["physx"] + [part.lower() for part in parts]
physxValue = "_".join( parts )
enumerationContent.append( " %s = %s,\n" % (physxValue, nxValue) )
initializer = namesToInitializers[nxValue]
enumerationContentForInterrogate.append( " %s = %s,\n" % (physxValue, initializer) )
enumerationContent.append( "};\n\n" )
enumerationContentForInterrogate.append( "};\n\n" )
enumerationTemplate = """// Filename: physx_enumerations.h
// Created by: pratt (Apr 20, 2006)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef PHYSX_ENUMERATIONS_H
#define PHYSX_ENUMERATIONS_H
#ifdef HAVE_PHYSX
#include "NoMinMax.h"
#include "NxPhysics.h"
%s
#endif // HAVE_PHYSX
#endif // PHYSX_ENUMERATIONS_H
"""
outputFile = file( "generated/physx_enumerations.h", "w" )
outputFile.write( enumerationTemplate % "".join( enumerationContent ) )
outputFile.close()
outputFile = file( "generated/physx_enumerations_for_interrogate.h", "w" )
outputFile.write( enumerationTemplate % "".join( enumerationContentForInterrogate ) )
outputFile.close()
def getEnumerations( group, enumerations, locations ):
xmlfile = file( os.path.join( docDir, "group__%s.xml" % group ) )
doc = xmltramp.seed( xmlfile )
xmlfile.close()
for section in doc.compounddef["sectiondef":]:
if section( "kind" ) == "enum":
for enumeration in section["memberdef":]:
name = str( enumeration.name ).replace( "Nx", "Physx" )
nonInitializedItems = []
namesToInitializers = {}
for value in enumeration["enumvalue":]:
try:
initializer = str( value.initializer )
try:
eval( initializer )
namesToInitializers[str( value.name )] = initializer
except:
# Avoid creating enum values that we know will
# not work, i.e. bitwise ORs of previous values.
pass
except:
nonInitializedItems.append( str( value.name ) )
enumerations[name] = (nonInitializedItems, namesToInitializers)
location = os.path.basename( str( enumeration["location"]( "file" ) ) )
if group == "cloth":
location = "cloth/" + location
elif group == "fluids":
location = "fluids/" + location
elif group == "softbody":
location = "softbody/" + location
locations[location] = True
def generateSourcesPP( names ):
templateFile = file( "SourcesTemplate.pp" )
templateString = templateFile.read()
templateFile.close()
headerLines = []
sourceLines = []
for name in names:
if name == "Actor":
name = "ActorNode"
headerLines.append( " physx%s.I physx%s.h \\\n" % (name, name) )
sourceLines.append( " physx%s.cxx \\\n" % name )
headersPattern = re.compile( "//headers" )
cxxPattern = re.compile( "//cxx" )
templateString = headersPattern.sub( "".join( headerLines ), templateString )
templateString = cxxPattern.sub( "".join( sourceLines ), templateString )
outputFile = file( "generated/Sources.pp", "w" )
outputFile.write( templateString )
outputFile.close()
buildNowNames = [
"Actor",
"ActorDesc",
"BodyDesc",
"Bounds3",
"Box",
"Joint",
"D6Joint",
"JointDesc",
"D6JointDesc",
"JointDriveDesc",
"JointLimitSoftDesc",
"JointLimitSoftPairDesc",
"Material",
"MaterialDesc",
"Plane",
"Ray",
"Scene",
"SceneDesc",
"SceneStats2",
"Segment",
"Capsule",
"Shape",
"BoxShape",
"CapsuleShape",
"PlaneShape",
"SphereShape",
"ShapeDesc",
"BoxShapeDesc",
"CapsuleShapeDesc",
"PlaneShapeDesc",
"SphereShapeDesc",
"Sphere",
"UtilLib",
]
buildNowStructs = [
]
allBuiltNames = [
"Actor",
"ActorDesc",
"BodyDesc",
"Bounds3",
"Box",
"Joint",
"D6Joint",
"JointDesc",
"D6JointDesc",
"JointDriveDesc",
"JointLimitSoftDesc",
"JointLimitSoftPairDesc",
"Material",
"MaterialDesc",
"Plane",
"Ray",
"Scene",
"SceneDesc",
"SceneStats2",
"Segment",
"Capsule",
"Shape",
"BoxShape",
"CapsuleShape",
"PlaneShape",
"SphereShape",
"ShapeDesc",
"BoxShapeDesc",
"CapsuleShapeDesc",
"PlaneShapeDesc",
"SphereShapeDesc",
"Sphere",
"UtilLib",
]
expectedNames = [
"Actor",
"ActorDesc",
"BodyDesc",
"Bounds3",
"Box",
"Cloth",
"ClothDesc",
"ClothMesh",
"ContactPair",
"ContactStreamIterator",
"ConvexMesh",
"ConvexMeshDesc",
"Effector",
"SpringAndDamperEffector",
"Fluid",
"FluidDesc",
"FluidEmitter",
"FluidEmitterDesc",
"GroupsMask",
"HeightField",
"HeightFieldDesc",
"Joint",
"CylindricalJoint",
"D6Joint",
"DistanceJoint",
"FixedJoint",
"PointInPlaneJoint",
"PointOnLineJoint",
"PrismaticJoint",
"PulleyJoint",
"RevoluteJoint",
"SphericalJoint",
"JointDesc",
"CylindricalJointDesc",
"D6JointDesc",
"DistanceJointDesc",
"FixedJointDesc",
"PointInPlaneJointDesc",
"PointOnLineJointDesc",
"PrismaticJointDesc",
"PulleyJointDesc",
"RevoluteJointDesc",
"SphericalJointDesc",
"JointDriveDesc",
"JointLimitDesc",
"JointLimitPairDesc",
"JointLimitSoftDesc",
"JointLimitSoftPairDesc",
"Material",
"MaterialDesc",
"MeshData",
"MotorDesc",
"PairFlag",
"ParticleData",
"Plane",
"PMap",
"Ray",
"Scene",
"SceneDesc",
"SceneStats2",
"Segment",
"Capsule",
"Shape",
"BoxShape",
"CapsuleShape",
"ConvexShape",
"PlaneShape",
"SphereShape",
"TriangleMeshShape",
"WheelShape",
"ShapeDesc",
"BoxShapeDesc",
"CapsuleShapeDesc",
"ConvexShapeDesc",
"PlaneShapeDesc",
"SphereShapeDesc",
"TriangleMeshShapeDesc",
"WheelShapeDesc",
"SimpleTriangleMesh",
"ClothMeshDesc",
"TriangleMeshDesc",
"Sphere",
"SpringAndDamperEffectorDesc",
"SpringDesc",
"TireFunctionDesc",
"UtilLib",
"WheelContactData",
]
avoidPointerNames = [
"ActorDesc",
"ActorDescBase",
"BodyDesc",
"ClothDesc",
"ConvexMeshDesc",
"FluidDesc",
"FluidEmitterDesc",
"HeightFieldDesc",
"CylindricalJointDesc",
"D6JointDesc",
"DistanceJointDesc",
"FixedJointDesc",
"PointInPlaneJointDesc",
"PointOnLineJointDesc",
"PrismaticJointDesc",
"PulleyJointDesc",
"RevoluteJointDesc",
"SphericalJointDesc",
"JointDriveDesc",
"JointLimitDesc",
"JointLimitPairDesc",
"JointLimitSoftDesc",
"JointLimitSoftPairDesc",
"MaterialDesc",
"MotorDesc",
"SceneDesc",
"ShapeDesc",
"BoxShapeDesc",
"CapsuleShapeDesc",
"ConvexShapeDesc",
"PlaneShapeDesc",
"SphereShapeDesc",
"TriangleMeshShapeDesc",
"WheelShapeDesc",
"ClothMeshDesc",
"TriangleMeshDesc",
"SpringAndDamperEffectorDesc",
"SpringDesc",
"TireFunctionDesc",
]
if __name__ == "__main__":
if not os.path.exists( "generated" ):
os.mkdir( "generated" )
generateEnumerationFile()
generateSourcesPP( allBuiltNames )
for name in buildNowNames:
print name
generateClassCode( name )
for name in buildNowStructs:
print name
generateClassCode( name, isStruct=True )