-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Restore scene grabbables/physics support
Scene grabbables support was reverted (Hubs-Foundation/hubs#6515) in the Hubs client due to bugs and is now only present for the Hubs Client's addons branch and its behavior graphs add-on. This commit restores the scene grabbables and physics support (along with fixes/improvements that were added to it in the main Blender add-on) to the behavior graphs Blender add-on to allow the functionality to be used with the Hubs Client's addons branch and its behavior graphs add-on. A corresponding commit to the main Blender add-on removes support for scene grabbables/physics in the main Blender add-on so it maintains compatibility with the current Hubs Client.
- Loading branch information
Showing
6 changed files
with
432 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
from bpy.props import BoolProperty | ||
from io_hubs_addon.components.hubs_component import HubsComponent | ||
from io_hubs_addon.components.types import NodeType, PanelType, Category | ||
from io_hubs_addon.components.utils import remove_component, add_component | ||
from .networked_transform import NetworkedTransform | ||
from ..utils import do_register, do_unregister | ||
|
||
|
||
class Grabbable(HubsComponent): | ||
_definition = { | ||
'name': 'grabbable', | ||
'display_name': 'Grabbable', | ||
'category': Category.OBJECT, | ||
'node_type': NodeType.NODE, | ||
'panel_type': [PanelType.OBJECT], | ||
'icon': 'VIEW_PAN', | ||
'deps': ['rigidbody', 'networked-transform'], | ||
'version': (1, 0, 1) | ||
} | ||
|
||
cursor: BoolProperty( | ||
name="By Cursor", description="Can be grabbed by a cursor", default=True) | ||
|
||
hand: BoolProperty( | ||
name="By Hand", description="Can be grabbed by VR hands", default=True) | ||
|
||
@classmethod | ||
def init(cls, obj): | ||
obj.hubs_component_list.items.get('rigidbody').isDependency = True | ||
|
||
def migrate(self, migration_type, panel_type, instance_version, host, migration_report, ob=None): | ||
migration_occurred = False | ||
if instance_version <= (1, 0, 0): | ||
migration_occurred = True | ||
|
||
# This was a component that has disappeared but it was usually added together with grababble so we try to remove those instances. | ||
if "capturable" in host.hubs_component_list.items: | ||
remove_component(host, "capturable") | ||
|
||
if "networked-object-properties" in host.hubs_component_list.items: | ||
remove_component(host, "networked-object-properties") | ||
|
||
add_component(host, NetworkedTransform.get_name()) | ||
|
||
return migration_occurred | ||
|
||
|
||
def register(): | ||
do_register(Grabbable) | ||
|
||
|
||
def unregister(): | ||
do_unregister(Grabbable) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
from io_hubs_addon.components.hubs_component import HubsComponent | ||
from io_hubs_addon.components.types import NodeType, PanelType | ||
from ..utils import do_register, do_unregister | ||
|
||
|
||
class NetworkedTransform(HubsComponent): | ||
_definition = { | ||
'name': 'networked-transform', | ||
'display_name': 'Networked Transform', | ||
'node_type': NodeType.NODE, | ||
'panel_type': [PanelType.OBJECT], | ||
'icon': 'EMPTY_AXIS', | ||
'deps': ['networked'], | ||
'version': (1, 0, 0) | ||
} | ||
|
||
|
||
def register(): | ||
do_register(NetworkedTransform) | ||
|
||
|
||
def unregister(): | ||
do_unregister(NetworkedTransform) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
from bpy.props import BoolProperty, FloatProperty, EnumProperty, FloatVectorProperty | ||
from io_hubs_addon.components.hubs_component import HubsComponent | ||
from io_hubs_addon.components.types import NodeType, PanelType, Category | ||
from mathutils import Vector | ||
from io_hubs_addon.io.utils import import_component, assign_property | ||
from ..utils import do_register, do_unregister | ||
|
||
|
||
class PhysicsShape(HubsComponent): | ||
_definition = { | ||
'name': 'physics-shape', | ||
'display_name': 'Physics Shape', | ||
'category': Category.OBJECT, | ||
'node_type': NodeType.NODE, | ||
'panel_type': [PanelType.OBJECT, PanelType.BONE], | ||
'icon': 'SCENE_DATA', | ||
'version': (1, 0, 1) | ||
} | ||
|
||
type: EnumProperty( | ||
name="Type", description="Type", | ||
items=[("box", "Box Collider", "A box-shaped primitive collision shape"), | ||
("sphere", "Sphere Collider", "A primitive collision shape which represents a sphere"), | ||
("hull", "Convex Hull", | ||
"A convex hull wrapped around the object's vertices. A good analogy for a convex hull is an elastic membrane or balloon under pressure which is placed around a given set of vertices. When released the membrane will assume the shape of the convex hull"), | ||
("mesh", "Mesh Collider", | ||
"A shape made of the actual vertices of the object. This can be expensive for large meshes")], | ||
default="hull") | ||
|
||
fit: EnumProperty( | ||
name="Fit Mode", | ||
description="Shape fitting mode", | ||
items=[("all", "Automatic fit all", "Automatically match the shape to fit the object's vertices"), | ||
("manual", "Manual", "Use the manually specified dimensions to define the shape, ignoring the object's vertices")], | ||
default="all") | ||
|
||
halfExtents: FloatVectorProperty( | ||
name="Half Extents", | ||
description="Half dimensions of the collider. (Only used when fit is set to \"manual\" and type is set to \"box\")", | ||
unit='LENGTH', | ||
subtype="XYZ", | ||
default=(0.5, 0.5, 0.5)) | ||
|
||
minHalfExtent: FloatProperty( | ||
name="Min Half Extent", | ||
description="The minimum size to use when automatically generating half extents. (Only used when fit is set to \"all\" and type is set to \"box\")", | ||
unit="LENGTH", | ||
default=0.0) | ||
|
||
maxHalfExtent: FloatProperty( | ||
name="Max Half Extent", | ||
description="The maximum size to use when automatically generating half extents. (Only used when fit is set to \"all\" and type is set to \"box\")", | ||
unit="LENGTH", | ||
default=1000.0) | ||
|
||
sphereRadius: FloatProperty( | ||
name="Sphere Radius", | ||
description="Radius of the sphere collider. (Only used when fit is set to \"manual\" and type is set to \"sphere\")", | ||
unit="LENGTH", default=0.5) | ||
|
||
offset: FloatVectorProperty( | ||
name="Offset", description="An offset to apply to the collider relative to the object's origin", | ||
unit='LENGTH', | ||
subtype="XYZ", | ||
default=(0.0, 0.0, 0.0)) | ||
|
||
includeInvisible: BoolProperty( | ||
name="Include Invisible", | ||
description="Include invisible objects when generating a collider. (Only used if \"fit\" is set to \"all\")", | ||
default=False) | ||
|
||
def draw(self, context, layout, panel): | ||
layout.prop(self, "type") | ||
layout.prop(self, "fit") | ||
if self.fit == "manual": | ||
if self.type == "box": | ||
layout.prop(self, "halfExtents") | ||
elif self.type == "sphere": | ||
layout.prop(self, "sphereRadius") | ||
else: | ||
if self.type == "box": | ||
layout.prop(self, "minHalfExtent") | ||
layout.prop(self, "maxHalfExtent") | ||
layout.prop(self, "includeInvisible") | ||
layout.prop(self, "offset") | ||
|
||
if self.fit == "manual" and (self.type == "mesh" or self.type == "hull"): | ||
col = layout.column() | ||
col.alert = True | ||
col.label( | ||
text="'Hull' and 'Mesh' do not support 'manual' fit mode", icon='ERROR') | ||
|
||
def gather(self, export_settings, object): | ||
props = super().gather(export_settings, object) | ||
props['offset'] = { | ||
'x': self.offset.x, | ||
'y': self.offset.z if export_settings['gltf_yup'] else self.offset.y, | ||
'z': self.offset.y if export_settings['gltf_yup'] else self.offset.z, | ||
} | ||
props['halfExtents'] = { | ||
'x': self.halfExtents.x, | ||
'y': self.halfExtents.z if export_settings['gltf_yup'] else self.halfExtents.y, | ||
'z': self.halfExtents.y if export_settings['gltf_yup'] else self.halfExtents.z, | ||
} | ||
return props | ||
|
||
def migrate(self, migration_type, panel_type, instance_version, host, migration_report, ob=None): | ||
migration_occurred = False | ||
if instance_version <= (1, 0, 0): | ||
migration_occurred = True | ||
|
||
offset = self.offset.copy() | ||
offset = Vector((offset.x, offset.z, offset.y)) | ||
self.offset = offset | ||
|
||
halfExtents = self.halfExtents.copy() | ||
halfExtents = Vector((halfExtents.x, halfExtents.z, halfExtents.y)) | ||
self.halfExtents = halfExtents | ||
|
||
return migration_occurred | ||
|
||
@classmethod | ||
def gather_import(cls, gltf, blender_host, component_name, component_value, import_report, blender_ob=None): | ||
gltf_yup = gltf.import_settings.get('gltf_yup', True) | ||
|
||
blender_component = import_component(component_name, blender_host) | ||
for property_name, property_value in component_value.items(): | ||
if property_name == 'offset' and gltf_yup: | ||
property_value['y'], property_value['z'] = property_value['z'], property_value['y'] | ||
|
||
elif property_name == 'halfExtents' and gltf_yup: | ||
property_value['y'], property_value['z'] = property_value['z'], property_value['y'] | ||
|
||
assign_property(gltf.vnodes, blender_component, | ||
property_name, property_value) | ||
|
||
|
||
def register(): | ||
do_register(PhysicsShape) | ||
|
||
|
||
def unregister(): | ||
do_unregister(PhysicsShape) |
Oops, something went wrong.