summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2018-07-09 12:43:27 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2018-07-10 08:03:30 +0000
commit3b8e7ec55889d81d996e208dbe8a431bd8edffc2 (patch)
tree6c01f2337548c8811ba3ba8d76fc9d2840ac49c4
parentdd2243a416402fc6f087982397f40fccb09912d2 (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.cpp63
-rw-r--r--src/runtime/q3dsscenemanager.cpp10
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);