diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2018-07-09 12:43:27 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2018-07-10 08:03:30 +0000 |
commit | 3b8e7ec55889d81d996e208dbe8a431bd8edffc2 (patch) | |
tree | 6c01f2337548c8811ba3ba8d76fc9d2840ac49c4 | |
parent | dd2243a416402fc6f087982397f40fccb09912d2 (diff) |
Add fixes and console commands for dynamic subtree spawning
For example, executing the following - either interactively or from a
file via prgload and prgrun - creates a subtree with a Group having a
Text and a Model child. The Model has a DefaultMaterial. The subtree
is then attached to a scene by adding the Group to an existing node
in the scene.
object(csop, csop, Group, null, Slide1)
object(szoveg, szoveg, Text, csop, Slide1)
set(szoveg, textstring, Kocka!)
set(szoveg, textcolor, 1 0 0)
object(kocka, kocka, Model, csop, Slide1)
set(kocka, sourcepath, #Cube)
set(kocka, position, 0 -100 0)
set(kocka, rotation, 30 40 0)
object(ka, ka, DefaultMaterial, kocka, Slide1)
setparent(csop, Layer)
In-progress subtrees can always be inspected by doing scenegraph(obj)
since this walks any object tree regardless of it being part of the
scene or not.
Slide associations can now be changed dynamically with objslideadd and
objslideremove. This will need further work for correct behavior since
right now adding an object to a slide after adding it to the scene will
not lead to making the object correctly visible.
Change-Id: Id270cf8f7906aaa2324c854bda656fa295906f5e
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
-rw-r--r-- | src/runtime/q3dsconsolecommands.cpp | 63 | ||||
-rw-r--r-- | src/runtime/q3dsscenemanager.cpp | 10 |
2 files changed, 60 insertions, 13 deletions
diff --git a/src/runtime/q3dsconsolecommands.cpp b/src/runtime/q3dsconsolecommands.cpp index 4a4489a..2da5a8a 100644 --- a/src/runtime/q3dsconsolecommands.cpp +++ b/src/runtime/q3dsconsolecommands.cpp @@ -146,9 +146,12 @@ void Q3DSConsoleCommands::setupConsole(Q3DSConsole *console) "slide(ctxObj) - Prints the current slide on the time context (scene or component object). [R]\n" "setslide(ctxObj, name) - Changes the current slide on the time context (scene or component object). [R]\n" "\n" - "object(id, name, type, parentObj, slide) - Creates a new object. (type == Model, DefaultMaterial, etc.) [R]\n" - "primitive(id, name, source, parentObj, slide) - Adds a model node with a default material. (source == #Cube, #Cone, etc.) [R]\n" + "object(id, name, type, parentObj, slide) - Creates a new object. (type == Model, DefaultMaterial, ...; parent and slide may be null) [R]\n" + "primitive(id, name, source, parentObj, slide) - Shortcut to add a model with a default material. (source == #Cube, #Cone, etc.) [R]\n" + "setparent(obj, parentObj) - Sets the parent (only valid when object()/primitive() was called with parentObj == null) [R]\n" "kill(obj) - Removes a node from the scene graph (and from the slides' object list). [R]\n" + "objslideadd(obj, slide) - Associates the object with the given slide. [R]\n" + "objslideremove(obj, slide) - Removes the object from the slide's objject list. [R]\n" "\n" "record - Switches to recording mode.\n" "immed - Switches to immediate mode (the default).\n" @@ -363,7 +366,7 @@ void Q3DSConsoleCommands::setupConsole(Q3DSConsole *console) if (obj) { // Unlink (incl. all children) from the slide. Q3DSSlide *slide = m_currentPresentation->masterSlide(); - if (obj->attached()->component) + if (obj->attached() && obj->attached()->component) slide = obj->attached()->component->masterSlide(); Q3DSUipPresentation::forAllObjectsInSubTree(obj, [slide](Q3DSGraphObject *objOrChild) { removeFromSlide_helper(objOrChild, slide); @@ -384,8 +387,6 @@ void Q3DSConsoleCommands::setupConsole(Q3DSConsole *console) const QString source = QString::fromUtf8(unquote(splitArgs[2])); Q3DSGraphObject *parent = resolveObj(splitArgs[3]); Q3DSSlide *slide = static_cast<Q3DSSlide *>(resolveObj(splitArgs[4])); - if (!parent || !slide) - return; Q3DSModelNode *model = m_currentPresentation->newObject<Q3DSModelNode>(id); if (!model) return; @@ -398,11 +399,14 @@ void Q3DSConsoleCommands::setupConsole(Q3DSConsole *console) return; mat->setName(QString::fromUtf8(matId)); model->appendChildNode(mat); - slide->addObject(model); - slide->addObject(mat); + if (slide) { + slide->addObject(model); + slide->addObject(mat); + } // adding to parent must be the last, since it triggers a scene // change notification to the scene manager - parent->appendChildNode(model); + if (parent) + parent->appendChildNode(model); m_console->addMessageFmt(responseColor, "Added"); } }, Q3DSConsole::CmdRecordable)); @@ -414,21 +418,54 @@ void Q3DSConsoleCommands::setupConsole(Q3DSConsole *console) const QByteArray type = unquote(splitArgs[2]); Q3DSGraphObject *parent = resolveObj(splitArgs[3]); Q3DSSlide *slide = static_cast<Q3DSSlide *>(resolveObj(splitArgs[4])); - if (!parent || !slide) - return; Q3DSGraphObject *obj = m_currentPresentation->newObject(type.constData(), id); if (obj) { obj->setName(name); - slide->addObject(obj); + if (slide) + slide->addObject(obj); // adding to parent must be the last, since it triggers a scene // change notification to the scene manager - parent->appendChildNode(obj); + if (parent) + parent->appendChildNode(obj); m_console->addMessageFmt(responseColor, "Added"); } else { m_console->addMessageFmt(errorColor, "Unknown type or duplicate id"); } } }, Q3DSConsole::CmdRecordable)); + m_console->addCommand(Q3DSConsole::makeCommand("setparent", [this](const QByteArray &args) { + QByteArrayList splitArgs = args.split(','); + if (splitArgs.count() >= 2) { + Q3DSGraphObject *obj = resolveObj(splitArgs[0]); + Q3DSGraphObject *parent = resolveObj(splitArgs[1]); + if (obj && parent) { + parent->appendChildNode(obj); + m_console->addMessageFmt(responseColor, "Appended as child node"); + } + } + }, Q3DSConsole::CmdRecordable)); + m_console->addCommand(Q3DSConsole::makeCommand("objslideadd", [this](const QByteArray &args) { + QByteArrayList splitArgs = args.split(','); + if (splitArgs.count() >= 2) { + Q3DSGraphObject *obj = resolveObj(splitArgs[0]); + Q3DSSlide *slide = static_cast<Q3DSSlide *>(resolveObj(splitArgs[1])); + if (obj && slide) { + slide->addObject(obj); + m_console->addMessageFmt(responseColor, "Added to slide object list"); + } + } + }, Q3DSConsole::CmdRecordable)); + m_console->addCommand(Q3DSConsole::makeCommand("objslideremove", [this](const QByteArray &args) { + QByteArrayList splitArgs = args.split(','); + if (splitArgs.count() >= 2) { + Q3DSGraphObject *obj = resolveObj(splitArgs[0]); + Q3DSSlide *slide = static_cast<Q3DSSlide *>(resolveObj(splitArgs[1])); + if (obj && slide) { + slide->removeObject(obj); + m_console->addMessageFmt(responseColor, "Removed from slide object list"); + } + } + }, Q3DSConsole::CmdRecordable)); m_console->setCommandRecorder([this](const QByteArray &cmd) { m_program.append(cmd); @@ -513,6 +550,8 @@ Q3DSGraphObject *Q3DSConsoleCommands::resolveObj(const QByteArray &ref, bool sho if (r.startsWith('#')) obj = m_currentPresentation->object(r.mid(1)); + else if (r == QByteArrayLiteral("null")) + return nullptr; else obj = m_currentPresentation->objectByName(QString::fromUtf8(r)); diff --git a/src/runtime/q3dsscenemanager.cpp b/src/runtime/q3dsscenemanager.cpp index 457cf18..779f344 100644 --- a/src/runtime/q3dsscenemanager.cpp +++ b/src/runtime/q3dsscenemanager.cpp @@ -8073,6 +8073,14 @@ void Q3DSSceneManager::addLayerContent(Q3DSGraphObject *obj, Q3DSGraphObject *pa if (parent->type() == Q3DSGraphObject::Layer) parentEntity = parent->attached<Q3DSLayerAttached>()->layerSceneRootEntity; + // First make sure all properties are resolved; f.ex. a model with + // sourcepath changed before attaching the node to a scene will not + // generate a MeshChanges prop.change, and so the actual mesh will not + // be up-to-date without a resolve. Avoid this. + Q3DSUipPresentation::forAllObjectsInSubTree(obj, [this](Q3DSGraphObject *objOrChild) { + objOrChild->resolveReferences(*m_presentation); + }); + // phase 1 buildLayerScene(obj, layer3DS, parentEntity); qCDebug(lcScene) << "Dyn.added" << obj->attached()->entity; @@ -8095,7 +8103,7 @@ void Q3DSSceneManager::addLayerContent(Q3DSGraphObject *obj, Q3DSGraphObject *pa } Q3DSSlidePlayer *slidePlayer = m_slidePlayer; - if (objOrChild->attached()->component) + if (objOrChild->attached() && objOrChild->attached()->component) slidePlayer = objOrChild->attached()->component->masterSlide()->attached<Q3DSSlideAttached>()->slidePlayer; slidePlayer->objectAboutToBeAddedToScene(objOrChild); |