diff --git a/QtQmlViewport/Actors.py b/QtQmlViewport/Actors.py index 2d5add5..2daa56d 100644 --- a/QtQmlViewport/Actors.py +++ b/QtQmlViewport/Actors.py @@ -4,7 +4,7 @@ from QtQmlViewport.Transforms import Transform from QtQmlViewport.utils import to_numpy, tf_to_numpy -from PyQt5.QtGui import QVector3D +from PyQt5.QtGui import QMatrix4x4 from PyQt5.QtCore import pyqtProperty as Property, pyqtSignal as Signal, pyqtSlot as Slot, QObject, Q_CLASSINFO from PyQt5.QtQml import QQmlListProperty @@ -92,6 +92,7 @@ def renderables(self): return QQmlListProperty(Renderable, self, self._renderables) Product.InputProperty(vars(), QObject, 'instantiator', None) + Product.InputProperty(vars(), Transform, 'transform', None) @Slot(Renderable, result = Renderable) def addActor(self, actor): @@ -126,7 +127,7 @@ def actor_to_id(self, id_to_actors = None): id_to_actors = self.get_visible_actors() actor_to_id_ = {} - for i, a in enumerate(id_to_actors): + for i, (a, _) in enumerate(id_to_actors): n = a.objectName() if not n: n = "anonymous" @@ -150,14 +151,15 @@ def merged_bvhs(self): id_to_actors = self.get_visible_actors() - for i, a in enumerate(id_to_actors): + for i, (a, parentTransform) in enumerate(id_to_actors): a.geometry.update() if a.transform: a.transform.update() bvh = a.geometry.goc_bvh(True) bvhs.append(bvh if bvh is None else bvh.bvh) - - matrices.append(tf_to_numpy(a.transform) if a.transform else np.eye(4, dtype = 'f4')) + p = tf_to_numpy(a.transform) if parentTransform else np.eye(4, dtype = 'f4') + m = tf_to_numpy(a.transform) if a.transform else np.eye(4, dtype = 'f4') + matrices.append(np.matmul(p, m)) uniforms = {} for k,v, in a.effect.shader0.uniforms.items(): @@ -187,8 +189,6 @@ def merged_bvhs(self): def is_any_visible_actor_dirty(self): - is_dirty = False - def recursive_check(a): if issubclass(type(a), Actor): if a.visible: @@ -215,15 +215,17 @@ def recursive_check(a): return False - def get_visible_actors(self): - actors = set() + def get_visible_actors(self, parentTransform = QMatrix4x4()): + actors = [] + + tf = parentTransform * (self.transform.worldTransform(True) if self.transform else QMatrix4x4()) def add_actor(a): if issubclass(type(a), Actor): if a.visible: - actors.add(a) + actors.append((a, tf)) elif issubclass(type(a), Actors): - actors.update(a.get_visible_actors()) #union of sets + actors.extend(a.get_visible_actors(tf)) #union of sets for r in self._renderables: add_actor(r) diff --git a/QtQmlViewport/InFboRenderer.py b/QtQmlViewport/InFboRenderer.py index 7061fcc..2bef662 100644 --- a/QtQmlViewport/InFboRenderer.py +++ b/QtQmlViewport/InFboRenderer.py @@ -179,10 +179,10 @@ def synchronize(self, viewport): if viewport.actors is None : return - sorted_actors = sorted(list(viewport.actors.get_visible_actors()), key=attrgetter('renderRank')) + sorted_actors = sorted(list(viewport.actors.get_visible_actors()), key=lambda a_tf:a_tf[0].renderRank) sorted_actors.extend(viewport._debug_actors.get_visible_actors()) - for actor in sorted_actors: + for actor, parent_tf in sorted_actors: if not actor.update() : if not hasattr(actor, "__error_reported___") or not actor.__error_reported___: LoggingManager.instance().warning("Not rendering actor " + str(actor) + ". It is has error " + str(actor._error )+ ".") @@ -202,7 +202,6 @@ def synchronize(self, viewport): indices = actor.geometry.indices attribs = actor.geometry.attribs.get_attributes() - bo_actor = {"attribs": {} , "textures": {} , "out_textures": {} @@ -211,7 +210,7 @@ def synchronize(self, viewport): , "program": actor.effect.shader0._program , "point_size": actor.effect.pointSize , "line_width": actor.effect.lineWidth - , "transform" : actor.transform.worldTransform() if actor.transform else QMatrix4x4() + , "transform" : parent_tf * (actor.transform.worldTransform() if actor.transform else QMatrix4x4()) , "primitiveType": actor.geometry.primitiveType , "actor_not_thread_safe": actor} except Exception as e: diff --git a/QtQmlViewport/Transforms.py b/QtQmlViewport/Transforms.py index 1f7fa96..d34b30d 100644 --- a/QtQmlViewport/Transforms.py +++ b/QtQmlViewport/Transforms.py @@ -46,10 +46,16 @@ def before_write_local_transform(self, matrix4x4): matrix4x4 = QMatrix4x4() return matrix4x4 - Product.InputProperty(vars(), Product.Product, 'localTransform', QMatrix4x4(), None, before_write_local_transform) + Product.InputProperty(vars(), QMatrix4x4, 'localTransform', QMatrix4x4(), None, before_write_local_transform) Product.InputProperty(vars(), Product.Product, 'parentTransform', None) + @Slot(result = QMatrix4x4) + def earliestParent(self, update = False): + tf = self.parentTransform + while tf is not None: + tf = tf.parentTransform + return tf @Slot(result = QMatrix4x4) def worldTransform(self, update = False): diff --git a/QtQmlViewport/Viewport.py b/QtQmlViewport/Viewport.py index 15698fa..d281126 100644 --- a/QtQmlViewport/Viewport.py +++ b/QtQmlViewport/Viewport.py @@ -41,7 +41,7 @@ def __init__( self, parent=None ): Product.RWProperty(vars(), Camera, 'camera', Camera()) - Product.RWProperty(vars(), 'QVariant', 'backgroundColor', QColor(qRgba(1,1,1,1))) + Product.RWProperty(vars(), QColor, 'backgroundColor', QColor(qRgba(1,1,1,1))) Product.RWProperty(vars(), Actors, 'actors', None) diff --git a/setup.py b/setup.py index 429d922..2bf46d8 100644 --- a/setup.py +++ b/setup.py @@ -71,7 +71,7 @@ def build_extension(self, ext): kwargs = dict( name='QtQmlViewport', - version='0.2.0', + version='0.2.1', author='Maxime Lemonnier', description='Python QtQml 3D viewer toolkit', long_description='',