You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

124 lines
5.7 KiB

# This file is part of Korman.
#
# Korman is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Korman is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Korman. If not, see <http://www.gnu.org/licenses/>.
import bpy
from bpy.props import *
from PyHSPlasma import *
from .base import PlasmaModifierProperties
from ...exporter import ExportError
# These are the kinds of physical bounds Plasma can work with.
# This sequence is acceptable in any EnumProperty
bounds_types = (
("box", "Bounding Box", "Use a perfect bounding box"),
("sphere", "Bounding Sphere", "Use a perfect bounding sphere"),
("hull", "Convex Hull", "Use a convex set encompasing all vertices"),
("trimesh", "Triangle Mesh", "Use the exact triangle mesh (SLOW!)")
)
def bounds_type_index(key):
return list(zip(*bounds_types))[0].index(key)
def bounds_type_str(idx):
return bounds_types[idx][0]
def _set_phys_prop(prop, sim, phys, value=True):
"""Sets properties on plGenericPhysical and plSimulationInterface (seeing as how they are duped)"""
sim.setProperty(prop, value)
phys.setProperty(prop, value)
class PlasmaCollider(PlasmaModifierProperties):
pl_id = "collision"
bl_category = "Physics"
bl_label = "Collision"
bl_icon = "MOD_PHYSICS"
bl_description = "Simple physical collider"
bounds = EnumProperty(name="Bounds Type", description="", items=bounds_types, default="hull")
avatar_blocker = BoolProperty(name="Blocks Avatars", description="Object blocks avatars", default=True)
camera_blocker = BoolProperty(name="Blocks Camera LOS", description="Object blocks camera line-of-sight", default=True)
friction = FloatProperty(name="Friction", min=0.0, default=0.5)
restitution = FloatProperty(name="Restitution", description="Coefficient of collision elasticity", min=0.0, max=1.0)
terrain = BoolProperty(name="Terrain", description="Object represents the ground", default=False)
dynamic = BoolProperty(name="Dynamic", description="Object can be influenced by other objects (ie is kickable)", default=False)
mass = FloatProperty(name="Mass", description="Mass of object in pounds", min=0.0, default=1.0)
start_asleep = BoolProperty(name="Start Asleep", description="Object is not active until influenced by another object", default=False)
def export(self, exporter, bo, so):
# All modifier properties are examined by this little stinker...
exporter.physics.generate_physical(bo, so)
@property
def requires_actor(self):
return self.dynamic
class PlasmaSubworld(PlasmaModifierProperties):
pl_id = "subworld_def"
bl_category = "Physics"
bl_label = "Subworld"
bl_description = "Subworld definition"
bl_icon = "WORLD"
sub_type = EnumProperty(name="Subworld Type",
description="Specifies the physics strategy to use for this subworld",
items=[("auto", "Auto", "Korman will decide which physics strategy to use"),
("dynamicav", "Dynamic Avatar", "Allows the avatar to affected by dynamic physicals"),
("subworld", "Separate World", "Causes all objects to be placed in a separate physics simulation")],
default="auto",
options=set())
gravity = FloatVectorProperty(name="Gravity",
description="Subworld's gravity defined in feet per second squared",
size=3, default=(0.0, 0.0, -32.174), precision=3,
subtype="ACCELERATION", unit="ACCELERATION")
def export(self, exporter, bo, so):
if self.is_dedicated_subworld(exporter):
# NOTE to posterity... Cyan's PotS/Havok subworlds appear to have a
# plHKPhysical object that is set as LOSOnly convex hull. They appear to
# be a bounding box. PyPRP generated PRPs do not do this and work just fine,
# however, so this is probably just a quirk of the Havok-era PlasmaMAX
subworld = exporter.mgr.find_create_object(plHKSubWorld, so=so)
subworld.gravity = hsVector3(*self.gravity)
def is_dedicated_subworld(self, exporter):
if exporter.mgr.getVer() != pvMoul:
return True
if self.sub_type == "subworld":
return True
elif self.sub_type == "dynamicav":
return False
else:
return not self.property_unset("gravity")
def post_export(self, exporter, bo, so):
# It appears PotS does something really fancy with subworlds under the hood such that
# if you make a subworld that has collision, it will get into an infinite loop in
# plCoordinateInterface::IGetRoot. Not really sure why this happens (nor do I care),
# but we definitely don't want it to happen.
if bo.type != "EMPTY":
exporter.report.warn("Subworld '{}' is attached to a '{}'--this should be an empty.", bo.name, bo.type, indent=1)
if so.sim:
if exporter.mgr.getVer() > pvPots:
exporter.report.port("Subworld '{}' has physics data--this will cause PotS to crash.", bo.name, indent=1)
else:
raise ExportError("Subworld '{}' cannot have physics data (should be an empty).".format(bo.name))