Merge remote-tracking branch 'upstream/master' into smarter_textures
Conflicts: libraries/gpu/src/gpu/Texture.cpp
|
@ -58,6 +58,8 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig
|
|||
|
||||
DependencyManager::registerInheritance<SpatialParentFinder, AssignmentParentFinder>();
|
||||
|
||||
DependencyManager::set<AudioScriptingInterface>();
|
||||
|
||||
DependencyManager::set<ResourceCacheSharedItems>();
|
||||
DependencyManager::set<SoundCache>();
|
||||
DependencyManager::set<AudioInjectorManager>();
|
||||
|
@ -324,7 +326,26 @@ void EntityScriptServer::nodeActivated(SharedNodePointer activatedNode) {
|
|||
void EntityScriptServer::nodeKilled(SharedNodePointer killedNode) {
|
||||
switch (killedNode->getType()) {
|
||||
case NodeType::EntityServer: {
|
||||
clear();
|
||||
// Before we clear, make sure this was our only entity server.
|
||||
// Otherwise we're assuming that we have "trading" entity servers
|
||||
// (an old one going away and a new one coming onboard)
|
||||
// and that we shouldn't clear here because we're still doing work.
|
||||
bool hasAnotherEntityServer = false;
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
nodeList->eachNodeBreakable([&hasAnotherEntityServer, &killedNode](const SharedNodePointer& node){
|
||||
if (node->getType() == NodeType::EntityServer && node->getUUID() != killedNode->getUUID()) {
|
||||
// we're talking to > 1 entity servers, we know we won't clear
|
||||
hasAnotherEntityServer = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!hasAnotherEntityServer) {
|
||||
clear();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -395,7 +416,8 @@ void EntityScriptServer::selectAudioFormat(const QString& selectedCodecName) {
|
|||
|
||||
void EntityScriptServer::resetEntitiesScriptEngine() {
|
||||
auto engineName = QString("about:Entities %1").arg(++_entitiesScriptEngineCount);
|
||||
auto newEngine = QSharedPointer<ScriptEngine>(new ScriptEngine(ScriptEngine::ENTITY_SERVER_SCRIPT, NO_SCRIPT, engineName));
|
||||
auto newEngine = QSharedPointer<ScriptEngine>(new ScriptEngine(ScriptEngine::ENTITY_SERVER_SCRIPT, NO_SCRIPT, engineName),
|
||||
&ScriptEngine::deleteLater);
|
||||
|
||||
auto webSocketServerConstructorValue = newEngine->newFunction(WebSocketServerClass::constructor);
|
||||
newEngine->globalObject().setProperty("WebSocketServer", webSocketServerConstructorValue);
|
||||
|
|
|
@ -1,125 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="45"
|
||||
height="45"
|
||||
id="svg3827"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.1 r9760"
|
||||
sodipodi:docname="load-script.svg">
|
||||
<defs
|
||||
id="defs3829" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="3.959798"
|
||||
inkscape:cx="171.17264"
|
||||
inkscape:cy="-8.0710166"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1028"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata3832">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>T.Hofmeister</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1007.3622)">
|
||||
<g
|
||||
id="layer1-7"
|
||||
transform="matrix(-0.25019951,0,0,0.28877175,123.44112,917.40972)"
|
||||
style="fill:#696969">
|
||||
<g
|
||||
id="g3257"
|
||||
transform="matrix(1.9175,0,0,1.9175,-607.19,-179.09)"
|
||||
style="fill:#696969">
|
||||
<path
|
||||
id="path3224"
|
||||
d="m 563.06,260.72 -1.25,0.16 -40.15,4.87 -1.66,0.22 0.38,1.62 c 3.78,16.93 -0.59,34.07 -2.88,51.57 l -0.22,1.84 1.81,-0.16 42,-3 1.25,-0.06 0.16,-1.25 c 2.13,-17.86 6.92,-36.12 0.94,-54.62 l -0.38,-1.19 z m -2.18,3.28 c 4.96,16.72 -1.56,33.17 -3.72,50.47 l -35.63,2.78 c 2.25,-16.14 7.03,-29.55 3.78,-46.19 L 560.88,264 z"
|
||||
style="fill:#696969;fill-rule:evenodd"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3237"
|
||||
d="m 531.39,275.61 23.34,-4.6"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3243"
|
||||
d="m 532.1,280.91 22.27,-2.83"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3247"
|
||||
d="m 531.92,285.86 22.89,-1.95"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3249"
|
||||
d="m 530.15,292.84 24.22,-2.12"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3251"
|
||||
d="m 529.45,297.53 22.98,-0.8"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3253"
|
||||
d="m 528.65,304.24 22.45,-2.56"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3255"
|
||||
d="m 527.5,309.37 22.81,-1.77"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<path
|
||||
display="block"
|
||||
d="m 22.50945,1041.7031 c 10.249979,14.5758 18.326744,5.8628 15.179173,-14.1826 l 3.401516,-0.2354 -8.04206,-17.0393 -2.800459,17.789 3.507825,-0.2428 c 2.535261,14.6877 0.402108,18.0407 -11.324416,13.7916 z"
|
||||
style="color:#000000;fill:#a9a9a9;stroke:#000000;stroke-width:0.61923206;display:block"
|
||||
id="path1432"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
<rect
|
||||
style="color:#000000;fill:#00ffff;fill-opacity:0;fill-rule:nonzero;stroke:none;stroke-width:0.42527184;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3032"
|
||||
width="44.57473"
|
||||
height="44.57473"
|
||||
x="0.18852967"
|
||||
y="1007.5989" />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 4.5 KiB |
|
@ -1,129 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="45"
|
||||
height="45"
|
||||
id="svg3827"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.1 r9760"
|
||||
sodipodi:docname="new-script - Kopie (2).svg">
|
||||
<defs
|
||||
id="defs3829" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="39.376692"
|
||||
inkscape:cy="9.0006701"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1028"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata3832">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>T.Hofmeister</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1007.3622)">
|
||||
<rect
|
||||
style="color:#000000;fill:#00ffff;fill-opacity:0;fill-rule:nonzero;stroke:none;stroke-width:0.42527184;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3032"
|
||||
width="44.57473"
|
||||
height="44.57473"
|
||||
x="0.18852967"
|
||||
y="1007.5989" />
|
||||
<g
|
||||
id="layer1-7-7"
|
||||
transform="matrix(-0.23943965,0,0,0.3096188,117.90945,912.00498)"
|
||||
style="fill:#696969">
|
||||
<g
|
||||
id="g3257-4"
|
||||
transform="matrix(1.9175,0,0,1.9175,-607.19,-179.09)"
|
||||
style="fill:#696969">
|
||||
<path
|
||||
id="path3224-0"
|
||||
d="m 563.06,260.72 -1.25,0.16 -40.15,4.87 -1.66,0.22 0.38,1.62 c 3.78,16.93 -0.59,34.07 -2.88,51.57 l -0.22,1.84 1.81,-0.16 42,-3 1.25,-0.06 0.16,-1.25 c 2.13,-17.86 6.92,-36.12 0.94,-54.62 l -0.38,-1.19 z m -2.18,3.28 c 4.96,16.72 -1.56,33.17 -3.72,50.47 l -35.63,2.78 c 2.25,-16.14 7.03,-29.55 3.78,-46.19 L 560.88,264 z"
|
||||
style="fill:#696969;fill-rule:evenodd"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3237-9"
|
||||
d="m 531.39,275.61 23.34,-4.6"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3243-4"
|
||||
d="m 532.1,280.91 22.27,-2.83"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3247-8"
|
||||
d="m 531.92,285.86 22.89,-1.95"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3249-8"
|
||||
d="m 530.15,292.84 24.22,-2.12"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3251-2"
|
||||
d="m 529.45,297.53 22.98,-0.8"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3253-4"
|
||||
d="m 528.65,304.24 22.45,-2.56"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3255-5"
|
||||
d="m 527.5,309.37 22.81,-1.77"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="layer1-1"
|
||||
transform="matrix(0.85515704,0.72492349,-0.91920854,2.1402565,983.21735,-1213.0824)"
|
||||
style="fill:#a9a9a9;stroke:#000000">
|
||||
<path
|
||||
style="fill:#a9a9a9;fill-opacity:1;stroke:#000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="path2996"
|
||||
transform="translate(0,1036.3622)"
|
||||
d="m 3.4723994,8.5185577 3.0304576,-7.0710678 6.944799,0 -5.0191957,5.08233 4.1353117,0 -8.1127873,9.0913731 2.0834396,-7.1342026 z"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 4.7 KiB |
|
@ -1,674 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="45"
|
||||
height="45"
|
||||
id="svg3827"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.1 r9760"
|
||||
sodipodi:docname="load-script - Kopie.svg">
|
||||
<defs
|
||||
id="defs3829">
|
||||
<linearGradient
|
||||
x1="28.061"
|
||||
x2="28.061"
|
||||
y1="31.431"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="36.437"
|
||||
id="linearGradient6971">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#ddd"
|
||||
id="stop6967" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#fdfdfd"
|
||||
id="stop6969" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
x1="12.25"
|
||||
x2="7"
|
||||
y1="18.25"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="21.118"
|
||||
id="linearGradient6931">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#204a87"
|
||||
id="stop6927" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-opacity="0"
|
||||
stop-color="#204a87"
|
||||
id="stop6929" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
x1="14.752"
|
||||
x2="8.8953"
|
||||
y1="15.868"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="16.743"
|
||||
id="linearGradient6907">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#3465a4"
|
||||
id="stop6903" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-opacity="0"
|
||||
stop-color="#3465a4"
|
||||
id="stop6905" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
x1="33.431"
|
||||
x2="21.748"
|
||||
y1="31.965"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="11.781"
|
||||
id="linearGradient2553">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#fff"
|
||||
id="stop2557" />
|
||||
<stop
|
||||
offset=".5"
|
||||
stop-color="#e6e6e6"
|
||||
id="stop2561" />
|
||||
<stop
|
||||
offset=".75"
|
||||
stop-color="#fff"
|
||||
id="stop2563" />
|
||||
<stop
|
||||
offset=".84167"
|
||||
stop-color="#e1e1e1"
|
||||
id="stop2565" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#fff"
|
||||
id="stop2559" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="26.357"
|
||||
y1="11.319"
|
||||
gradientTransform="translate(0,5.125)"
|
||||
x2="23.688"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="23.688"
|
||||
id="linearGradient4272">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-opacity=".2549"
|
||||
stop-color="#fff"
|
||||
id="stop4276" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#fff"
|
||||
id="stop4278" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="47.621"
|
||||
y1="4.4331"
|
||||
gradientTransform="translate(0,5.125)"
|
||||
x2="44.096"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="12.378"
|
||||
id="linearGradient4260">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#fff"
|
||||
id="stop4256" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-opacity="0"
|
||||
stop-color="#fff"
|
||||
id="stop4258" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
r="20.936"
|
||||
gradientTransform="matrix(1.2862,0.7817,-0.71078,1.1696,-2.3543,0.24814)"
|
||||
cx="15.571"
|
||||
cy="2.9585"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient4250">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#e4e4e4"
|
||||
id="stop4246" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#d3d3d3"
|
||||
id="stop4248" />
|
||||
</radialGradient>
|
||||
<linearGradient
|
||||
y2="33.759"
|
||||
y1="37.206"
|
||||
gradientTransform="translate(0,5.125)"
|
||||
x2="12.222"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="12.277"
|
||||
id="linearGradient4242">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#eee"
|
||||
id="stop4238" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-opacity="0"
|
||||
stop-color="#eee"
|
||||
id="stop4240" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="40.944"
|
||||
y1="28.481"
|
||||
gradientTransform="translate(0,5.125)"
|
||||
x2="36.183"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="7.6046"
|
||||
id="linearGradient4234">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#bbb"
|
||||
id="stop4230" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#9f9f9f"
|
||||
id="stop4232" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="35.281"
|
||||
y1="35.281"
|
||||
gradientTransform="translate(0.79549,3.7992)"
|
||||
x2="24.688"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="7.0625"
|
||||
id="linearGradient4209">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#838383"
|
||||
id="stop4186" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-opacity="0"
|
||||
stop-color="#bbb"
|
||||
id="stop4188" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
r="15.645"
|
||||
gradientTransform="matrix(1,0,0,0.53672,0,16.873)"
|
||||
cx="24.837"
|
||||
cy="36.421"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient8668">
|
||||
<stop
|
||||
offset="0"
|
||||
id="stop8664" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-opacity="0"
|
||||
id="stop8666" />
|
||||
</radialGradient>
|
||||
<linearGradient
|
||||
y2="12.584"
|
||||
x2="12.624"
|
||||
gradientTransform="matrix(0.91411,0,0,0.91411,-3.8687,-2.7069)"
|
||||
y1="27.394"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="33.06"
|
||||
id="linearGradient1764">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#fff"
|
||||
id="stop2189" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-opacity="0"
|
||||
stop-color="#fff"
|
||||
id="stop2191" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
r="19.062"
|
||||
gradientTransform="matrix(-1.3145,-0.010063,-0.01023,1.3362,46.221,-4.9099)"
|
||||
cx="23.447"
|
||||
cy="6.4577"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient4997">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#fff"
|
||||
id="stop4993" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-opacity="0"
|
||||
stop-color="#fff"
|
||||
id="stop4995" />
|
||||
</radialGradient>
|
||||
<linearGradient
|
||||
y2="609.51"
|
||||
x2="302.86"
|
||||
gradientTransform="matrix(2.7744,0,0,1.9697,-1892.2,-872.89)"
|
||||
y1="366.65"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="302.86"
|
||||
id="linearGradient5027">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-opacity="0"
|
||||
id="stop5050" />
|
||||
<stop
|
||||
offset=".5"
|
||||
id="stop5056" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-opacity="0"
|
||||
id="stop5052" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
r="117.14"
|
||||
gradientTransform="matrix(2.7744,0,0,1.9697,-1891.6,-872.89)"
|
||||
cx="605.71"
|
||||
cy="486.65"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
xlink:href="#linearGradient5060"
|
||||
id="radialGradient5029" />
|
||||
<linearGradient
|
||||
id="linearGradient5060">
|
||||
<stop
|
||||
offset="0"
|
||||
id="stop5062" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-opacity="0"
|
||||
id="stop5064" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
r="117.14"
|
||||
gradientTransform="matrix(-2.7744,0,0,1.9697,112.76,-872.89)"
|
||||
cx="605.71"
|
||||
cy="486.65"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
xlink:href="#linearGradient5060"
|
||||
id="radialGradient5031" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient6971"
|
||||
id="linearGradient3239"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="28.061"
|
||||
y1="31.431"
|
||||
x2="28.061"
|
||||
y2="36.437"
|
||||
gradientTransform="translate(51.972416,1005.3761)" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#radialGradient8668"
|
||||
id="radialGradient3253"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.1302,0,0,-0.40769251,48.062716,1046.2254)"
|
||||
cx="24.837"
|
||||
cy="36.421"
|
||||
r="15.645" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5027"
|
||||
id="linearGradient3361"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.7744,0,0,1.9697,-1892.2,-872.89)"
|
||||
x1="302.86"
|
||||
y1="366.65"
|
||||
x2="302.86"
|
||||
y2="609.51" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5060"
|
||||
id="radialGradient3363"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.7744,0,0,1.9697,-1891.6,-872.89)"
|
||||
cx="605.71"
|
||||
cy="486.65"
|
||||
r="117.14" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5060"
|
||||
id="radialGradient3365"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-2.7744,0,0,1.9697,112.76,-872.89)"
|
||||
cx="605.71"
|
||||
cy="486.65"
|
||||
r="117.14" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4234"
|
||||
id="linearGradient3367"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(0,5.125)"
|
||||
x1="7.6046"
|
||||
y1="28.481"
|
||||
x2="36.183"
|
||||
y2="40.944" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#radialGradient4250"
|
||||
id="radialGradient3369"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.2862,0.7817,-0.71078,1.1696,-2.3543,0.24814)"
|
||||
cx="15.571"
|
||||
cy="2.9585"
|
||||
r="20.936" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4209"
|
||||
id="linearGradient3371"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(0.79549,3.7992)"
|
||||
x1="7.0625"
|
||||
y1="35.281"
|
||||
x2="24.688"
|
||||
y2="35.281" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4242"
|
||||
id="linearGradient3373"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(0,5.125)"
|
||||
x1="12.277"
|
||||
y1="37.206"
|
||||
x2="12.222"
|
||||
y2="33.759" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4272"
|
||||
id="linearGradient3375"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(0,5.125)"
|
||||
x1="23.688"
|
||||
y1="11.319"
|
||||
x2="23.688"
|
||||
y2="26.357" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4260"
|
||||
id="linearGradient3377"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(0,5.125)"
|
||||
x1="12.378"
|
||||
y1="4.4331"
|
||||
x2="44.096"
|
||||
y2="47.621" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2553"
|
||||
id="linearGradient3379"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="33.431"
|
||||
y1="31.965"
|
||||
x2="21.748"
|
||||
y2="11.781" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#radialGradient8668"
|
||||
id="radialGradient3381"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.1302,0,0,-0.40769251,48.062716,1046.2254)"
|
||||
cx="24.837"
|
||||
cy="36.421"
|
||||
r="15.645" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient6971"
|
||||
id="linearGradient3383"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(51.972416,1005.3761)"
|
||||
x1="28.061"
|
||||
y1="31.431"
|
||||
x2="28.061"
|
||||
y2="36.437" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="113.76169"
|
||||
inkscape:cy="-12.107928"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1028"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata3832">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>T.Hofmeister</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1007.3622)">
|
||||
<g
|
||||
id="g3385">
|
||||
<g
|
||||
transform="matrix(0.87964671,0,0,1,-44.027424,-2)"
|
||||
id="g3255">
|
||||
<g
|
||||
id="layer2"
|
||||
transform="translate(51.972416,1005.3761)">
|
||||
<g
|
||||
id="g5022"
|
||||
transform="matrix(0.024114,0,0,0.019292,45.49,41.752)">
|
||||
<rect
|
||||
id="rect4173"
|
||||
style="opacity:0.40206;color:#000000;fill:url(#linearGradient3361)"
|
||||
height="478.35999"
|
||||
width="1339.6"
|
||||
y="-150.7"
|
||||
x="-1559.3" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5058"
|
||||
style="opacity:0.40206;color:#000000;fill:url(#radialGradient3363)"
|
||||
d="m -219.62,-150.68 v 478.33 c 142.88,0.9 345.4,-107.17 345.4,-239.2 0,-132.02 -159.44,-239.13 -345.4,-239.13 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5018"
|
||||
style="opacity:0.40206;color:#000000;fill:url(#radialGradient3365)"
|
||||
d="m -1559.3,-150.68 v 478.33 c -142.8,0.9 -345.4,-107.17 -345.4,-239.2 0,-132.02 159.5,-239.13 345.4,-239.13 z" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;stroke:#535353;stroke-width:2;stroke-linecap:round;stroke-linejoin:round"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4196"
|
||||
d="m 11.286,13.088 c -0.625,0 -1.032,0.29 -1.282,0.843 L 3.5357,31.035 c 0,0 -0.25,0.671 -0.25,1.781 v 9.65 c 0,1.083 0.6578,1.625 1.6562,1.625 h 38.562 c 0.985,0 1.594,-0.718 1.594,-1.844 v -9.65 c 0,0 0.106,-0.77 -0.094,-1.312 l -6.718,-17.197 c -0.185,-0.512 -0.637,-0.988 -1.125,-1 h -25.875 z" />
|
||||
<path
|
||||
style="fill:url(#linearGradient3367);fill-rule:evenodd"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4170"
|
||||
d="m 3.2736,32.122 0.7646,-0.692 37.61,0.062 3.462,0.317 v 10.439 c 0,1.125 -0.607,1.843 -1.592,1.843 H 4.9352 c -0.998,0 -1.6614,-0.542 -1.6614,-1.624 V 32.122 z" />
|
||||
<path
|
||||
style="fill:url(#radialGradient3369);fill-rule:evenodd"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3093"
|
||||
d="m 3.5491,31.039 c -0.7143,1.465 -6e-4,2.393 1.0357,2.393 h 39 c 1.119,-0.024 1.845,-1.012 1.428,-2.143 l -6.714,-17.21 c -0.184,-0.512 -0.655,-0.988 -1.143,-1 h -25.857 c -0.625,0 -1.036,0.303 -1.286,0.857 L 3.5489,31.039 z" />
|
||||
<rect
|
||||
id="rect4174"
|
||||
style="color:#000000;fill:url(#linearGradient3371);fill-rule:evenodd"
|
||||
height="5.5625"
|
||||
width="17.625"
|
||||
y="36.299"
|
||||
x="7.8579998" />
|
||||
<path
|
||||
style="opacity:0.81142997;fill:url(#linearGradient3373);fill-rule:evenodd"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4194"
|
||||
d="M 7.858,41.862 V 37.85 c 1.8355,3.179 8.296,4.012 12.937,4.012 H 7.858 z" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-rule:evenodd"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4201"
|
||||
d="m 44.796,30.754 c 0.064,1.25 -0.414,2.316 -1.322,2.343 H 5.355 c -1.2889,0 -1.8674,-0.325 -2.0837,-0.868 0.0917,0.945 0.8258,1.65 2.084,1.65 h 38.119 c 1.076,-0.033 1.753,-1.424 1.352,-2.995 l -0.03,-0.13 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4211"
|
||||
style="opacity:0.69142995;color:#000000;fill:url(#linearGradient3375);fill-rule:evenodd"
|
||||
d="m 10.969,15.281 c -0.046,0.201 -0.188,0.387 -0.188,0.594 0,0.949 0.591,1.789 1.344,2.594 0.24,-0.154 0.365,-0.355 0.625,-0.5 -0.94,-0.816 -1.553,-1.717 -1.781,-2.688 z m 26.656,0 c -0.229,0.97 -0.842,1.873 -1.781,2.688 0.274,0.153 0.404,0.368 0.656,0.531 0.757,-0.807 1.312,-1.673 1.312,-2.625 0,-0.207 -0.141,-0.393 -0.187,-0.594 z m 2.187,8.438 c -0.613,4.04 -7.298,7.25 -15.531,7.25 -8.212,0 -14.86,-3.193 -15.5,-7.219 -0.0321,0.197 -0.1248,0.392 -0.1248,0.594 10e-5,4.318 6.9888,7.844 15.625,7.844 8.636,0 15.656,-3.526 15.657,-7.844 0,-0.213 -0.09,-0.418 -0.126,-0.625 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4224"
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:0.45762999;fill-rule:evenodd"
|
||||
d="m 8.5737,25.594 a 1.37005,1.0165371 0 1 1 -2.7401,0 1.37005,1.0165371 0 1 1 2.7401,0 z"
|
||||
transform="translate(0.088388,5.3018)" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4226"
|
||||
style="color:#000000;fill:#ffffff;fill-opacity:0.45762999;fill-rule:evenodd"
|
||||
d="m 8.5737,25.594 a 1.37005,1.0165371 0 1 1 -2.7401,0 1.37005,1.0165371 0 1 1 2.7401,0 z"
|
||||
transform="translate(33.967,5.2134)" />
|
||||
<path
|
||||
style="fill:none;stroke:url(#linearGradient3377);stroke-linecap:round;stroke-linejoin:round"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4252"
|
||||
d="m 11.643,13.541 c -0.602,0 -0.993,0.279 -1.234,0.812 L 3.994,30.944 c 0,0 -0.2406,0.646 -0.2406,1.715 v 9.29 c 0,1.354 0.444,1.627 1.5944,1.627 h 37.687 c 1.323,0 1.534,-0.317 1.534,-1.838 v -9.29 c 0,0 0.102,-0.742 -0.09,-1.264 l -6.593,-16.806 c -0.178,-0.492 -0.551,-0.826 -1.021,-0.837 h -25.222 z" />
|
||||
<path
|
||||
style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:square;stroke-opacity:0.42372999"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4282"
|
||||
d="m 40.5,36.554 v 5.021" />
|
||||
<path
|
||||
style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:square;stroke-opacity:0.42372999"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4284"
|
||||
d="m 38.5,36.614 v 5.021" />
|
||||
<path
|
||||
style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:square;stroke-opacity:0.42372999"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4286"
|
||||
d="m 36.5,36.614 v 5.021" />
|
||||
<path
|
||||
style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:square;stroke-opacity:0.42372999"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4288"
|
||||
d="m 34.5,36.614 v 5.021" />
|
||||
<path
|
||||
style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:square;stroke-opacity:0.42372999"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4290"
|
||||
d="m 32.5,36.614 v 5.021" />
|
||||
<path
|
||||
style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:square;stroke-opacity:0.42372999"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4292"
|
||||
d="m 30.5,36.614 v 5.021" />
|
||||
<path
|
||||
style="opacity:0.09714302;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:square"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4294"
|
||||
d="m 39.5,36.604 v 5.021" />
|
||||
<path
|
||||
style="opacity:0.09714302;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:square"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4296"
|
||||
d="m 37.5,36.664 v 5.021" />
|
||||
<path
|
||||
style="opacity:0.09714302;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:square"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4298"
|
||||
d="m 35.5,36.664 v 5.021" />
|
||||
<path
|
||||
style="opacity:0.09714302;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:square"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4300"
|
||||
d="m 33.5,36.664 v 5.021" />
|
||||
<path
|
||||
style="opacity:0.09714302;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:square"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4302"
|
||||
d="m 31.5,36.664 v 5.021" />
|
||||
<path
|
||||
style="opacity:0.43999999;fill:#ffffff;fill-rule:evenodd"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4572"
|
||||
d="m 7.875,36.312 v 5.532 H 20.438 L 8.219,41.5 7.875,36.312 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path2545"
|
||||
style="opacity:0.20571002;color:#000000;fill:url(#linearGradient3379);fill-rule:evenodd"
|
||||
d="m 39.875,19.562 a 14.875,6.6875 0 1 1 -29.75,0 14.875,6.6875 0 1 1 29.75,0 z"
|
||||
transform="matrix(1.0378,0,0,1.0607,-1.6329,3.0304)" />
|
||||
</g>
|
||||
<path
|
||||
d="m 93.815472,1031.3767 a 17.681979,6.3782852 0 1 0 -35.363958,0 17.681979,6.3782852 0 1 0 35.363958,0 z"
|
||||
style="opacity:0.14118;color:#000000;fill:url(#radialGradient3381);fill-rule:evenodd"
|
||||
id="path8660"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
x="56.535915"
|
||||
y="1035.6741"
|
||||
width="39.248001"
|
||||
height="12.278"
|
||||
ry="1.625"
|
||||
rx="1.625"
|
||||
display="block"
|
||||
style="color:#000000;fill:url(#linearGradient3383);stroke:#7d7d7d;stroke-linecap:round;display:block"
|
||||
id="rect6951" />
|
||||
<rect
|
||||
x="58.972416"
|
||||
y="1038.3761"
|
||||
width="16"
|
||||
height="7"
|
||||
ry="0"
|
||||
display="block"
|
||||
style="opacity:0.59658999;color:#000000;fill:#7d7d7d;display:block"
|
||||
id="rect6953" />
|
||||
<rect
|
||||
display="block"
|
||||
height="9"
|
||||
x="75.97242"
|
||||
y="1037.3761"
|
||||
width="1"
|
||||
style="color:#000000;display:block"
|
||||
id="rect6957" />
|
||||
</g>
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path1432"
|
||||
style="color:#000000;fill:#a9a9a9;stroke:#000000;stroke-width:0.48586071;display:block"
|
||||
d="m 6.087091,1019.0168 c -2.4783484,-13.3382 7.140839,-12.9964 16.821938,-0.5354 l 2.083662,-1.7011 5.154697,13.4755 -11.796108,-8.0529 2.148807,-1.7542 c -6.962373,-9.2534 -10.105498,-9.9089 -14.389461,-1.3256 z"
|
||||
display="block" />
|
||||
<rect
|
||||
y="1007.8514"
|
||||
x="0.20883489"
|
||||
height="44.57473"
|
||||
width="44.57473"
|
||||
id="rect3032"
|
||||
style="color:#000000;fill:#00ffff;fill-opacity:0;fill-rule:nonzero;stroke:none;stroke-width:0.42527184;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 23 KiB |
|
@ -1,550 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="45"
|
||||
height="45"
|
||||
id="svg3827"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.3.1 r9886"
|
||||
sodipodi:docname="start-script.svg">
|
||||
<defs
|
||||
id="defs3829">
|
||||
<radialGradient
|
||||
r="15.645"
|
||||
cy="36.421"
|
||||
cx="24.837"
|
||||
gradientTransform="matrix(1.1302,0,0,-0.40769251,48.062716,1046.2254)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient3253"
|
||||
xlink:href="#radialGradient8668"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
gradientTransform="translate(51.972416,1005.3761)"
|
||||
y2="36.437"
|
||||
x2="28.061"
|
||||
y1="31.431"
|
||||
x1="28.061"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient3239"
|
||||
xlink:href="#linearGradient6971"
|
||||
inkscape:collect="always" />
|
||||
<radialGradient
|
||||
id="radialGradient5031"
|
||||
xlink:href="#linearGradient5060"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cy="486.65"
|
||||
cx="605.71"
|
||||
gradientTransform="matrix(-2.7744,0,0,1.9697,112.76,-872.89)"
|
||||
r="117.14" />
|
||||
<linearGradient
|
||||
id="linearGradient5060">
|
||||
<stop
|
||||
id="stop5062"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop5064"
|
||||
stop-opacity="0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
id="radialGradient5029"
|
||||
xlink:href="#linearGradient5060"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cy="486.65"
|
||||
cx="605.71"
|
||||
gradientTransform="matrix(2.7744,0,0,1.9697,-1891.6,-872.89)"
|
||||
r="117.14" />
|
||||
<linearGradient
|
||||
id="linearGradient5027"
|
||||
x1="302.86"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y1="366.65"
|
||||
gradientTransform="matrix(2.7744,0,0,1.9697,-1892.2,-872.89)"
|
||||
x2="302.86"
|
||||
y2="609.51">
|
||||
<stop
|
||||
id="stop5050"
|
||||
stop-opacity="0"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop5056"
|
||||
offset=".5" />
|
||||
<stop
|
||||
id="stop5052"
|
||||
stop-opacity="0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
id="radialGradient4997"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cy="6.4577"
|
||||
cx="23.447"
|
||||
gradientTransform="matrix(-1.3145,-0.010063,-0.01023,1.3362,46.221,-4.9099)"
|
||||
r="19.062">
|
||||
<stop
|
||||
id="stop4993"
|
||||
stop-color="#fff"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop4995"
|
||||
stop-color="#fff"
|
||||
stop-opacity="0"
|
||||
offset="1" />
|
||||
</radialGradient>
|
||||
<linearGradient
|
||||
id="linearGradient1764"
|
||||
x1="33.06"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y1="27.394"
|
||||
gradientTransform="matrix(0.91411,0,0,0.91411,-3.8687,-2.7069)"
|
||||
x2="12.624"
|
||||
y2="12.584">
|
||||
<stop
|
||||
id="stop2189"
|
||||
stop-color="#fff"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop2191"
|
||||
stop-color="#fff"
|
||||
stop-opacity="0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
id="radialGradient8668"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cy="36.421"
|
||||
cx="24.837"
|
||||
gradientTransform="matrix(1,0,0,0.53672,0,16.873)"
|
||||
r="15.645">
|
||||
<stop
|
||||
id="stop8664"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop8666"
|
||||
stop-opacity="0"
|
||||
offset="1" />
|
||||
</radialGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4209"
|
||||
x1="7.0625"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="24.688"
|
||||
gradientTransform="translate(0.79549,3.7992)"
|
||||
y1="35.281"
|
||||
y2="35.281">
|
||||
<stop
|
||||
id="stop4186"
|
||||
stop-color="#838383"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop4188"
|
||||
stop-color="#bbb"
|
||||
stop-opacity="0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4234"
|
||||
x1="7.6046"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="36.183"
|
||||
gradientTransform="translate(0,5.125)"
|
||||
y1="28.481"
|
||||
y2="40.944">
|
||||
<stop
|
||||
id="stop4230"
|
||||
stop-color="#bbb"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop4232"
|
||||
stop-color="#9f9f9f"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4242"
|
||||
x1="12.277"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="12.222"
|
||||
gradientTransform="translate(0,5.125)"
|
||||
y1="37.206"
|
||||
y2="33.759">
|
||||
<stop
|
||||
id="stop4238"
|
||||
stop-color="#eee"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop4240"
|
||||
stop-color="#eee"
|
||||
stop-opacity="0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
id="radialGradient4250"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cy="2.9585"
|
||||
cx="15.571"
|
||||
gradientTransform="matrix(1.2862,0.7817,-0.71078,1.1696,-2.3543,0.24814)"
|
||||
r="20.936">
|
||||
<stop
|
||||
id="stop4246"
|
||||
stop-color="#e4e4e4"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop4248"
|
||||
stop-color="#d3d3d3"
|
||||
offset="1" />
|
||||
</radialGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4260"
|
||||
x1="12.378"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="44.096"
|
||||
gradientTransform="translate(0,5.125)"
|
||||
y1="4.4331"
|
||||
y2="47.621">
|
||||
<stop
|
||||
id="stop4256"
|
||||
stop-color="#fff"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop4258"
|
||||
stop-color="#fff"
|
||||
stop-opacity="0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4272"
|
||||
x1="23.688"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="23.688"
|
||||
gradientTransform="translate(0,5.125)"
|
||||
y1="11.319"
|
||||
y2="26.357">
|
||||
<stop
|
||||
id="stop4276"
|
||||
stop-color="#fff"
|
||||
stop-opacity=".2549"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop4278"
|
||||
stop-color="#fff"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient2553"
|
||||
y2="11.781"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y1="31.965"
|
||||
x2="21.748"
|
||||
x1="33.431">
|
||||
<stop
|
||||
id="stop2557"
|
||||
stop-color="#fff"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop2561"
|
||||
stop-color="#e6e6e6"
|
||||
offset=".5" />
|
||||
<stop
|
||||
id="stop2563"
|
||||
stop-color="#fff"
|
||||
offset=".75" />
|
||||
<stop
|
||||
id="stop2565"
|
||||
stop-color="#e1e1e1"
|
||||
offset=".84167" />
|
||||
<stop
|
||||
id="stop2559"
|
||||
stop-color="#fff"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient6907"
|
||||
y2="16.743"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y1="15.868"
|
||||
x2="8.8953"
|
||||
x1="14.752">
|
||||
<stop
|
||||
id="stop6903"
|
||||
stop-color="#3465a4"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop6905"
|
||||
stop-color="#3465a4"
|
||||
stop-opacity="0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient6931"
|
||||
y2="21.118"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y1="18.25"
|
||||
x2="7"
|
||||
x1="12.25">
|
||||
<stop
|
||||
id="stop6927"
|
||||
stop-color="#204a87"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop6929"
|
||||
stop-color="#204a87"
|
||||
stop-opacity="0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient6971"
|
||||
y2="36.437"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y1="31.431"
|
||||
x2="28.061"
|
||||
x1="28.061">
|
||||
<stop
|
||||
id="stop6967"
|
||||
stop-color="#ddd"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop6969"
|
||||
stop-color="#fdfdfd"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5027"
|
||||
id="linearGradient3248"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.7744,0,0,1.9697,-1892.2,-872.89)"
|
||||
x1="302.86"
|
||||
y1="366.65"
|
||||
x2="302.86"
|
||||
y2="609.51" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5060"
|
||||
id="radialGradient3250"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.7744,0,0,1.9697,-1891.6,-872.89)"
|
||||
cx="605.71"
|
||||
cy="486.65"
|
||||
r="117.14" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5060"
|
||||
id="radialGradient3252"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-2.7744,0,0,1.9697,112.76,-872.89)"
|
||||
cx="605.71"
|
||||
cy="486.65"
|
||||
r="117.14" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4234"
|
||||
id="linearGradient3254"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(0,5.125)"
|
||||
x1="7.6046"
|
||||
y1="28.481"
|
||||
x2="36.183"
|
||||
y2="40.944" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#radialGradient4250"
|
||||
id="radialGradient3256"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.2862,0.7817,-0.71078,1.1696,-2.3543,0.24814)"
|
||||
cx="15.571"
|
||||
cy="2.9585"
|
||||
r="20.936" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4209"
|
||||
id="linearGradient3258"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(0.79549,3.7992)"
|
||||
x1="7.0625"
|
||||
y1="35.281"
|
||||
x2="24.688"
|
||||
y2="35.281" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4242"
|
||||
id="linearGradient3260"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(0,5.125)"
|
||||
x1="12.277"
|
||||
y1="37.206"
|
||||
x2="12.222"
|
||||
y2="33.759" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4272"
|
||||
id="linearGradient3262"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(0,5.125)"
|
||||
x1="23.688"
|
||||
y1="11.319"
|
||||
x2="23.688"
|
||||
y2="26.357" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4260"
|
||||
id="linearGradient3264"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(0,5.125)"
|
||||
x1="12.378"
|
||||
y1="4.4331"
|
||||
x2="44.096"
|
||||
y2="47.621" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2553"
|
||||
id="linearGradient3266"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="33.431"
|
||||
y1="31.965"
|
||||
x2="21.748"
|
||||
y2="11.781" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#radialGradient8668"
|
||||
id="radialGradient3268"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.1302,0,0,-0.40769251,48.062716,1046.2254)"
|
||||
cx="24.837"
|
||||
cy="36.421"
|
||||
r="15.645" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient6971"
|
||||
id="linearGradient3270"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(51.972416,1005.3761)"
|
||||
x1="28.061"
|
||||
y1="31.431"
|
||||
x2="28.061"
|
||||
y2="36.437" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="22.4"
|
||||
inkscape:cx="44.04179"
|
||||
inkscape:cy="22.346221"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="997"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="21"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata3832">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Maximillian Merlin</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1007.3622)">
|
||||
<g
|
||||
id="layer1-7"
|
||||
transform="matrix(-0.25019951,0,0,0.28877175,123.44112,917.40972)"
|
||||
style="fill:#696969">
|
||||
<g
|
||||
id="g3257"
|
||||
transform="matrix(1.9175,0,0,1.9175,-607.19,-179.09)"
|
||||
style="fill:#696969">
|
||||
<path
|
||||
id="path3224"
|
||||
d="m 563.06,260.72 -1.25,0.16 -40.15,4.87 -1.66,0.22 0.38,1.62 c 3.78,16.93 -0.59,34.07 -2.88,51.57 l -0.22,1.84 1.81,-0.16 42,-3 1.25,-0.06 0.16,-1.25 c 2.13,-17.86 6.92,-36.12 0.94,-54.62 l -0.38,-1.19 z m -2.18,3.28 c 4.96,16.72 -1.56,33.17 -3.72,50.47 l -35.63,2.78 c 2.25,-16.14 7.03,-29.55 3.78,-46.19 L 560.88,264 z"
|
||||
style="fill:#696969;fill-rule:evenodd"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3237"
|
||||
d="m 531.39,275.61 23.34,-4.6"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3243"
|
||||
d="m 532.1,280.91 22.27,-2.83"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3247"
|
||||
d="m 531.92,285.86 22.89,-1.95"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3249"
|
||||
d="m 530.15,292.84 24.22,-2.12"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3251"
|
||||
d="m 529.45,297.53 22.98,-0.8"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3253"
|
||||
d="m 528.65,304.24 22.45,-2.56"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3255"
|
||||
d="m 527.5,309.37 22.81,-1.77"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<rect
|
||||
style="color:#000000;fill:#00ffff;fill-opacity:0;fill-rule:nonzero;stroke:none;stroke-width:0.42527184;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3032"
|
||||
width="44.57473"
|
||||
height="44.57473"
|
||||
x="0.18852967"
|
||||
y="1007.5989" />
|
||||
<rect
|
||||
style="color:#000000;fill:#00ffff;fill-opacity:0;fill-rule:nonzero;stroke:none;stroke-width:0.42527184;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3032-4"
|
||||
width="44.57473"
|
||||
height="44.57473"
|
||||
x="84.498352"
|
||||
y="1050.0748" />
|
||||
<g
|
||||
id="run-arrow"
|
||||
transform="translate(-46.607143,-3.5714285)"
|
||||
inkscape:label="#run-arrow">
|
||||
<path
|
||||
d="m 75.506508,1023.3478 1.372845,5.4631 -14.094975,-1.152 2.35e-4,7.2772 14.094975,-1.152 -1.372845,5.1249 13.761293,-7.6113 -13.761293,-7.9499 z"
|
||||
id="arrow-rect"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#d3d3d3;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.77974033;stroke-linecap:round;stroke-linejoin:round" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 16 KiB |
|
@ -1,163 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="45"
|
||||
height="45"
|
||||
id="svg3827"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.1 r9760"
|
||||
sodipodi:docname="stop-script.svg">
|
||||
<defs
|
||||
id="defs3829" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="15.598703"
|
||||
inkscape:cy="22.861751"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1028"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata3832">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Maximillian Merlin</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1007.3622)">
|
||||
<g
|
||||
id="layer1-7"
|
||||
transform="matrix(-0.25019951,0,0,0.28877175,123.44112,917.40972)"
|
||||
style="fill:#696969">
|
||||
<g
|
||||
id="g3257"
|
||||
transform="matrix(1.9175,0,0,1.9175,-607.19,-179.09)"
|
||||
style="fill:#696969">
|
||||
<path
|
||||
id="path3224"
|
||||
d="m 563.06,260.72 -1.25,0.16 -40.15,4.87 -1.66,0.22 0.38,1.62 c 3.78,16.93 -0.59,34.07 -2.88,51.57 l -0.22,1.84 1.81,-0.16 42,-3 1.25,-0.06 0.16,-1.25 c 2.13,-17.86 6.92,-36.12 0.94,-54.62 l -0.38,-1.19 z m -2.18,3.28 c 4.96,16.72 -1.56,33.17 -3.72,50.47 l -35.63,2.78 c 2.25,-16.14 7.03,-29.55 3.78,-46.19 L 560.88,264 z"
|
||||
style="fill:#696969;fill-rule:evenodd"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3237"
|
||||
d="m 531.39,275.61 23.34,-4.6"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3243"
|
||||
d="m 532.1,280.91 22.27,-2.83"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3247"
|
||||
d="m 531.92,285.86 22.89,-1.95"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3249"
|
||||
d="m 530.15,292.84 24.22,-2.12"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3251"
|
||||
d="m 529.45,297.53 22.98,-0.8"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3253"
|
||||
d="m 528.65,304.24 22.45,-2.56"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3255"
|
||||
d="m 527.5,309.37 22.81,-1.77"
|
||||
style="fill:#696969;stroke:#000000;stroke-width:1px"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<rect
|
||||
style="color:#000000;fill:#00ffff;fill-opacity:0;fill-rule:nonzero;stroke:none;stroke-width:0.42527184;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="rect3032"
|
||||
width="44.57473"
|
||||
height="44.57473"
|
||||
x="0.18852967"
|
||||
y="1007.5989" />
|
||||
<g
|
||||
id="stop"
|
||||
transform="matrix(0.08804464,0,0,0.0856179,29.060719,1033.5397)">
|
||||
<g
|
||||
id="g3004">
|
||||
<path
|
||||
d="M 0,-150 H 62.132 L 150,-62.132 V 62.128 L 62.132,150 H -62.128 L -149,62.132 V -62.128 L -61.132,-150 H 1 0 z"
|
||||
id="stop_octagon"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#e81108" />
|
||||
</g>
|
||||
<g
|
||||
id="g3007"
|
||||
transform="scale(0.95,0.95)">
|
||||
<path
|
||||
d="M 0,-142.5 H 59.025 L 142.5,-59.025 V 59.025 L 59.025,142.5 H -59.025 L -141.549,59.025 V -59.025 L -58.074,-142.5 H 0.951 0.001 z"
|
||||
id="stop_octagon_1_"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#ffffff;stroke-width:5" />
|
||||
</g>
|
||||
<g
|
||||
id="g3010"
|
||||
transform="scale(1,1.45)">
|
||||
<g
|
||||
id="g3012"
|
||||
style="fill:#ffffff;enable-background:new">
|
||||
<path
|
||||
id="path3014"
|
||||
d="m -124.2,12.152 8.489,-0.742 c 0.401,3.402 1.337,6.192 2.806,8.373 1.469,2.18 3.75,3.943 6.842,5.288 3.092,1.345 6.571,2.018 10.437,2.018 3.433,0 6.463,-0.51 9.092,-1.53 2.628,-1.021 4.584,-2.42 5.868,-4.198 1.283,-1.778 1.925,-3.718 1.925,-5.821 0,-2.134 -0.619,-3.997 -1.855,-5.59 -1.237,-1.592 -3.278,-2.93 -6.123,-4.013 -1.825,-0.711 -5.861,-1.816 -12.107,-3.317 -6.247,-1.5 -10.623,-2.914 -13.127,-4.244 -3.247,-1.7 -5.667,-3.811 -7.26,-6.332 -1.593,-2.52 -2.389,-5.342 -2.389,-8.465 0,-3.433 0.974,-6.641 2.922,-9.625 1.948,-2.984 4.793,-5.249 8.535,-6.796 3.741,-1.546 7.901,-2.319 12.478,-2.319 5.04,0 9.486,0.812 13.336,2.435 3.85,1.623 6.811,4.012 8.883,7.167 2.071,3.154 3.185,6.726 3.34,10.715 l -8.628,0.65 c -0.464,-4.298 -2.034,-7.545 -4.708,-9.741 -2.675,-2.195 -6.626,-3.293 -11.852,-3.293 -5.443,0 -9.409,0.997 -11.898,2.992 -2.489,1.995 -3.734,4.4 -3.734,7.213 0,2.443 0.881,4.453 2.644,6.03 1.731,1.577 6.254,3.194 13.568,4.847 7.313,1.655 12.331,3.101 15.053,4.337 3.958,1.825 6.88,4.136 8.767,6.935 1.886,2.799 2.83,6.023 2.83,9.672 0,3.618 -1.037,7.028 -3.108,10.228 -2.072,3.201 -5.049,5.69 -8.93,7.468 -3.881,1.778 -8.25,2.667 -13.104,2.667 -6.154,0 -11.311,-0.897 -15.47,-2.691 -4.159,-1.793 -7.422,-4.492 -9.788,-8.094 -2.37,-3.604 -3.62,-7.678 -3.74,-12.224 z"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3016"
|
||||
d="m -40.473,34 v -59.978 h -22.405 v -8.025 h 53.901 v 8.025 H -31.475 V 34 h -8.998 z"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3018"
|
||||
d="m -4.198,0.88 c 0,-11.287 3.03,-20.124 9.092,-26.51 6.061,-6.385 13.885,-9.579 23.472,-9.579 6.277,0 11.937,1.5 16.978,4.5 5.04,3 8.883,7.182 11.527,12.547 2.644,5.366 3.966,11.45 3.966,18.253 0,6.896 -1.392,13.066 -4.175,18.508 -2.783,5.443 -6.726,9.564 -11.829,12.362 -5.103,2.799 -10.607,4.198 -16.514,4.198 -6.401,0 -12.123,-1.546 -17.163,-4.639 C 6.115,27.428 2.296,23.207 -0.302,17.856 -2.899,12.508 -4.198,6.848 -4.198,0.88 z m 9.277,0.139 c 0,8.195 2.203,14.651 6.61,19.366 4.407,4.716 9.934,7.074 16.583,7.074 6.772,0 12.346,-2.381 16.722,-7.143 4.376,-4.762 6.564,-11.519 6.564,-20.271 0,-5.535 -0.936,-10.367 -2.807,-14.496 -1.871,-4.129 -4.608,-7.329 -8.21,-9.602 -3.603,-2.273 -7.646,-3.41 -12.13,-3.41 -6.371,0 -11.852,2.188 -16.444,6.564 -4.592,4.377 -6.888,11.682 -6.888,21.918 z"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path3020"
|
||||
d="m 72.433,34 v -68.003 h 25.652 c 4.515,0 7.962,0.217 10.344,0.65 3.34,0.557 6.138,1.616 8.396,3.178 2.257,1.562 4.074,3.75 5.45,6.564 1.376,2.815 2.064,5.907 2.064,9.277 0,5.783 -1.84,10.677 -5.52,14.681 -3.681,4.005 -10.329,6.007 -19.946,6.007 H 81.431 V 34 h -8.999 z m 8.999,-35.672 h 17.581 c 5.813,0 9.942,-1.082 12.385,-3.247 2.442,-2.164 3.665,-5.21 3.665,-9.138 0,-2.845 -0.719,-5.28 -2.157,-7.306 -1.438,-2.025 -3.333,-3.363 -5.682,-4.012 -1.516,-0.401 -4.314,-0.603 -8.396,-0.603 H 81.436 v 24.306 z"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 8 KiB |
|
@ -198,7 +198,7 @@ Item {
|
|||
}
|
||||
StatText {
|
||||
visible: root.expanded;
|
||||
text: "Audio Out Mic: " + root.audioMicOutboundPPS + " pps, " +
|
||||
text: "Audio Out Mic: " + root.audioOutboundPPS + " pps, " +
|
||||
"Silent: " + root.audioSilentOutboundPPS + " pps";
|
||||
}
|
||||
StatText {
|
||||
|
|
|
@ -740,23 +740,24 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
}
|
||||
});
|
||||
|
||||
auto& audioScriptingInterface = AudioScriptingInterface::getInstance();
|
||||
auto audioScriptingInterface = DependencyManager::set<AudioScriptingInterface>();
|
||||
connect(audioThread, &QThread::started, audioIO.data(), &AudioClient::start);
|
||||
connect(audioIO.data(), &AudioClient::destroyed, audioThread, &QThread::quit);
|
||||
connect(audioThread, &QThread::finished, audioThread, &QThread::deleteLater);
|
||||
connect(audioIO.data(), &AudioClient::muteToggled, this, &Application::audioMuteToggled);
|
||||
connect(audioIO.data(), &AudioClient::mutedByMixer, &audioScriptingInterface, &AudioScriptingInterface::mutedByMixer);
|
||||
connect(audioIO.data(), &AudioClient::receivedFirstPacket, &audioScriptingInterface, &AudioScriptingInterface::receivedFirstPacket);
|
||||
connect(audioIO.data(), &AudioClient::disconnected, &audioScriptingInterface, &AudioScriptingInterface::disconnected);
|
||||
connect(audioIO.data(), &AudioClient::mutedByMixer, audioScriptingInterface.data(), &AudioScriptingInterface::mutedByMixer);
|
||||
connect(audioIO.data(), &AudioClient::receivedFirstPacket, audioScriptingInterface.data(), &AudioScriptingInterface::receivedFirstPacket);
|
||||
connect(audioIO.data(), &AudioClient::disconnected, audioScriptingInterface.data(), &AudioScriptingInterface::disconnected);
|
||||
connect(audioIO.data(), &AudioClient::muteEnvironmentRequested, [](glm::vec3 position, float radius) {
|
||||
auto audioClient = DependencyManager::get<AudioClient>();
|
||||
auto audioScriptingInterface = DependencyManager::get<AudioScriptingInterface>();
|
||||
auto myAvatarPosition = DependencyManager::get<AvatarManager>()->getMyAvatar()->getPosition();
|
||||
float distance = glm::distance(myAvatarPosition, position);
|
||||
bool shouldMute = !audioClient->isMuted() && (distance < radius);
|
||||
|
||||
if (shouldMute) {
|
||||
audioClient->toggleMute();
|
||||
AudioScriptingInterface::getInstance().environmentMuted();
|
||||
audioScriptingInterface->environmentMuted();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1181,10 +1182,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
|
||||
// set the local loopback interface for local sounds
|
||||
AudioInjector::setLocalAudioInterface(audioIO.data());
|
||||
AudioScriptingInterface::getInstance().setLocalAudioInterface(audioIO.data());
|
||||
connect(audioIO.data(), &AudioClient::noiseGateOpened, &AudioScriptingInterface::getInstance(), &AudioScriptingInterface::noiseGateOpened);
|
||||
connect(audioIO.data(), &AudioClient::noiseGateClosed, &AudioScriptingInterface::getInstance(), &AudioScriptingInterface::noiseGateClosed);
|
||||
connect(audioIO.data(), &AudioClient::inputReceived, &AudioScriptingInterface::getInstance(), &AudioScriptingInterface::inputReceived);
|
||||
audioScriptingInterface->setLocalAudioInterface(audioIO.data());
|
||||
connect(audioIO.data(), &AudioClient::noiseGateOpened, audioScriptingInterface.data(), &AudioScriptingInterface::noiseGateOpened);
|
||||
connect(audioIO.data(), &AudioClient::noiseGateClosed, audioScriptingInterface.data(), &AudioScriptingInterface::noiseGateClosed);
|
||||
connect(audioIO.data(), &AudioClient::inputReceived, audioScriptingInterface.data(), &AudioScriptingInterface::inputReceived);
|
||||
|
||||
|
||||
this->installEventFilter(this);
|
||||
|
@ -1949,7 +1950,7 @@ void Application::initializeUi() {
|
|||
// For some reason there is already an "Application" object in the QML context,
|
||||
// though I can't find it. Hence, "ApplicationInterface"
|
||||
rootContext->setContextProperty("ApplicationInterface", this);
|
||||
rootContext->setContextProperty("Audio", &AudioScriptingInterface::getInstance());
|
||||
rootContext->setContextProperty("Audio", DependencyManager::get<AudioScriptingInterface>().data());
|
||||
rootContext->setContextProperty("AudioStats", DependencyManager::get<AudioClient>()->getStats().data());
|
||||
rootContext->setContextProperty("AudioScope", DependencyManager::get<AudioScope>().data());
|
||||
|
||||
|
@ -2745,8 +2746,6 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
case Qt::Key_S:
|
||||
if (isShifted && isMeta && !isOption) {
|
||||
Menu::getInstance()->triggerOption(MenuOption::SuppressShortTimings);
|
||||
} else if (isOption && !isShifted && !isMeta) {
|
||||
Menu::getInstance()->triggerOption(MenuOption::ScriptEditor);
|
||||
} else if (!isOption && !isShifted && isMeta) {
|
||||
takeSnapshot(true);
|
||||
}
|
||||
|
|
|
@ -117,11 +117,6 @@ Menu::Menu() {
|
|||
scriptEngines.data(), SLOT(reloadAllScripts()),
|
||||
QAction::NoRole, UNSPECIFIED_POSITION, "Advanced");
|
||||
|
||||
// Edit > Scripts Editor... [advanced]
|
||||
addActionToQMenuAndActionHash(editMenu, MenuOption::ScriptEditor, Qt::ALT | Qt::Key_S,
|
||||
dialogsManager.data(), SLOT(showScriptEditor()),
|
||||
QAction::NoRole, UNSPECIFIED_POSITION, "Advanced");
|
||||
|
||||
// Edit > Console... [advanced]
|
||||
addActionToQMenuAndActionHash(editMenu, MenuOption::Console, Qt::CTRL | Qt::ALT | Qt::Key_J,
|
||||
DependencyManager::get<StandAloneJSConsole>().data(),
|
||||
|
|
|
@ -166,7 +166,6 @@ namespace MenuOption {
|
|||
const QString RunningScripts = "Running Scripts...";
|
||||
const QString RunClientScriptTests = "Run Client Script Tests";
|
||||
const QString RunTimingTests = "Run Timing Tests";
|
||||
const QString ScriptEditor = "Script Editor...";
|
||||
const QString ScriptedMotorControl = "Enable Scripted Motor Control";
|
||||
const QString SendWrongDSConnectVersion = "Send wrong DS connect version";
|
||||
const QString SendWrongProtocolVersion = "Send wrong protocol version";
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include "LoginDialog.h"
|
||||
#include "OctreeStatsDialog.h"
|
||||
#include "PreferencesDialog.h"
|
||||
#include "ScriptEditorWindow.h"
|
||||
#include "UpdateDialog.h"
|
||||
|
||||
template<typename T>
|
||||
|
@ -120,12 +119,6 @@ void DialogsManager::hmdToolsClosed() {
|
|||
}
|
||||
}
|
||||
|
||||
void DialogsManager::showScriptEditor() {
|
||||
maybeCreateDialog(_scriptEditor);
|
||||
_scriptEditor->show();
|
||||
_scriptEditor->raise();
|
||||
}
|
||||
|
||||
void DialogsManager::showTestingResults() {
|
||||
if (!_testingDialog) {
|
||||
_testingDialog = new TestingDialog(qApp->getWindow());
|
||||
|
|
|
@ -50,7 +50,6 @@ public slots:
|
|||
void octreeStatsDetails();
|
||||
void lodTools();
|
||||
void hmdTools(bool showTools);
|
||||
void showScriptEditor();
|
||||
void showDomainConnectionDialog();
|
||||
void showTestingResults();
|
||||
|
||||
|
@ -78,7 +77,6 @@ private:
|
|||
QPointer<HMDToolsDialog> _hmdToolsDialog;
|
||||
QPointer<LodToolsDialog> _lodToolsDialog;
|
||||
QPointer<OctreeStatsDialog> _octreeStatsDialog;
|
||||
QPointer<ScriptEditorWindow> _scriptEditor;
|
||||
QPointer<TestingDialog> _testingDialog;
|
||||
QPointer<DomainConnectionDialog> _domainConnectionDialog;
|
||||
};
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
//
|
||||
// ScriptEditBox.cpp
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Thijs Wenker on 4/30/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "ScriptEditBox.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QTextBlock>
|
||||
|
||||
#include "ScriptLineNumberArea.h"
|
||||
|
||||
ScriptEditBox::ScriptEditBox(QWidget* parent) :
|
||||
QPlainTextEdit(parent)
|
||||
{
|
||||
_scriptLineNumberArea = new ScriptLineNumberArea(this);
|
||||
|
||||
connect(this, &ScriptEditBox::blockCountChanged, this, &ScriptEditBox::updateLineNumberAreaWidth);
|
||||
connect(this, &ScriptEditBox::updateRequest, this, &ScriptEditBox::updateLineNumberArea);
|
||||
connect(this, &ScriptEditBox::cursorPositionChanged, this, &ScriptEditBox::highlightCurrentLine);
|
||||
|
||||
updateLineNumberAreaWidth(0);
|
||||
highlightCurrentLine();
|
||||
}
|
||||
|
||||
int ScriptEditBox::lineNumberAreaWidth() {
|
||||
int digits = 1;
|
||||
const int SPACER_PIXELS = 3;
|
||||
const int BASE_TEN = 10;
|
||||
int max = qMax(1, blockCount());
|
||||
while (max >= BASE_TEN) {
|
||||
max /= BASE_TEN;
|
||||
digits++;
|
||||
}
|
||||
return SPACER_PIXELS + fontMetrics().width(QLatin1Char('H')) * digits;
|
||||
}
|
||||
|
||||
void ScriptEditBox::updateLineNumberAreaWidth(int blockCount) {
|
||||
setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
|
||||
}
|
||||
|
||||
void ScriptEditBox::updateLineNumberArea(const QRect& rect, int deltaY) {
|
||||
if (deltaY) {
|
||||
_scriptLineNumberArea->scroll(0, deltaY);
|
||||
} else {
|
||||
_scriptLineNumberArea->update(0, rect.y(), _scriptLineNumberArea->width(), rect.height());
|
||||
}
|
||||
|
||||
if (rect.contains(viewport()->rect())) {
|
||||
updateLineNumberAreaWidth(0);
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEditBox::resizeEvent(QResizeEvent* event) {
|
||||
QPlainTextEdit::resizeEvent(event);
|
||||
|
||||
QRect localContentsRect = contentsRect();
|
||||
_scriptLineNumberArea->setGeometry(QRect(localContentsRect.left(), localContentsRect.top(), lineNumberAreaWidth(),
|
||||
localContentsRect.height()));
|
||||
}
|
||||
|
||||
void ScriptEditBox::highlightCurrentLine() {
|
||||
QList<QTextEdit::ExtraSelection> extraSelections;
|
||||
|
||||
if (!isReadOnly()) {
|
||||
QTextEdit::ExtraSelection selection;
|
||||
|
||||
QColor lineColor = QColor(Qt::gray).lighter();
|
||||
|
||||
selection.format.setBackground(lineColor);
|
||||
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
|
||||
selection.cursor = textCursor();
|
||||
selection.cursor.clearSelection();
|
||||
extraSelections.append(selection);
|
||||
}
|
||||
|
||||
setExtraSelections(extraSelections);
|
||||
}
|
||||
|
||||
void ScriptEditBox::lineNumberAreaPaintEvent(QPaintEvent* event)
|
||||
{
|
||||
QPainter painter(_scriptLineNumberArea);
|
||||
painter.fillRect(event->rect(), Qt::lightGray);
|
||||
QTextBlock block = firstVisibleBlock();
|
||||
int blockNumber = block.blockNumber();
|
||||
int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();
|
||||
int bottom = top + (int) blockBoundingRect(block).height();
|
||||
|
||||
while (block.isValid() && top <= event->rect().bottom()) {
|
||||
if (block.isVisible() && bottom >= event->rect().top()) {
|
||||
QFont font = painter.font();
|
||||
font.setBold(this->textCursor().blockNumber() == block.blockNumber());
|
||||
painter.setFont(font);
|
||||
QString number = QString::number(blockNumber + 1);
|
||||
painter.setPen(Qt::black);
|
||||
painter.drawText(0, top, _scriptLineNumberArea->width(), fontMetrics().height(),
|
||||
Qt::AlignRight, number);
|
||||
}
|
||||
|
||||
block = block.next();
|
||||
top = bottom;
|
||||
bottom = top + (int) blockBoundingRect(block).height();
|
||||
blockNumber++;
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
//
|
||||
// ScriptEditBox.h
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Thijs Wenker on 4/30/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_ScriptEditBox_h
|
||||
#define hifi_ScriptEditBox_h
|
||||
|
||||
#include <QPlainTextEdit>
|
||||
|
||||
class ScriptEditBox : public QPlainTextEdit {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ScriptEditBox(QWidget* parent = NULL);
|
||||
|
||||
void lineNumberAreaPaintEvent(QPaintEvent* event);
|
||||
int lineNumberAreaWidth();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
|
||||
private slots:
|
||||
void updateLineNumberAreaWidth(int blockCount);
|
||||
void highlightCurrentLine();
|
||||
void updateLineNumberArea(const QRect& rect, int deltaY);
|
||||
|
||||
private:
|
||||
QWidget* _scriptLineNumberArea;
|
||||
};
|
||||
|
||||
#endif // hifi_ScriptEditBox_h
|
|
@ -1,256 +0,0 @@
|
|||
//
|
||||
// ScriptEditorWidget.cpp
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Thijs Wenker on 4/14/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "ui_scriptEditorWidget.h"
|
||||
#include "ScriptEditorWidget.h"
|
||||
#include "ScriptEditorWindow.h"
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QFileDialog>
|
||||
#include <QFrame>
|
||||
#include <QLayoutItem>
|
||||
#include <QMainWindow>
|
||||
#include <QMessageBox>
|
||||
#include <QPalette>
|
||||
#include <QScrollBar>
|
||||
#include <QSizePolicy>
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
|
||||
#include <ScriptEngines.h>
|
||||
#include <NetworkAccessManager.h>
|
||||
#include <OffscreenUi.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "ScriptHighlighting.h"
|
||||
|
||||
ScriptEditorWidget::ScriptEditorWidget() :
|
||||
_scriptEditorWidgetUI(new Ui::ScriptEditorWidget),
|
||||
_scriptEngine(NULL),
|
||||
_isRestarting(false),
|
||||
_isReloading(false)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
_scriptEditorWidgetUI->setupUi(this);
|
||||
|
||||
connect(_scriptEditorWidgetUI->scriptEdit->document(), &QTextDocument::modificationChanged, this,
|
||||
&ScriptEditorWidget::scriptModified);
|
||||
connect(_scriptEditorWidgetUI->scriptEdit->document(), &QTextDocument::contentsChanged, this,
|
||||
&ScriptEditorWidget::onScriptModified);
|
||||
|
||||
// remove the title bar (see the Qt docs on setTitleBarWidget)
|
||||
setTitleBarWidget(new QWidget());
|
||||
QFontMetrics fm(_scriptEditorWidgetUI->scriptEdit->font());
|
||||
_scriptEditorWidgetUI->scriptEdit->setTabStopWidth(fm.width('0') * 4);
|
||||
// We create a new ScriptHighligting QObject and provide it with a parent so this is NOT a memory leak.
|
||||
new ScriptHighlighting(_scriptEditorWidgetUI->scriptEdit->document());
|
||||
QTimer::singleShot(0, _scriptEditorWidgetUI->scriptEdit, SLOT(setFocus()));
|
||||
|
||||
_console = new JSConsole(this);
|
||||
_console->setFixedHeight(CONSOLE_HEIGHT);
|
||||
_scriptEditorWidgetUI->verticalLayout->addWidget(_console);
|
||||
connect(_scriptEditorWidgetUI->clearButton, &QPushButton::clicked, _console, &JSConsole::clear);
|
||||
}
|
||||
|
||||
ScriptEditorWidget::~ScriptEditorWidget() {
|
||||
delete _scriptEditorWidgetUI;
|
||||
delete _console;
|
||||
}
|
||||
|
||||
void ScriptEditorWidget::onScriptModified() {
|
||||
if(_scriptEditorWidgetUI->onTheFlyCheckBox->isChecked() && isModified() && isRunning() && !_isReloading) {
|
||||
_isRestarting = true;
|
||||
setRunning(false);
|
||||
// Script is restarted once current script instance finishes.
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEditorWidget::onScriptFinished(const QString& scriptPath) {
|
||||
_scriptEngine = NULL;
|
||||
_console->setScriptEngine(NULL);
|
||||
if (_isRestarting) {
|
||||
_isRestarting = false;
|
||||
setRunning(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool ScriptEditorWidget::isModified() {
|
||||
return _scriptEditorWidgetUI->scriptEdit->document()->isModified();
|
||||
}
|
||||
|
||||
bool ScriptEditorWidget::isRunning() {
|
||||
return (_scriptEngine != NULL) ? _scriptEngine->isRunning() : false;
|
||||
}
|
||||
|
||||
bool ScriptEditorWidget::setRunning(bool run) {
|
||||
if (run && isModified() && !save()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_scriptEngine != NULL) {
|
||||
disconnect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged);
|
||||
disconnect(_scriptEngine, &ScriptEngine::update, this, &ScriptEditorWidget::onScriptModified);
|
||||
disconnect(_scriptEngine, &ScriptEngine::finished, this, &ScriptEditorWidget::onScriptFinished);
|
||||
}
|
||||
|
||||
auto scriptEngines = DependencyManager::get<ScriptEngines>();
|
||||
if (run) {
|
||||
const QString& scriptURLString = QUrl(_currentScript).toString();
|
||||
// Reload script so that an out of date copy is not retrieved from the cache
|
||||
_scriptEngine = scriptEngines->loadScript(scriptURLString, true, true, false, true);
|
||||
connect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged);
|
||||
connect(_scriptEngine, &ScriptEngine::update, this, &ScriptEditorWidget::onScriptModified);
|
||||
connect(_scriptEngine, &ScriptEngine::finished, this, &ScriptEditorWidget::onScriptFinished);
|
||||
} else {
|
||||
connect(_scriptEngine, &ScriptEngine::finished, this, &ScriptEditorWidget::onScriptFinished);
|
||||
const QString& scriptURLString = QUrl(_currentScript).toString();
|
||||
scriptEngines->stopScript(scriptURLString);
|
||||
_scriptEngine = NULL;
|
||||
}
|
||||
_console->setScriptEngine(_scriptEngine);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScriptEditorWidget::saveFile(const QString &scriptPath) {
|
||||
QFile file(scriptPath);
|
||||
if (!file.open(QFile::WriteOnly | QFile::Text)) {
|
||||
OffscreenUi::warning(this, tr("Interface"), tr("Cannot write script %1:\n%2.").arg(scriptPath)
|
||||
.arg(file.errorString()));
|
||||
return false;
|
||||
}
|
||||
|
||||
QTextStream out(&file);
|
||||
out << _scriptEditorWidgetUI->scriptEdit->toPlainText();
|
||||
file.close();
|
||||
|
||||
setScriptFile(scriptPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScriptEditorWidget::loadFile(const QString& scriptPath) {
|
||||
QUrl url(scriptPath);
|
||||
|
||||
// if the scheme length is one or lower, maybe they typed in a file, let's try
|
||||
const int WINDOWS_DRIVE_LETTER_SIZE = 1;
|
||||
if (url.scheme().size() <= WINDOWS_DRIVE_LETTER_SIZE) {
|
||||
QFile file(scriptPath);
|
||||
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
||||
OffscreenUi::warning(this, tr("Interface"), tr("Cannot read script %1:\n%2.").arg(scriptPath)
|
||||
.arg(file.errorString()));
|
||||
return;
|
||||
}
|
||||
QTextStream in(&file);
|
||||
_scriptEditorWidgetUI->scriptEdit->setPlainText(in.readAll());
|
||||
file.close();
|
||||
setScriptFile(scriptPath);
|
||||
|
||||
if (_scriptEngine != NULL) {
|
||||
disconnect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged);
|
||||
disconnect(_scriptEngine, &ScriptEngine::update, this, &ScriptEditorWidget::onScriptModified);
|
||||
disconnect(_scriptEngine, &ScriptEngine::finished, this, &ScriptEditorWidget::onScriptFinished);
|
||||
}
|
||||
} else {
|
||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||
QNetworkRequest networkRequest = QNetworkRequest(url);
|
||||
networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||
networkRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT);
|
||||
QNetworkReply* reply = networkAccessManager.get(networkRequest);
|
||||
qDebug() << "Downloading included script at" << scriptPath;
|
||||
QEventLoop loop;
|
||||
QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
|
||||
loop.exec();
|
||||
_scriptEditorWidgetUI->scriptEdit->setPlainText(reply->readAll());
|
||||
delete reply;
|
||||
|
||||
if (!saveAs()) {
|
||||
static_cast<ScriptEditorWindow*>(this->parent()->parent()->parent())->terminateCurrentTab();
|
||||
}
|
||||
}
|
||||
const QString& scriptURLString = QUrl(_currentScript).toString();
|
||||
_scriptEngine = DependencyManager::get<ScriptEngines>()->getScriptEngine(scriptURLString);
|
||||
if (_scriptEngine != NULL) {
|
||||
connect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged);
|
||||
connect(_scriptEngine, &ScriptEngine::update, this, &ScriptEditorWidget::onScriptModified);
|
||||
connect(_scriptEngine, &ScriptEngine::finished, this, &ScriptEditorWidget::onScriptFinished);
|
||||
}
|
||||
_console->setScriptEngine(_scriptEngine);
|
||||
}
|
||||
|
||||
bool ScriptEditorWidget::save() {
|
||||
return _currentScript.isEmpty() ? saveAs() : saveFile(_currentScript);
|
||||
}
|
||||
|
||||
bool ScriptEditorWidget::saveAs() {
|
||||
auto scriptEngines = DependencyManager::get<ScriptEngines>();
|
||||
QString fileName = QFileDialog::getSaveFileName(this, tr("Save script"),
|
||||
qApp->getPreviousScriptLocation(),
|
||||
tr("JavaScript Files (*.js)"));
|
||||
if (!fileName.isEmpty()) {
|
||||
qApp->setPreviousScriptLocation(fileName);
|
||||
return saveFile(fileName);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEditorWidget::setScriptFile(const QString& scriptPath) {
|
||||
_currentScript = scriptPath;
|
||||
_currentScriptModified = QFileInfo(_currentScript).lastModified();
|
||||
_scriptEditorWidgetUI->scriptEdit->document()->setModified(false);
|
||||
setWindowModified(false);
|
||||
|
||||
emit scriptnameChanged();
|
||||
}
|
||||
|
||||
bool ScriptEditorWidget::questionSave() {
|
||||
if (_scriptEditorWidgetUI->scriptEdit->document()->isModified()) {
|
||||
QMessageBox::StandardButton button = OffscreenUi::warning(this, tr("Interface"),
|
||||
tr("The script has been modified.\nDo you want to save your changes?"), QMessageBox::Save | QMessageBox::Discard |
|
||||
QMessageBox::Cancel, QMessageBox::Save);
|
||||
return button == QMessageBox::Save ? save() : (button == QMessageBox::Discard);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScriptEditorWidget::onWindowActivated() {
|
||||
if (!_isReloading) {
|
||||
_isReloading = true;
|
||||
|
||||
QDateTime fileStamp = QFileInfo(_currentScript).lastModified();
|
||||
if (fileStamp > _currentScriptModified) {
|
||||
bool doReload = false;
|
||||
auto window = static_cast<ScriptEditorWindow*>(this->parent()->parent()->parent());
|
||||
window->inModalDialog = true;
|
||||
if (window->autoReloadScripts()
|
||||
|| OffscreenUi::question(this, tr("Reload Script"),
|
||||
tr("The following file has been modified outside of the Interface editor:") + "\n" + _currentScript + "\n"
|
||||
+ (isModified()
|
||||
? tr("Do you want to reload it and lose the changes you've made in the Interface editor?")
|
||||
: tr("Do you want to reload it?")),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
doReload = true;
|
||||
}
|
||||
window->inModalDialog = false;
|
||||
if (doReload) {
|
||||
loadFile(_currentScript);
|
||||
if (_scriptEditorWidgetUI->onTheFlyCheckBox->isChecked() && isRunning()) {
|
||||
_isRestarting = true;
|
||||
setRunning(false);
|
||||
// Script is restarted once current script instance finishes.
|
||||
}
|
||||
} else {
|
||||
_currentScriptModified = fileStamp; // Asked and answered. Don't ask again until the external file is changed again.
|
||||
}
|
||||
}
|
||||
_isReloading = false;
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
//
|
||||
// ScriptEditorWidget.h
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Thijs Wenker on 4/14/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_ScriptEditorWidget_h
|
||||
#define hifi_ScriptEditorWidget_h
|
||||
|
||||
#include <QDockWidget>
|
||||
|
||||
#include "JSConsole.h"
|
||||
#include "ScriptEngine.h"
|
||||
|
||||
namespace Ui {
|
||||
class ScriptEditorWidget;
|
||||
}
|
||||
|
||||
class ScriptEditorWidget : public QDockWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ScriptEditorWidget();
|
||||
~ScriptEditorWidget();
|
||||
|
||||
bool isModified();
|
||||
bool isRunning();
|
||||
bool setRunning(bool run);
|
||||
bool saveFile(const QString& scriptPath);
|
||||
void loadFile(const QString& scriptPath);
|
||||
void setScriptFile(const QString& scriptPath);
|
||||
bool save();
|
||||
bool saveAs();
|
||||
bool questionSave();
|
||||
const QString getScriptName() const { return _currentScript; };
|
||||
|
||||
signals:
|
||||
void runningStateChanged();
|
||||
void scriptnameChanged();
|
||||
void scriptModified();
|
||||
|
||||
public slots:
|
||||
void onWindowActivated();
|
||||
|
||||
private slots:
|
||||
void onScriptModified();
|
||||
void onScriptFinished(const QString& scriptName);
|
||||
|
||||
private:
|
||||
JSConsole* _console;
|
||||
Ui::ScriptEditorWidget* _scriptEditorWidgetUI;
|
||||
ScriptEngine* _scriptEngine;
|
||||
QString _currentScript;
|
||||
QDateTime _currentScriptModified;
|
||||
bool _isRestarting;
|
||||
bool _isReloading;
|
||||
};
|
||||
|
||||
#endif // hifi_ScriptEditorWidget_h
|
|
@ -1,259 +0,0 @@
|
|||
//
|
||||
// ScriptEditorWindow.cpp
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Thijs Wenker on 4/14/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QFileDialog>
|
||||
|
||||
#include "ui_scriptEditorWindow.h"
|
||||
#include "ScriptEditorWindow.h"
|
||||
#include "ScriptEditorWidget.h"
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QtCore/QSignalMapper>
|
||||
#include <QFrame>
|
||||
#include <QLayoutItem>
|
||||
#include <QMainWindow>
|
||||
#include <QMessageBox>
|
||||
#include <QPalette>
|
||||
#include <QScrollBar>
|
||||
#include <QShortcut>
|
||||
#include <QSizePolicy>
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
|
||||
#include <ScriptEngines.h>
|
||||
#include "Application.h"
|
||||
#include "PathUtils.h"
|
||||
|
||||
ScriptEditorWindow::ScriptEditorWindow(QWidget* parent) :
|
||||
QWidget(parent),
|
||||
_ScriptEditorWindowUI(new Ui::ScriptEditorWindow),
|
||||
_loadMenu(new QMenu),
|
||||
_saveMenu(new QMenu)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
_ScriptEditorWindowUI->setupUi(this);
|
||||
|
||||
this->setWindowFlags(Qt::Tool);
|
||||
addScriptEditorWidget("New script");
|
||||
connect(_loadMenu, &QMenu::aboutToShow, this, &ScriptEditorWindow::loadMenuAboutToShow);
|
||||
_ScriptEditorWindowUI->loadButton->setMenu(_loadMenu);
|
||||
|
||||
_saveMenu->addAction("Save as..", this, SLOT(saveScriptAsClicked()), Qt::CTRL | Qt::SHIFT | Qt::Key_S);
|
||||
|
||||
_ScriptEditorWindowUI->saveButton->setMenu(_saveMenu);
|
||||
|
||||
connect(new QShortcut(QKeySequence("Ctrl+N"), this), &QShortcut::activated, this, &ScriptEditorWindow::newScriptClicked);
|
||||
connect(new QShortcut(QKeySequence("Ctrl+S"), this), &QShortcut::activated, this,&ScriptEditorWindow::saveScriptClicked);
|
||||
connect(new QShortcut(QKeySequence("Ctrl+O"), this), &QShortcut::activated, this, &ScriptEditorWindow::loadScriptClicked);
|
||||
connect(new QShortcut(QKeySequence("F5"), this), &QShortcut::activated, this, &ScriptEditorWindow::toggleRunScriptClicked);
|
||||
|
||||
_ScriptEditorWindowUI->loadButton->setIcon(QIcon(QPixmap(PathUtils::resourcesPath() + "icons/load-script.svg")));
|
||||
_ScriptEditorWindowUI->newButton->setIcon(QIcon(QPixmap(PathUtils::resourcesPath() + "icons/new-script.svg")));
|
||||
_ScriptEditorWindowUI->saveButton->setIcon(QIcon(QPixmap(PathUtils::resourcesPath() + "icons/save-script.svg")));
|
||||
_ScriptEditorWindowUI->toggleRunButton->setIcon(QIcon(QPixmap(PathUtils::resourcesPath() + "icons/start-script.svg")));
|
||||
}
|
||||
|
||||
ScriptEditorWindow::~ScriptEditorWindow() {
|
||||
delete _ScriptEditorWindowUI;
|
||||
}
|
||||
|
||||
void ScriptEditorWindow::setRunningState(bool run) {
|
||||
if (_ScriptEditorWindowUI->tabWidget->currentIndex() != -1) {
|
||||
static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget->currentWidget())->setRunning(run);
|
||||
}
|
||||
this->updateButtons();
|
||||
}
|
||||
|
||||
void ScriptEditorWindow::updateButtons() {
|
||||
bool isRunning = _ScriptEditorWindowUI->tabWidget->currentIndex() != -1 &&
|
||||
static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget->currentWidget())->isRunning();
|
||||
_ScriptEditorWindowUI->toggleRunButton->setEnabled(_ScriptEditorWindowUI->tabWidget->currentIndex() != -1);
|
||||
_ScriptEditorWindowUI->toggleRunButton->setIcon(QIcon(QPixmap(PathUtils::resourcesPath() + ((isRunning ?
|
||||
"icons/stop-script.svg" : "icons/start-script.svg")))));
|
||||
}
|
||||
|
||||
void ScriptEditorWindow::loadScriptMenu(const QString& scriptName) {
|
||||
addScriptEditorWidget("loading...")->loadFile(scriptName);
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
void ScriptEditorWindow::loadScriptClicked() {
|
||||
QString scriptName = QFileDialog::getOpenFileName(this, tr("Interface"),
|
||||
qApp->getPreviousScriptLocation(),
|
||||
tr("JavaScript Files (*.js)"));
|
||||
if (!scriptName.isEmpty()) {
|
||||
qApp->setPreviousScriptLocation(scriptName);
|
||||
addScriptEditorWidget("loading...")->loadFile(scriptName);
|
||||
updateButtons();
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEditorWindow::loadMenuAboutToShow() {
|
||||
_loadMenu->clear();
|
||||
QStringList runningScripts = DependencyManager::get<ScriptEngines>()->getRunningScripts();
|
||||
if (runningScripts.count() > 0) {
|
||||
QSignalMapper* signalMapper = new QSignalMapper(this);
|
||||
foreach (const QString& runningScript, runningScripts) {
|
||||
QAction* runningScriptAction = new QAction(runningScript, _loadMenu);
|
||||
connect(runningScriptAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
|
||||
signalMapper->setMapping(runningScriptAction, runningScript);
|
||||
_loadMenu->addAction(runningScriptAction);
|
||||
}
|
||||
connect(signalMapper, SIGNAL(mapped(const QString &)), this, SLOT(loadScriptMenu(const QString&)));
|
||||
} else {
|
||||
QAction* naAction = new QAction("(no running scripts)", _loadMenu);
|
||||
naAction->setDisabled(true);
|
||||
_loadMenu->addAction(naAction);
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEditorWindow::newScriptClicked() {
|
||||
addScriptEditorWidget(QString("New script"));
|
||||
}
|
||||
|
||||
void ScriptEditorWindow::toggleRunScriptClicked() {
|
||||
this->setRunningState(!(_ScriptEditorWindowUI->tabWidget->currentIndex() !=-1
|
||||
&& static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget->currentWidget())->isRunning()));
|
||||
}
|
||||
|
||||
void ScriptEditorWindow::saveScriptClicked() {
|
||||
if (_ScriptEditorWindowUI->tabWidget->currentIndex() != -1) {
|
||||
ScriptEditorWidget* currentScriptWidget = static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget
|
||||
->currentWidget());
|
||||
currentScriptWidget->save();
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEditorWindow::saveScriptAsClicked() {
|
||||
if (_ScriptEditorWindowUI->tabWidget->currentIndex() != -1) {
|
||||
ScriptEditorWidget* currentScriptWidget = static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget
|
||||
->currentWidget());
|
||||
currentScriptWidget->saveAs();
|
||||
}
|
||||
}
|
||||
|
||||
ScriptEditorWidget* ScriptEditorWindow::addScriptEditorWidget(QString title) {
|
||||
ScriptEditorWidget* newScriptEditorWidget = new ScriptEditorWidget();
|
||||
connect(newScriptEditorWidget, &ScriptEditorWidget::scriptnameChanged, this, &ScriptEditorWindow::updateScriptNameOrStatus);
|
||||
connect(newScriptEditorWidget, &ScriptEditorWidget::scriptModified, this, &ScriptEditorWindow::updateScriptNameOrStatus);
|
||||
connect(newScriptEditorWidget, &ScriptEditorWidget::runningStateChanged, this, &ScriptEditorWindow::updateButtons);
|
||||
connect(this, &ScriptEditorWindow::windowActivated, newScriptEditorWidget, &ScriptEditorWidget::onWindowActivated);
|
||||
_ScriptEditorWindowUI->tabWidget->addTab(newScriptEditorWidget, title);
|
||||
_ScriptEditorWindowUI->tabWidget->setCurrentWidget(newScriptEditorWidget);
|
||||
newScriptEditorWidget->setUpdatesEnabled(true);
|
||||
newScriptEditorWidget->adjustSize();
|
||||
return newScriptEditorWidget;
|
||||
}
|
||||
|
||||
void ScriptEditorWindow::tabSwitched(int tabIndex) {
|
||||
this->updateButtons();
|
||||
if (_ScriptEditorWindowUI->tabWidget->currentIndex() != -1) {
|
||||
ScriptEditorWidget* currentScriptWidget = static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget
|
||||
->currentWidget());
|
||||
QString modifiedStar = (currentScriptWidget->isModified() ? "*" : "");
|
||||
if (currentScriptWidget->getScriptName().length() > 0) {
|
||||
this->setWindowTitle("Script Editor [" + currentScriptWidget->getScriptName() + modifiedStar + "]");
|
||||
} else {
|
||||
this->setWindowTitle("Script Editor [New script" + modifiedStar + "]");
|
||||
}
|
||||
} else {
|
||||
this->setWindowTitle("Script Editor");
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEditorWindow::tabCloseRequested(int tabIndex) {
|
||||
if (ignoreCloseForModal(nullptr)) {
|
||||
return;
|
||||
}
|
||||
ScriptEditorWidget* closingScriptWidget = static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget
|
||||
->widget(tabIndex));
|
||||
if(closingScriptWidget->questionSave()) {
|
||||
_ScriptEditorWindowUI->tabWidget->removeTab(tabIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// If this operating system window causes a qml overlay modal dialog (which might not even be seen by the user), closing this window
|
||||
// will crash the code that was waiting on the dialog result. So that code whousl set inModalDialog to true while the question is up.
|
||||
// This code will not be necessary when switch out all operating system windows for qml overlays.
|
||||
bool ScriptEditorWindow::ignoreCloseForModal(QCloseEvent* event) {
|
||||
if (!inModalDialog) {
|
||||
return false;
|
||||
}
|
||||
// Deliberately not using OffscreenUi, so that the dialog is seen.
|
||||
QMessageBox::information(this, tr("Interface"), tr("There is a modal dialog that must be answered before closing."),
|
||||
QMessageBox::Discard, QMessageBox::Discard);
|
||||
if (event) {
|
||||
event->ignore(); // don't close
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScriptEditorWindow::closeEvent(QCloseEvent *event) {
|
||||
if (ignoreCloseForModal(event)) {
|
||||
return;
|
||||
}
|
||||
bool unsaved_docs_warning = false;
|
||||
for (int i = 0; i < _ScriptEditorWindowUI->tabWidget->count(); i++){
|
||||
if(static_cast<ScriptEditorWidget*>(_ScriptEditorWindowUI->tabWidget->widget(i))->isModified()){
|
||||
unsaved_docs_warning = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!unsaved_docs_warning || QMessageBox::warning(this, tr("Interface"),
|
||||
tr("There are some unsaved scripts, are you sure you want to close the editor? Changes will be lost!"),
|
||||
QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Cancel) == QMessageBox::Discard) {
|
||||
event->accept();
|
||||
} else {
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEditorWindow::updateScriptNameOrStatus() {
|
||||
ScriptEditorWidget* source = static_cast<ScriptEditorWidget*>(QObject::sender());
|
||||
QString modifiedStar = (source->isModified()? "*" : "");
|
||||
if (source->getScriptName().length() > 0) {
|
||||
for (int i = 0; i < _ScriptEditorWindowUI->tabWidget->count(); i++){
|
||||
if (_ScriptEditorWindowUI->tabWidget->widget(i) == source) {
|
||||
_ScriptEditorWindowUI->tabWidget->setTabText(i, modifiedStar + QFileInfo(source->getScriptName()).fileName());
|
||||
_ScriptEditorWindowUI->tabWidget->setTabToolTip(i, source->getScriptName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_ScriptEditorWindowUI->tabWidget->currentWidget() == source) {
|
||||
if (source->getScriptName().length() > 0) {
|
||||
this->setWindowTitle("Script Editor [" + source->getScriptName() + modifiedStar + "]");
|
||||
} else {
|
||||
this->setWindowTitle("Script Editor [New script" + modifiedStar + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEditorWindow::terminateCurrentTab() {
|
||||
if (_ScriptEditorWindowUI->tabWidget->currentIndex() != -1) {
|
||||
_ScriptEditorWindowUI->tabWidget->removeTab(_ScriptEditorWindowUI->tabWidget->currentIndex());
|
||||
this->raise();
|
||||
}
|
||||
}
|
||||
|
||||
bool ScriptEditorWindow::autoReloadScripts() {
|
||||
return _ScriptEditorWindowUI->autoReloadCheckBox->isChecked();
|
||||
}
|
||||
|
||||
bool ScriptEditorWindow::event(QEvent* event) {
|
||||
if (event->type() == QEvent::WindowActivate) {
|
||||
emit windowActivated();
|
||||
}
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
//
|
||||
// ScriptEditorWindow.h
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Thijs Wenker on 4/14/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_ScriptEditorWindow_h
|
||||
#define hifi_ScriptEditorWindow_h
|
||||
|
||||
#include "ScriptEditorWidget.h"
|
||||
|
||||
namespace Ui {
|
||||
class ScriptEditorWindow;
|
||||
}
|
||||
|
||||
class ScriptEditorWindow : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ScriptEditorWindow(QWidget* parent = nullptr);
|
||||
~ScriptEditorWindow();
|
||||
|
||||
void terminateCurrentTab();
|
||||
bool autoReloadScripts();
|
||||
|
||||
bool inModalDialog { false };
|
||||
bool ignoreCloseForModal(QCloseEvent* event);
|
||||
|
||||
signals:
|
||||
void windowActivated();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent* event) override;
|
||||
virtual bool event(QEvent* event) override;
|
||||
|
||||
private:
|
||||
Ui::ScriptEditorWindow* _ScriptEditorWindowUI;
|
||||
QMenu* _loadMenu;
|
||||
QMenu* _saveMenu;
|
||||
|
||||
ScriptEditorWidget* addScriptEditorWidget(QString title);
|
||||
void setRunningState(bool run);
|
||||
void setScriptName(const QString& scriptName);
|
||||
|
||||
private slots:
|
||||
void loadScriptMenu(const QString& scriptName);
|
||||
void loadScriptClicked();
|
||||
void newScriptClicked();
|
||||
void toggleRunScriptClicked();
|
||||
void saveScriptClicked();
|
||||
void saveScriptAsClicked();
|
||||
void loadMenuAboutToShow();
|
||||
void tabSwitched(int tabIndex);
|
||||
void tabCloseRequested(int tabIndex);
|
||||
void updateScriptNameOrStatus();
|
||||
void updateButtons();
|
||||
};
|
||||
|
||||
#endif // hifi_ScriptEditorWindow_h
|
|
@ -1,28 +0,0 @@
|
|||
//
|
||||
// ScriptLineNumberArea.cpp
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Thijs Wenker on 4/30/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "ScriptLineNumberArea.h"
|
||||
|
||||
#include "ScriptEditBox.h"
|
||||
|
||||
ScriptLineNumberArea::ScriptLineNumberArea(ScriptEditBox* scriptEditBox) :
|
||||
QWidget(scriptEditBox)
|
||||
{
|
||||
_scriptEditBox = scriptEditBox;
|
||||
}
|
||||
|
||||
QSize ScriptLineNumberArea::sizeHint() const {
|
||||
return QSize(_scriptEditBox->lineNumberAreaWidth(), 0);
|
||||
}
|
||||
|
||||
void ScriptLineNumberArea::paintEvent(QPaintEvent* event) {
|
||||
_scriptEditBox->lineNumberAreaPaintEvent(event);
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
//
|
||||
// ScriptLineNumberArea.h
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Thijs Wenker on 4/30/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_ScriptLineNumberArea_h
|
||||
#define hifi_ScriptLineNumberArea_h
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class ScriptEditBox;
|
||||
|
||||
class ScriptLineNumberArea : public QWidget {
|
||||
|
||||
public:
|
||||
ScriptLineNumberArea(ScriptEditBox* scriptEditBox);
|
||||
QSize sizeHint() const override;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
|
||||
private:
|
||||
ScriptEditBox* _scriptEditBox;
|
||||
};
|
||||
|
||||
#endif // hifi_ScriptLineNumberArea_h
|
|
@ -1,49 +0,0 @@
|
|||
//
|
||||
// ScriptsTableWidget.cpp
|
||||
// interface
|
||||
//
|
||||
// Created by Mohammed Nafees on 04/03/2014.
|
||||
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QDebug>
|
||||
#include <QHeaderView>
|
||||
#include <QKeyEvent>
|
||||
#include <QPainter>
|
||||
|
||||
#include "ScriptsTableWidget.h"
|
||||
|
||||
ScriptsTableWidget::ScriptsTableWidget(QWidget* parent) :
|
||||
QTableWidget(parent) {
|
||||
verticalHeader()->setVisible(false);
|
||||
horizontalHeader()->setVisible(false);
|
||||
setShowGrid(false);
|
||||
setSelectionMode(QAbstractItemView::NoSelection);
|
||||
setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
setStyleSheet("QTableWidget { border: none; background: transparent; color: #333333; } QToolTip { color: #000000; background: #f9f6e4; padding: 2px; }");
|
||||
setToolTipDuration(200);
|
||||
setWordWrap(true);
|
||||
setGeometry(0, 0, parent->width(), parent->height());
|
||||
}
|
||||
|
||||
void ScriptsTableWidget::paintEvent(QPaintEvent* event) {
|
||||
QPainter painter(viewport());
|
||||
painter.setPen(QColor::fromRgb(225, 225, 225)); // #e1e1e1
|
||||
|
||||
int y = 0;
|
||||
for (int i = 0; i < rowCount(); i++) {
|
||||
painter.drawLine(5, rowHeight(i) + y, width(), rowHeight(i) + y);
|
||||
y += rowHeight(i);
|
||||
}
|
||||
painter.end();
|
||||
|
||||
QTableWidget::paintEvent(event);
|
||||
}
|
||||
|
||||
void ScriptsTableWidget::keyPressEvent(QKeyEvent* event) {
|
||||
// Ignore keys so they will propagate correctly
|
||||
event->ignore();
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
//
|
||||
// ScriptsTableWidget.h
|
||||
// interface
|
||||
//
|
||||
// Created by Mohammed Nafees on 04/03/2014.
|
||||
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi__ScriptsTableWidget_h
|
||||
#define hifi__ScriptsTableWidget_h
|
||||
|
||||
#include <QDebug>
|
||||
#include <QTableWidget>
|
||||
|
||||
class ScriptsTableWidget : public QTableWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ScriptsTableWidget(QWidget* parent);
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent* event) override;
|
||||
virtual void keyPressEvent(QKeyEvent* event) override;
|
||||
};
|
||||
|
||||
#endif // hifi__ScriptsTableWidget_h
|
|
@ -222,10 +222,10 @@ void Stats::updateStats(bool force) {
|
|||
STAT_UPDATE(audioMixerInPps, roundf(bandwidthRecorder->getAverageInputPacketsPerSecond(NodeType::AudioMixer)));
|
||||
STAT_UPDATE(audioMixerOutKbps, roundf(bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AudioMixer)));
|
||||
STAT_UPDATE(audioMixerOutPps, roundf(bandwidthRecorder->getAverageOutputPacketsPerSecond(NodeType::AudioMixer)));
|
||||
STAT_UPDATE(audioMicOutboundPPS, audioClient->getMicAudioOutboundPPS());
|
||||
STAT_UPDATE(audioSilentOutboundPPS, audioClient->getSilentOutboundPPS());
|
||||
STAT_UPDATE(audioAudioInboundPPS, audioClient->getAudioInboundPPS());
|
||||
STAT_UPDATE(audioSilentInboundPPS, audioClient->getSilentInboundPPS());
|
||||
STAT_UPDATE(audioOutboundPPS, audioClient->getAudioOutboundPPS());
|
||||
STAT_UPDATE(audioSilentOutboundPPS, audioClient->getSilentOutboundPPS());
|
||||
} else {
|
||||
STAT_UPDATE(audioMixerKbps, -1);
|
||||
STAT_UPDATE(audioMixerPps, -1);
|
||||
|
@ -233,7 +233,7 @@ void Stats::updateStats(bool force) {
|
|||
STAT_UPDATE(audioMixerInPps, -1);
|
||||
STAT_UPDATE(audioMixerOutKbps, -1);
|
||||
STAT_UPDATE(audioMixerOutPps, -1);
|
||||
STAT_UPDATE(audioMicOutboundPPS, -1);
|
||||
STAT_UPDATE(audioOutboundPPS, -1);
|
||||
STAT_UPDATE(audioSilentOutboundPPS, -1);
|
||||
STAT_UPDATE(audioAudioInboundPPS, -1);
|
||||
STAT_UPDATE(audioSilentInboundPPS, -1);
|
||||
|
|
|
@ -77,7 +77,7 @@ class Stats : public QQuickItem {
|
|||
STATS_PROPERTY(int, audioMixerOutPps, 0)
|
||||
STATS_PROPERTY(int, audioMixerKbps, 0)
|
||||
STATS_PROPERTY(int, audioMixerPps, 0)
|
||||
STATS_PROPERTY(int, audioMicOutboundPPS, 0)
|
||||
STATS_PROPERTY(int, audioOutboundPPS, 0)
|
||||
STATS_PROPERTY(int, audioSilentOutboundPPS, 0)
|
||||
STATS_PROPERTY(int, audioAudioInboundPPS, 0)
|
||||
STATS_PROPERTY(int, audioSilentInboundPPS, 0)
|
||||
|
@ -200,7 +200,7 @@ signals:
|
|||
void audioMixerOutPpsChanged();
|
||||
void audioMixerKbpsChanged();
|
||||
void audioMixerPpsChanged();
|
||||
void audioMicOutboundPPSChanged();
|
||||
void audioOutboundPPSChanged();
|
||||
void audioSilentOutboundPPSChanged();
|
||||
void audioAudioInboundPPSChanged();
|
||||
void audioSilentInboundPPSChanged();
|
||||
|
|
|
@ -431,7 +431,9 @@ RayToOverlayIntersectionResult Overlays::findRayIntersectionInternal(const PickR
|
|||
if (thisOverlay->findRayIntersectionExtraInfo(ray.origin, ray.direction, thisDistance,
|
||||
thisFace, thisSurfaceNormal, thisExtraInfo)) {
|
||||
bool isDrawInFront = thisOverlay->getDrawInFront();
|
||||
if (thisDistance < bestDistance && (!bestIsFront || isDrawInFront)) {
|
||||
if ((bestIsFront && isDrawInFront && thisDistance < bestDistance)
|
||||
|| (!bestIsFront && (isDrawInFront || thisDistance < bestDistance))) {
|
||||
|
||||
bestIsFront = isDrawInFront;
|
||||
bestDistance = thisDistance;
|
||||
result.intersects = true;
|
||||
|
|
|
@ -1,142 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ScriptEditorWidget</class>
|
||||
<widget class="QDockWidget" name="ScriptEditorWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>691</width>
|
||||
<height>549</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>690</width>
|
||||
<height>328</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font-family: Helvetica, Arial, sans-serif;</string>
|
||||
</property>
|
||||
<property name="features">
|
||||
<set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set>
|
||||
</property>
|
||||
<property name="allowedAreas">
|
||||
<set>Qt::NoDockWidgetArea</set>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Edit Script</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="dockWidgetContents">
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,1">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="ScriptEditBox" name="scriptEdit">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Courier</family>
|
||||
<pointsize>-1</pointsize>
|
||||
<weight>50</weight>
|
||||
<italic>false</italic>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font: 16px "Courier";</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font: 13px "Helvetica","Arial","sans-serif";</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Debug Log:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="onTheFlyCheckBox">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Helvetica,Arial,sans-serif</family>
|
||||
<pointsize>-1</pointsize>
|
||||
<weight>50</weight>
|
||||
<italic>false</italic>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font: 13px "Helvetica","Arial","sans-serif";</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Run on the fly (Careful: Any valid change made to the code will run immediately) </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="clearButton">
|
||||
<property name="text">
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ScriptEditBox</class>
|
||||
<extends>QTextEdit</extends>
|
||||
<header>ui/ScriptEditBox.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
</ui>
|
|
@ -1,324 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ScriptEditorWindow</class>
|
||||
<widget class="QWidget" name="ScriptEditorWindow">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::NonModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>780</width>
|
||||
<height>717</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>250</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Script Editor</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font-family: Helvetica, Arial, sans-serif;</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0,0,0">
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetNoConstraint</enum>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolButton" name="newButton">
|
||||
<property name="toolTip">
|
||||
<string>New Script (Ctrl+N)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>New</string>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="loadButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>25</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Load Script (Ctrl+O)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load</string>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::MenuButtonPopup</enum>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonIconOnly</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="saveButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::NoContextMenu</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Save Script (Ctrl+S)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoRepeatDelay">
|
||||
<number>316</number>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::MenuButtonPopup</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="toggleRunButton">
|
||||
<property name="toolTip">
|
||||
<string>Toggle Run Script (F5)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Run/Stop</string>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="autoReloadCheckBox">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font: 13px "Helvetica","Arial","sans-serif";</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Automatically reload externally changed files</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>80</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="tabPosition">
|
||||
<enum>QTabWidget::West</enum>
|
||||
</property>
|
||||
<property name="tabShape">
|
||||
<enum>QTabWidget::Triangular</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="elideMode">
|
||||
<enum>Qt::ElideNone</enum>
|
||||
</property>
|
||||
<property name="tabsClosable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="movable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>saveButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>ScriptEditorWindow</receiver>
|
||||
<slot>saveScriptClicked()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>236</x>
|
||||
<y>10</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>199</x>
|
||||
<y>264</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>toggleRunButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>ScriptEditorWindow</receiver>
|
||||
<slot>toggleRunScriptClicked()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>330</x>
|
||||
<y>10</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>199</x>
|
||||
<y>264</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>newButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>ScriptEditorWindow</receiver>
|
||||
<slot>newScriptClicked()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>58</x>
|
||||
<y>10</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>199</x>
|
||||
<y>264</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>loadButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>ScriptEditorWindow</receiver>
|
||||
<slot>loadScriptClicked()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>85</x>
|
||||
<y>10</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>199</x>
|
||||
<y>264</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>tabWidget</sender>
|
||||
<signal>currentChanged(int)</signal>
|
||||
<receiver>ScriptEditorWindow</receiver>
|
||||
<slot>tabSwitched(int)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>352</x>
|
||||
<y>360</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>352</x>
|
||||
<y>340</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>tabWidget</sender>
|
||||
<signal>tabCloseRequested(int)</signal>
|
||||
<receiver>ScriptEditorWindow</receiver>
|
||||
<slot>tabCloseRequested(int)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>352</x>
|
||||
<y>360</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>352</x>
|
||||
<y>340</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
|
@ -184,7 +184,6 @@ AudioClient::AudioClient() :
|
|||
_outgoingAvatarAudioSequenceNumber(0),
|
||||
_audioOutputIODevice(_localInjectorsStream, _receivedAudioStream, this),
|
||||
_stats(&_receivedAudioStream),
|
||||
_inputGate(),
|
||||
_positionGetter(DEFAULT_POSITION_GETTER),
|
||||
_orientationGetter(DEFAULT_ORIENTATION_GETTER) {
|
||||
// avoid putting a lock in the device callback
|
||||
|
@ -971,14 +970,87 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) {
|
|||
}
|
||||
}
|
||||
|
||||
void AudioClient::handleAudioInput() {
|
||||
void AudioClient::handleAudioInput(QByteArray& audioBuffer) {
|
||||
if (_muted) {
|
||||
_lastInputLoudness = 0.0f;
|
||||
_timeSinceLastClip = 0.0f;
|
||||
} else {
|
||||
int16_t* samples = reinterpret_cast<int16_t*>(audioBuffer.data());
|
||||
int numSamples = audioBuffer.size() / sizeof(AudioConstants::SAMPLE_SIZE);
|
||||
bool didClip = false;
|
||||
|
||||
bool shouldRemoveDCOffset = !_isPlayingBackRecording && !_isStereoInput;
|
||||
if (shouldRemoveDCOffset) {
|
||||
_noiseGate.removeDCOffset(samples, numSamples);
|
||||
}
|
||||
|
||||
bool shouldNoiseGate = (_isPlayingBackRecording || !_isStereoInput) && _isNoiseGateEnabled;
|
||||
if (shouldNoiseGate) {
|
||||
_noiseGate.gateSamples(samples, numSamples);
|
||||
_lastInputLoudness = _noiseGate.getLastLoudness();
|
||||
didClip = _noiseGate.clippedInLastBlock();
|
||||
} else {
|
||||
float loudness = 0.0f;
|
||||
for (int i = 0; i < numSamples; ++i) {
|
||||
int16_t sample = std::abs(samples[i]);
|
||||
loudness += (float)sample;
|
||||
didClip = didClip ||
|
||||
(sample > (AudioConstants::MAX_SAMPLE_VALUE * AudioNoiseGate::CLIPPING_THRESHOLD));
|
||||
}
|
||||
_lastInputLoudness = fabs(loudness / numSamples);
|
||||
}
|
||||
|
||||
if (didClip) {
|
||||
_timeSinceLastClip = 0.0f;
|
||||
} else if (_timeSinceLastClip >= 0.0f) {
|
||||
_timeSinceLastClip += (float)numSamples / (float)AudioConstants::SAMPLE_RATE;
|
||||
}
|
||||
|
||||
emit inputReceived({ audioBuffer.data(), numSamples });
|
||||
|
||||
if (_noiseGate.openedInLastBlock()) {
|
||||
emit noiseGateOpened();
|
||||
} else if (_noiseGate.closedInLastBlock()) {
|
||||
emit noiseGateClosed();
|
||||
}
|
||||
}
|
||||
|
||||
// the codec needs a flush frame before sending silent packets, so
|
||||
// do not send one if the gate closed in this block (eventually this can be crossfaded).
|
||||
auto packetType = _shouldEchoToServer ?
|
||||
PacketType::MicrophoneAudioWithEcho : PacketType::MicrophoneAudioNoEcho;
|
||||
if (_lastInputLoudness == 0.0f && !_noiseGate.closedInLastBlock()) {
|
||||
packetType = PacketType::SilentAudioFrame;
|
||||
_silentOutbound.increment();
|
||||
} else {
|
||||
_audioOutbound.increment();
|
||||
}
|
||||
|
||||
Transform audioTransform;
|
||||
audioTransform.setTranslation(_positionGetter());
|
||||
audioTransform.setRotation(_orientationGetter());
|
||||
|
||||
QByteArray encodedBuffer;
|
||||
if (_encoder) {
|
||||
_encoder->encode(audioBuffer, encodedBuffer);
|
||||
} else {
|
||||
encodedBuffer = audioBuffer;
|
||||
}
|
||||
|
||||
emitAudioPacket(encodedBuffer.data(), encodedBuffer.size(), _outgoingAvatarAudioSequenceNumber,
|
||||
audioTransform, avatarBoundingBoxCorner, avatarBoundingBoxScale,
|
||||
packetType, _selectedCodecName);
|
||||
_stats.sentPacket();
|
||||
}
|
||||
|
||||
void AudioClient::handleMicAudioInput() {
|
||||
if (!_inputDevice || _isPlayingBackRecording) {
|
||||
return;
|
||||
}
|
||||
|
||||
// input samples required to produce exactly NETWORK_FRAME_SAMPLES of output
|
||||
const int inputSamplesRequired = (_inputToNetworkResampler ?
|
||||
_inputToNetworkResampler->getMinInput(AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL) :
|
||||
const int inputSamplesRequired = (_inputToNetworkResampler ?
|
||||
_inputToNetworkResampler->getMinInput(AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL) :
|
||||
AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL) * _inputFormat.channelCount();
|
||||
|
||||
const auto inputAudioSamples = std::unique_ptr<int16_t[]>(new int16_t[inputSamplesRequired]);
|
||||
|
@ -1001,126 +1073,27 @@ void AudioClient::handleAudioInput() {
|
|||
static int16_t networkAudioSamples[AudioConstants::NETWORK_FRAME_SAMPLES_STEREO];
|
||||
|
||||
while (_inputRingBuffer.samplesAvailable() >= inputSamplesRequired) {
|
||||
|
||||
if (!_muted) {
|
||||
|
||||
|
||||
// Increment the time since the last clip
|
||||
if (_timeSinceLastClip >= 0.0f) {
|
||||
_timeSinceLastClip += (float)numNetworkSamples / (float)AudioConstants::SAMPLE_RATE;
|
||||
}
|
||||
|
||||
if (_muted) {
|
||||
_inputRingBuffer.shiftReadPosition(inputSamplesRequired);
|
||||
} else {
|
||||
_inputRingBuffer.readSamples(inputAudioSamples.get(), inputSamplesRequired);
|
||||
possibleResampling(_inputToNetworkResampler,
|
||||
inputAudioSamples.get(), networkAudioSamples,
|
||||
inputSamplesRequired, numNetworkSamples,
|
||||
_inputFormat.channelCount(), _desiredInputFormat.channelCount());
|
||||
|
||||
// Remove DC offset
|
||||
if (!_isStereoInput) {
|
||||
_inputGate.removeDCOffset(networkAudioSamples, numNetworkSamples);
|
||||
}
|
||||
|
||||
// only impose the noise gate and perform tone injection if we are sending mono audio
|
||||
if (!_isStereoInput && _isNoiseGateEnabled) {
|
||||
_inputGate.gateSamples(networkAudioSamples, numNetworkSamples);
|
||||
|
||||
// if we performed the noise gate we can get values from it instead of enumerating the samples again
|
||||
_lastInputLoudness = _inputGate.getLastLoudness();
|
||||
|
||||
if (_inputGate.clippedInLastBlock()) {
|
||||
_timeSinceLastClip = 0.0f;
|
||||
}
|
||||
|
||||
} else {
|
||||
float loudness = 0.0f;
|
||||
|
||||
for (int i = 0; i < numNetworkSamples; i++) {
|
||||
int thisSample = std::abs(networkAudioSamples[i]);
|
||||
loudness += (float)thisSample;
|
||||
|
||||
if (thisSample > (AudioConstants::MAX_SAMPLE_VALUE * AudioNoiseGate::CLIPPING_THRESHOLD)) {
|
||||
_timeSinceLastClip = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
_lastInputLoudness = fabs(loudness / numNetworkSamples);
|
||||
}
|
||||
|
||||
emit inputReceived({ reinterpret_cast<char*>(networkAudioSamples), numNetworkBytes });
|
||||
|
||||
if (_inputGate.openedInLastBlock()) {
|
||||
emit noiseGateOpened();
|
||||
} else if (_inputGate.closedInLastBlock()) {
|
||||
emit noiseGateClosed();
|
||||
}
|
||||
|
||||
} else {
|
||||
// our input loudness is 0, since we're muted
|
||||
_lastInputLoudness = 0;
|
||||
_timeSinceLastClip = 0.0f;
|
||||
|
||||
_inputRingBuffer.shiftReadPosition(inputSamplesRequired);
|
||||
}
|
||||
|
||||
auto packetType = _shouldEchoToServer ?
|
||||
PacketType::MicrophoneAudioWithEcho : PacketType::MicrophoneAudioNoEcho;
|
||||
|
||||
// if the _inputGate closed in this last frame, then we don't actually want
|
||||
// to send a silent packet, instead, we want to go ahead and encode and send
|
||||
// the output from the input gate (eventually, this could be crossfaded)
|
||||
// and allow the codec to properly encode down to silent/zero. If we still
|
||||
// have _lastInputLoudness of 0 in our NEXT frame, we will send a silent packet
|
||||
if (_lastInputLoudness == 0 && !_inputGate.closedInLastBlock()) {
|
||||
packetType = PacketType::SilentAudioFrame;
|
||||
_silentOutbound.increment();
|
||||
} else {
|
||||
_micAudioOutbound.increment();
|
||||
}
|
||||
|
||||
Transform audioTransform;
|
||||
audioTransform.setTranslation(_positionGetter());
|
||||
audioTransform.setRotation(_orientationGetter());
|
||||
// FIXME find a way to properly handle both playback audio and user audio concurrently
|
||||
|
||||
QByteArray decodedBuffer(reinterpret_cast<char*>(networkAudioSamples), numNetworkBytes);
|
||||
QByteArray encodedBuffer;
|
||||
if (_encoder) {
|
||||
_encoder->encode(decodedBuffer, encodedBuffer);
|
||||
} else {
|
||||
encodedBuffer = decodedBuffer;
|
||||
}
|
||||
|
||||
emitAudioPacket(encodedBuffer.constData(), encodedBuffer.size(), _outgoingAvatarAudioSequenceNumber,
|
||||
audioTransform, avatarBoundingBoxCorner, avatarBoundingBoxScale,
|
||||
packetType, _selectedCodecName);
|
||||
_stats.sentPacket();
|
||||
|
||||
int bytesInInputRingBuffer = _inputRingBuffer.samplesAvailable() * AudioConstants::SAMPLE_SIZE;
|
||||
float msecsInInputRingBuffer = bytesInInputRingBuffer / (float)(_inputFormat.bytesForDuration(USECS_PER_MSEC));
|
||||
_stats.updateInputMsUnplayed(msecsInInputRingBuffer);
|
||||
|
||||
QByteArray audioBuffer(reinterpret_cast<char*>(networkAudioSamples), numNetworkBytes);
|
||||
handleAudioInput(audioBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME - should this go through the noise gate and honor mute and echo?
|
||||
void AudioClient::handleRecordedAudioInput(const QByteArray& audio) {
|
||||
Transform audioTransform;
|
||||
audioTransform.setTranslation(_positionGetter());
|
||||
audioTransform.setRotation(_orientationGetter());
|
||||
|
||||
QByteArray encodedBuffer;
|
||||
if (_encoder) {
|
||||
_encoder->encode(audio, encodedBuffer);
|
||||
} else {
|
||||
encodedBuffer = audio;
|
||||
}
|
||||
|
||||
_micAudioOutbound.increment();
|
||||
|
||||
// FIXME check a flag to see if we should echo audio?
|
||||
emitAudioPacket(encodedBuffer.data(), encodedBuffer.size(), _outgoingAvatarAudioSequenceNumber,
|
||||
audioTransform, avatarBoundingBoxCorner, avatarBoundingBoxScale,
|
||||
PacketType::MicrophoneAudioWithEcho, _selectedCodecName);
|
||||
QByteArray audioBuffer(audio);
|
||||
handleAudioInput(audioBuffer);
|
||||
}
|
||||
|
||||
void AudioClient::prepareLocalAudioInjectors() {
|
||||
|
@ -1434,7 +1407,7 @@ bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo& inputDeviceIn
|
|||
lock.unlock();
|
||||
|
||||
if (_inputDevice) {
|
||||
connect(_inputDevice, SIGNAL(readyRead()), this, SLOT(handleAudioInput()));
|
||||
connect(_inputDevice, SIGNAL(readyRead()), this, SLOT(handleMicAudioInput()));
|
||||
supportedFormat = true;
|
||||
} else {
|
||||
qCDebug(audioclient) << "Error starting audio input -" << _audioInput->error();
|
||||
|
@ -1540,12 +1513,39 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo& outputDevice
|
|||
// setup our general output device for audio-mixer audio
|
||||
_audioOutput = new QAudioOutput(outputDeviceInfo, _outputFormat, this);
|
||||
|
||||
int osDefaultBufferSize = _audioOutput->bufferSize();
|
||||
int deviceChannelCount = _outputFormat.channelCount();
|
||||
int deviceFrameSize = (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * deviceChannelCount * _outputFormat.sampleRate()) / _desiredOutputFormat.sampleRate();
|
||||
int requestedSize = _sessionOutputBufferSizeFrames * deviceFrameSize * AudioConstants::SAMPLE_SIZE;
|
||||
int frameSize = (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * deviceChannelCount * _outputFormat.sampleRate()) / _desiredOutputFormat.sampleRate();
|
||||
int requestedSize = _sessionOutputBufferSizeFrames * frameSize * AudioConstants::SAMPLE_SIZE;
|
||||
_audioOutput->setBufferSize(requestedSize);
|
||||
|
||||
// initialize mix buffers on the _audioOutput thread to avoid races
|
||||
connect(_audioOutput, &QAudioOutput::stateChanged, [&, frameSize, requestedSize](QAudio::State state) {
|
||||
if (state == QAudio::ActiveState) {
|
||||
// restrict device callback to _outputPeriod samples
|
||||
_outputPeriod = (_audioOutput->periodSize() / AudioConstants::SAMPLE_SIZE) * 2;
|
||||
_outputMixBuffer = new float[_outputPeriod];
|
||||
_outputScratchBuffer = new int16_t[_outputPeriod];
|
||||
|
||||
// size local output mix buffer based on resampled network frame size
|
||||
_networkPeriod = _localToOutputResampler->getMaxOutput(AudioConstants::NETWORK_FRAME_SAMPLES_STEREO);
|
||||
_localOutputMixBuffer = new float[_networkPeriod];
|
||||
int localPeriod = _outputPeriod * 2;
|
||||
_localInjectorsStream.resizeForFrameSize(localPeriod);
|
||||
|
||||
int bufferSize = _audioOutput->bufferSize();
|
||||
int bufferSamples = bufferSize / AudioConstants::SAMPLE_SIZE;
|
||||
int bufferFrames = bufferSamples / (float)frameSize;
|
||||
qCDebug(audioclient) << "frame (samples):" << frameSize;
|
||||
qCDebug(audioclient) << "buffer (frames):" << bufferFrames;
|
||||
qCDebug(audioclient) << "buffer (samples):" << bufferSamples;
|
||||
qCDebug(audioclient) << "buffer (bytes):" << bufferSize;
|
||||
qCDebug(audioclient) << "requested (bytes):" << requestedSize;
|
||||
qCDebug(audioclient) << "period (samples):" << _outputPeriod;
|
||||
qCDebug(audioclient) << "local buffer (samples):" << localPeriod;
|
||||
|
||||
disconnect(_audioOutput, &QAudioOutput::stateChanged, 0, 0);
|
||||
}
|
||||
});
|
||||
connect(_audioOutput, &QAudioOutput::notify, this, &AudioClient::outputNotify);
|
||||
|
||||
_audioOutputIODevice.start();
|
||||
|
@ -1555,18 +1555,6 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo& outputDevice
|
|||
_audioOutput->start(&_audioOutputIODevice);
|
||||
lock.unlock();
|
||||
|
||||
int periodSampleSize = _audioOutput->periodSize() / AudioConstants::SAMPLE_SIZE;
|
||||
// device callback is not restricted to periodSampleSize, so double the mix/scratch buffer sizes
|
||||
_outputPeriod = periodSampleSize * 2;
|
||||
_outputMixBuffer = new float[_outputPeriod];
|
||||
_outputScratchBuffer = new int16_t[_outputPeriod];
|
||||
_localOutputMixBuffer = new float[_outputPeriod];
|
||||
_localInjectorsStream.resizeForFrameSize(_outputPeriod * 2);
|
||||
|
||||
qCDebug(audioclient) << "Output Buffer capacity in frames: " << _audioOutput->bufferSize() / AudioConstants::SAMPLE_SIZE / (float)deviceFrameSize <<
|
||||
"requested bytes:" << requestedSize << "actual bytes:" << _audioOutput->bufferSize() <<
|
||||
"os default:" << osDefaultBufferSize << "period size:" << _audioOutput->periodSize();
|
||||
|
||||
// setup a loopback audio output device
|
||||
_loopbackAudioOutput = new QAudioOutput(outputDeviceInfo, _outputFormat, this);
|
||||
|
||||
|
|
|
@ -124,16 +124,16 @@ public:
|
|||
void selectAudioFormat(const QString& selectedCodecName);
|
||||
|
||||
Q_INVOKABLE QString getSelectedAudioFormat() const { return _selectedCodecName; }
|
||||
Q_INVOKABLE bool getNoiseGateOpen() const { return _inputGate.isOpen(); }
|
||||
Q_INVOKABLE float getSilentOutboundPPS() const { return _silentOutbound.rate(); }
|
||||
Q_INVOKABLE float getMicAudioOutboundPPS() const { return _micAudioOutbound.rate(); }
|
||||
Q_INVOKABLE bool getNoiseGateOpen() const { return _noiseGate.isOpen(); }
|
||||
Q_INVOKABLE float getSilentInboundPPS() const { return _silentInbound.rate(); }
|
||||
Q_INVOKABLE float getAudioInboundPPS() const { return _audioInbound.rate(); }
|
||||
Q_INVOKABLE float getSilentOutboundPPS() const { return _silentOutbound.rate(); }
|
||||
Q_INVOKABLE float getAudioOutboundPPS() const { return _audioOutbound.rate(); }
|
||||
|
||||
const MixedProcessedAudioStream& getReceivedAudioStream() const { return _receivedAudioStream; }
|
||||
MixedProcessedAudioStream& getReceivedAudioStream() { return _receivedAudioStream; }
|
||||
|
||||
float getLastInputLoudness() const { return glm::max(_lastInputLoudness - _inputGate.getMeasuredFloor(), 0.0f); }
|
||||
float getLastInputLoudness() const { return glm::max(_lastInputLoudness - _noiseGate.getMeasuredFloor(), 0.0f); }
|
||||
|
||||
float getTimeSinceLastClip() const { return _timeSinceLastClip; }
|
||||
float getAudioAverageInputLoudness() const { return _lastInputLoudness; }
|
||||
|
@ -180,7 +180,7 @@ public slots:
|
|||
void handleMismatchAudioFormat(SharedNodePointer node, const QString& currentCodec, const QString& recievedCodec);
|
||||
|
||||
void sendDownstreamAudioStatsPacket() { _stats.publish(); }
|
||||
void handleAudioInput();
|
||||
void handleMicAudioInput();
|
||||
void handleRecordedAudioInput(const QByteArray& audio);
|
||||
void reset();
|
||||
void audioMixerKilled();
|
||||
|
@ -250,6 +250,7 @@ protected:
|
|||
|
||||
private:
|
||||
void outputFormatChanged();
|
||||
void handleAudioInput(QByteArray& audioBuffer);
|
||||
bool mixLocalAudioInjectors(float* mixBuffer);
|
||||
float azimuthForSource(const glm::vec3& relativePosition);
|
||||
float gainForSource(float distance, float volume);
|
||||
|
@ -339,6 +340,7 @@ private:
|
|||
int16_t _networkScratchBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_AMBISONIC];
|
||||
|
||||
// for local audio (used by audio injectors thread)
|
||||
int _networkPeriod { 0 };
|
||||
float _localMixBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_STEREO];
|
||||
int16_t _localScratchBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_AMBISONIC];
|
||||
float* _localOutputMixBuffer { NULL };
|
||||
|
@ -371,7 +373,7 @@ private:
|
|||
|
||||
AudioIOStats _stats;
|
||||
|
||||
AudioNoiseGate _inputGate;
|
||||
AudioNoiseGate _noiseGate;
|
||||
|
||||
AudioPositionGetter _positionGetter;
|
||||
AudioOrientationGetter _orientationGetter;
|
||||
|
@ -395,7 +397,7 @@ private:
|
|||
QThread* _checkDevicesThread { nullptr };
|
||||
|
||||
RateCounter<> _silentOutbound;
|
||||
RateCounter<> _micAudioOutbound;
|
||||
RateCounter<> _audioOutbound;
|
||||
RateCounter<> _silentInbound;
|
||||
RateCounter<> _audioInbound;
|
||||
};
|
||||
|
|
|
@ -666,11 +666,8 @@ void RenderablePolyVoxEntityItem::setZTextureURL(QString zTextureURL) {
|
|||
}
|
||||
}
|
||||
|
||||
void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
||||
PerformanceTimer perfTimer("RenderablePolyVoxEntityItem::render");
|
||||
assert(getType() == EntityTypes::PolyVox);
|
||||
Q_ASSERT(args->_batch);
|
||||
|
||||
bool RenderablePolyVoxEntityItem::updateDependents() {
|
||||
bool voxelDataDirty;
|
||||
bool volDataDirty;
|
||||
withWriteLock([&] {
|
||||
|
@ -688,6 +685,17 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
|||
recomputeMesh();
|
||||
}
|
||||
|
||||
return !volDataDirty;
|
||||
}
|
||||
|
||||
|
||||
void RenderablePolyVoxEntityItem::render(RenderArgs* args) {
|
||||
PerformanceTimer perfTimer("RenderablePolyVoxEntityItem::render");
|
||||
assert(getType() == EntityTypes::PolyVox);
|
||||
Q_ASSERT(args->_batch);
|
||||
|
||||
updateDependents();
|
||||
|
||||
model::MeshPointer mesh;
|
||||
glm::vec3 voxelVolumeSize;
|
||||
withReadLock([&] {
|
||||
|
@ -1584,14 +1592,22 @@ void RenderablePolyVoxEntityItem::locationChanged(bool tellPhysics) {
|
|||
scene->enqueuePendingChanges(pendingChanges);
|
||||
}
|
||||
|
||||
bool RenderablePolyVoxEntityItem::getMeshAsScriptValue(QScriptEngine *engine, QScriptValue& result) const {
|
||||
bool RenderablePolyVoxEntityItem::getMeshAsScriptValue(QScriptEngine *engine, QScriptValue& result) {
|
||||
if (!updateDependents()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
MeshProxy* meshProxy = nullptr;
|
||||
model::MeshPointer mesh = nullptr;
|
||||
glm::mat4 transform = voxelToLocalMatrix();
|
||||
withReadLock([&] {
|
||||
if (_meshInitialized) {
|
||||
success = true;
|
||||
meshProxy = new MeshProxy(_mesh);
|
||||
// the mesh will be in voxel-space. transform it into object-space
|
||||
meshProxy = new MeshProxy(
|
||||
_mesh->map([=](glm::vec3 position){ return glm::vec3(transform * glm::vec4(position, 1.0f)); },
|
||||
[=](glm::vec3 normal){ return glm::vec3(transform * glm::vec4(normal, 0.0f)); },
|
||||
[](uint32_t index){ return index; }));
|
||||
}
|
||||
});
|
||||
result = meshToScriptValue(engine, meshProxy);
|
||||
|
|
|
@ -61,6 +61,8 @@ public:
|
|||
virtual uint8_t getVoxel(int x, int y, int z) override;
|
||||
virtual bool setVoxel(int x, int y, int z, uint8_t toValue) override;
|
||||
|
||||
int getOnCount() const override { return _onCount; }
|
||||
|
||||
void render(RenderArgs* args) override;
|
||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
|
@ -133,7 +135,7 @@ public:
|
|||
QByteArray volDataToArray(quint16 voxelXSize, quint16 voxelYSize, quint16 voxelZSize) const;
|
||||
|
||||
void setMesh(model::MeshPointer mesh);
|
||||
bool getMeshAsScriptValue(QScriptEngine *engine, QScriptValue& result) const override;
|
||||
bool getMeshAsScriptValue(QScriptEngine *engine, QScriptValue& result) override;
|
||||
void setCollisionPoints(ShapeInfo::PointCollection points, AABox box);
|
||||
PolyVox::SimpleVolume<uint8_t>* getVolData() { return _volData; }
|
||||
|
||||
|
@ -193,6 +195,7 @@ private:
|
|||
void cacheNeighbors();
|
||||
void copyUpperEdgesFromNeighbors();
|
||||
void bonkNeighbors();
|
||||
bool updateDependents();
|
||||
};
|
||||
|
||||
bool inUserBounds(const PolyVox::SimpleVolume<uint8_t>* vol, PolyVoxEntityItem::PolyVoxSurfaceStyle surfaceStyle,
|
||||
|
|
|
@ -49,13 +49,6 @@ EntityItemProperties::EntityItemProperties(EntityPropertyFlags desiredProperties
|
|||
|
||||
}
|
||||
|
||||
void EntityItemProperties::setSittingPoints(const QVector<SittingPoint>& sittingPoints) {
|
||||
_sittingPoints.clear();
|
||||
foreach (SittingPoint sitPoint, sittingPoints) {
|
||||
_sittingPoints.append(sitPoint);
|
||||
}
|
||||
}
|
||||
|
||||
void EntityItemProperties::calculateNaturalPosition(const glm::vec3& min, const glm::vec3& max) {
|
||||
glm::vec3 halfDimension = (max - min) / 2.0f;
|
||||
_naturalPosition = max - halfDimension;
|
||||
|
@ -546,20 +539,6 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
|||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures);
|
||||
}
|
||||
|
||||
// Sitting properties support
|
||||
if (!skipDefaults && !strictSemantics) {
|
||||
QScriptValue sittingPoints = engine->newObject();
|
||||
for (int i = 0; i < _sittingPoints.size(); ++i) {
|
||||
QScriptValue sittingPoint = engine->newObject();
|
||||
sittingPoint.setProperty("name", _sittingPoints.at(i).name);
|
||||
sittingPoint.setProperty("position", vec3toScriptValue(engine, _sittingPoints.at(i).position));
|
||||
sittingPoint.setProperty("rotation", quatToScriptValue(engine, _sittingPoints.at(i).rotation));
|
||||
sittingPoints.setProperty(i, sittingPoint);
|
||||
}
|
||||
sittingPoints.setProperty("length", _sittingPoints.size());
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_ALWAYS(sittingPoints, sittingPoints); // gettable, but not settable
|
||||
}
|
||||
|
||||
if (!skipDefaults && !strictSemantics) {
|
||||
AABox aaBox = getAABox();
|
||||
QScriptValue boundingBox = engine->newObject();
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include <QString>
|
||||
|
||||
#include <AACube.h>
|
||||
#include <FBXReader.h> // for SittingPoint
|
||||
#include <NumericalConstants.h>
|
||||
#include <PropertyFlags.h>
|
||||
#include <OctreeConstants.h>
|
||||
|
@ -255,8 +254,6 @@ public:
|
|||
void clearID() { _id = UNKNOWN_ENTITY_ID; _idSet = false; }
|
||||
void markAllChanged();
|
||||
|
||||
void setSittingPoints(const QVector<SittingPoint>& sittingPoints);
|
||||
|
||||
const glm::vec3& getNaturalDimensions() const { return _naturalDimensions; }
|
||||
void setNaturalDimensions(const glm::vec3& value) { _naturalDimensions = value; }
|
||||
|
||||
|
@ -325,7 +322,6 @@ private:
|
|||
|
||||
// NOTE: The following are pseudo client only properties. They are only used in clients which can access
|
||||
// properties of model geometry. But these properties are not serialized like other properties.
|
||||
QVector<SittingPoint> _sittingPoints;
|
||||
QVariantMap _textureNames;
|
||||
glm::vec3 _naturalDimensions;
|
||||
glm::vec3 _naturalPosition;
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtx/transform.hpp>
|
||||
|
||||
#include "EntityScriptingInterface.h"
|
||||
|
||||
#include <QFutureWatcher>
|
||||
|
@ -292,13 +296,11 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit
|
|||
|
||||
results = entity->getProperties(desiredProperties);
|
||||
|
||||
// TODO: improve sitting points and naturalDimensions in the future,
|
||||
// for now we've included the old sitting points model behavior for entity types that are models
|
||||
// we've also added this hack for setting natural dimensions of models
|
||||
// TODO: improve naturalDimensions in the future,
|
||||
// for now we've added this hack for setting natural dimensions of models
|
||||
if (entity->getType() == EntityTypes::Model) {
|
||||
const FBXGeometry* geometry = _entityTree->getGeometryForEntity(entity);
|
||||
if (geometry) {
|
||||
results.setSittingPoints(geometry->sittingPoints);
|
||||
Extents meshExtents = geometry->getUnscaledMeshExtents();
|
||||
results.setNaturalDimensions(meshExtents.maximum - meshExtents.minimum);
|
||||
results.calculateNaturalPosition(meshExtents.minimum, meshExtents.maximum);
|
||||
|
@ -1041,13 +1043,20 @@ bool EntityScriptingInterface::setVoxelsInCuboid(QUuid entityID, const glm::vec3
|
|||
void EntityScriptingInterface::voxelsToMesh(QUuid entityID, QScriptValue callback) {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
|
||||
polyVoxWorker(entityID, [callback](PolyVoxEntityItem& polyVoxEntity) mutable {
|
||||
QScriptValue mesh;
|
||||
polyVoxEntity.getMeshAsScriptValue(callback.engine(), mesh);
|
||||
QScriptValueList args { mesh };
|
||||
callback.call(QScriptValue(), args);
|
||||
bool success { false };
|
||||
QScriptValue mesh { false };
|
||||
|
||||
polyVoxWorker(entityID, [&](PolyVoxEntityItem& polyVoxEntity) mutable {
|
||||
if (polyVoxEntity.getOnCount() == 0) {
|
||||
success = true;
|
||||
} else {
|
||||
success = polyVoxEntity.getMeshAsScriptValue(callback.engine(), mesh);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
QScriptValueList args { mesh, success };
|
||||
callback.call(QScriptValue(), args);
|
||||
}
|
||||
|
||||
bool EntityScriptingInterface::setAllPoints(QUuid entityID, const QVector<glm::vec3>& points) {
|
||||
|
@ -1665,3 +1674,20 @@ bool EntityScriptingInterface::AABoxIntersectsCapsule(const glm::vec3& low, cons
|
|||
AABox aaBox(low, dimensions);
|
||||
return aaBox.findCapsulePenetration(start, end, radius, penetration);
|
||||
}
|
||||
|
||||
glm::mat4 EntityScriptingInterface::getEntityTransform(const QUuid& entityID) {
|
||||
glm::mat4 result;
|
||||
if (_entityTree) {
|
||||
_entityTree->withReadLock([&] {
|
||||
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(entityID));
|
||||
if (entity) {
|
||||
glm::mat4 translation = glm::translate(entity->getPosition());
|
||||
glm::mat4 rotation = glm::mat4_cast(entity->getRotation());
|
||||
glm::mat4 registration = glm::translate(ENTITY_ITEM_DEFAULT_REGISTRATION_POINT -
|
||||
entity->getRegistrationPoint());
|
||||
result = translation * rotation * registration;
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -331,6 +331,15 @@ public slots:
|
|||
const glm::vec3& start, const glm::vec3& end, float radius);
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* Returns object to world transform, excluding scale
|
||||
*
|
||||
* @function Entities.getEntityTransform
|
||||
* @param {EntityID} entityID The ID of the entity whose transform is to be returned
|
||||
* @return {Mat4} Entity's object to world transform, excluding scale
|
||||
*/
|
||||
Q_INVOKABLE glm::mat4 getEntityTransform(const QUuid& entityID);
|
||||
|
||||
signals:
|
||||
void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
||||
|
||||
|
|
|
@ -243,6 +243,6 @@ const QByteArray PolyVoxEntityItem::getVoxelData() const {
|
|||
return voxelDataCopy;
|
||||
}
|
||||
|
||||
bool PolyVoxEntityItem::getMeshAsScriptValue(QScriptEngine *engine, QScriptValue& result) const {
|
||||
bool PolyVoxEntityItem::getMeshAsScriptValue(QScriptEngine *engine, QScriptValue& result) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -57,6 +57,8 @@ class PolyVoxEntityItem : public EntityItem {
|
|||
virtual void setVoxelData(QByteArray voxelData);
|
||||
virtual const QByteArray getVoxelData() const;
|
||||
|
||||
virtual int getOnCount() const { return 0; }
|
||||
|
||||
enum PolyVoxSurfaceStyle {
|
||||
SURFACE_MARCHING_CUBES,
|
||||
SURFACE_CUBIC,
|
||||
|
@ -133,7 +135,7 @@ class PolyVoxEntityItem : public EntityItem {
|
|||
void setVoxelDataDirty(bool value) { withWriteLock([&] { _voxelDataDirty = value; }); }
|
||||
virtual void recomputeMesh() {};
|
||||
|
||||
virtual bool getMeshAsScriptValue(QScriptEngine *engine, QScriptValue& result) const;
|
||||
virtual bool getMeshAsScriptValue(QScriptEngine *engine, QScriptValue& result);
|
||||
|
||||
protected:
|
||||
glm::vec3 _voxelVolumeSize; // this is always 3 bytes
|
||||
|
|
|
@ -14,9 +14,11 @@
|
|||
|
||||
#include <QtScript/QScriptEngine>
|
||||
|
||||
//#include "EntityItemProperties.h"
|
||||
#include <OctreeElement.h>
|
||||
|
||||
#include "EntityPropertyFlags.h"
|
||||
|
||||
|
||||
class EntityItemProperties;
|
||||
class EncodeBitstreamParams;
|
||||
class OctreePacketData;
|
||||
|
@ -24,31 +26,6 @@ class EntityTreeElementExtraEncodeData;
|
|||
class ReadBitstreamToTreeParams;
|
||||
using EntityTreeElementExtraEncodeDataPointer = std::shared_ptr<EntityTreeElementExtraEncodeData>;
|
||||
|
||||
#include <OctreeElement.h>
|
||||
|
||||
/*
|
||||
#include <stdint.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtx/extented_min_max.hpp>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QVector>
|
||||
#include <QString>
|
||||
|
||||
#include <AACube.h>
|
||||
#include <FBXReader.h> // for SittingPoint
|
||||
#include <PropertyFlags.h>
|
||||
#include <OctreeConstants.h>
|
||||
#include <ShapeInfo.h>
|
||||
|
||||
#include "EntityItemID.h"
|
||||
#include "PropertyGroupMacros.h"
|
||||
#include "EntityTypes.h"
|
||||
*/
|
||||
|
||||
//typedef PropertyFlags<EntityPropertyList> EntityPropertyFlags;
|
||||
|
||||
|
||||
class PropertyGroup {
|
||||
public:
|
||||
|
|
|
@ -1799,19 +1799,6 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
}
|
||||
geometry.palmDirection = parseVec3(mapping.value("palmDirection", "0, -1, 0").toString());
|
||||
|
||||
// Add sitting points
|
||||
QVariantHash sittingPoints = mapping.value("sit").toHash();
|
||||
for (QVariantHash::const_iterator it = sittingPoints.constBegin(); it != sittingPoints.constEnd(); it++) {
|
||||
SittingPoint sittingPoint;
|
||||
sittingPoint.name = it.key();
|
||||
|
||||
QVariantList properties = it->toList();
|
||||
sittingPoint.position = parseVec3(properties.at(0).toString());
|
||||
sittingPoint.rotation = glm::quat(glm::radians(parseVec3(properties.at(1).toString())));
|
||||
|
||||
geometry.sittingPoints.append(sittingPoint);
|
||||
}
|
||||
|
||||
// attempt to map any meshes to a named model
|
||||
for (QHash<QString, int>::const_iterator m = meshIDsToMeshIndices.constBegin();
|
||||
m != meshIDsToMeshIndices.constEnd(); m++) {
|
||||
|
|
|
@ -265,24 +265,6 @@ public:
|
|||
Q_DECLARE_METATYPE(FBXAnimationFrame)
|
||||
Q_DECLARE_METATYPE(QVector<FBXAnimationFrame>)
|
||||
|
||||
/// A point where an avatar can sit
|
||||
class SittingPoint {
|
||||
public:
|
||||
QString name;
|
||||
glm::vec3 position; // relative postion
|
||||
glm::quat rotation; // relative orientation
|
||||
};
|
||||
|
||||
inline bool operator==(const SittingPoint& lhs, const SittingPoint& rhs)
|
||||
{
|
||||
return (lhs.name == rhs.name) && (lhs.position == rhs.position) && (lhs.rotation == rhs.rotation);
|
||||
}
|
||||
|
||||
inline bool operator!=(const SittingPoint& lhs, const SittingPoint& rhs)
|
||||
{
|
||||
return (lhs.name != rhs.name) || (lhs.position != rhs.position) || (lhs.rotation != rhs.rotation);
|
||||
}
|
||||
|
||||
/// A set of meshes extracted from an FBX document.
|
||||
class FBXGeometry {
|
||||
public:
|
||||
|
@ -320,8 +302,6 @@ public:
|
|||
|
||||
glm::vec3 palmDirection;
|
||||
|
||||
QVector<SittingPoint> sittingPoints;
|
||||
|
||||
glm::vec3 neckPivot;
|
||||
|
||||
Extents bindExtents;
|
||||
|
|
|
@ -267,7 +267,7 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) {
|
|||
}
|
||||
if (token == "map_Kd") {
|
||||
currentMaterial.diffuseTextureFilename = filename;
|
||||
} else {
|
||||
} else if( token == "map_Ks" ) {
|
||||
currentMaterial.specularTextureFilename = filename;
|
||||
}
|
||||
}
|
||||
|
@ -612,6 +612,9 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping,
|
|||
if (!objMaterial.diffuseTextureFilename.isEmpty()) {
|
||||
fbxMaterial.albedoTexture.filename = objMaterial.diffuseTextureFilename;
|
||||
}
|
||||
if (!objMaterial.specularTextureFilename.isEmpty()) {
|
||||
fbxMaterial.specularTexture.filename = objMaterial.specularTextureFilename;
|
||||
}
|
||||
|
||||
modelMaterial->setEmissive(fbxMaterial.emissiveColor);
|
||||
modelMaterial->setAlbedo(fbxMaterial.diffuseColor);
|
||||
|
|
|
@ -198,7 +198,7 @@ public:
|
|||
BufferView(const BufferPointer& buffer, Size offset, Size size, const Element& element = DEFAULT_ELEMENT);
|
||||
BufferView(const BufferPointer& buffer, Size offset, Size size, uint16 stride, const Element& element = DEFAULT_ELEMENT);
|
||||
|
||||
Size getNumElements() const { return _size / _element.getSize(); }
|
||||
Size getNumElements() const { return (_size - _offset) / _stride; }
|
||||
|
||||
//Template iterator with random access on the buffer sysmem
|
||||
template<typename T>
|
||||
|
|
|
@ -762,8 +762,17 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector<
|
|||
for(int face=0; face < gpu::Texture::NUM_CUBE_FACES; face++) {
|
||||
PROFILE_RANGE(render_gpu, "ProcessFace");
|
||||
|
||||
auto numComponents = cubeTexture.getStoredMipFormat().getScalarCount();
|
||||
auto data = cubeTexture.accessStoredMipFace(0,face)->data();
|
||||
auto mipFormat = cubeTexture.accessStoredMipFace(0, face)->getFormat();
|
||||
auto numComponents = mipFormat.getScalarCount();
|
||||
int roffset { 0 };
|
||||
int goffset { 1 };
|
||||
int boffset { 2 };
|
||||
if ((mipFormat.getSemantic() == gpu::BGRA) || (mipFormat.getSemantic() == gpu::SBGRA)) {
|
||||
roffset = 2;
|
||||
boffset = 0;
|
||||
}
|
||||
|
||||
auto data = cubeTexture.accessStoredMipFace(0,face)->readData();
|
||||
if (data == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
@ -850,9 +859,9 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector<
|
|||
for (int i = 0; i < stride; ++i) {
|
||||
for (int j = 0; j < stride; ++j) {
|
||||
int k = (int)(x + i - halfStride + (y + j - halfStride) * width) * numComponents;
|
||||
red += ColorUtils::sRGB8ToLinearFloat(data[k]);
|
||||
green += ColorUtils::sRGB8ToLinearFloat(data[k + 1]);
|
||||
blue += ColorUtils::sRGB8ToLinearFloat(data[k + 2]);
|
||||
red += ColorUtils::sRGB8ToLinearFloat(data[k + roffset]);
|
||||
green += ColorUtils::sRGB8ToLinearFloat(data[k + goffset]);
|
||||
blue += ColorUtils::sRGB8ToLinearFloat(data[k + boffset]);
|
||||
}
|
||||
}
|
||||
glm::vec3 clr(red, green, blue);
|
||||
|
@ -879,8 +888,6 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector<
|
|||
|
||||
// save result
|
||||
for(uint i=0; i < sqOrder; i++) {
|
||||
// gamma Correct
|
||||
// output[i] = linearTosRGB(glm::vec3(resultR[i], resultG[i], resultB[i]));
|
||||
output[i] = glm::vec3(resultR[i], resultG[i], resultB[i]);
|
||||
}
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ Box Mesh::evalPartsBound(int partStart, int partEnd) const {
|
|||
auto partItEnd = _partBuffer.cbegin<Part>() + partEnd;
|
||||
|
||||
for (;part != partItEnd; part++) {
|
||||
|
||||
|
||||
Box partBound;
|
||||
auto index = _indexBuffer.cbegin<uint>() + (*part)._startIndex;
|
||||
auto endIndex = index + (*part)._numIndices;
|
||||
|
@ -134,6 +134,115 @@ Box Mesh::evalPartsBound(int partStart, int partEnd) const {
|
|||
return totalBound;
|
||||
}
|
||||
|
||||
|
||||
model::MeshPointer Mesh::map(std::function<glm::vec3(glm::vec3)> vertexFunc,
|
||||
std::function<glm::vec3(glm::vec3)> normalFunc,
|
||||
std::function<uint32_t(uint32_t)> indexFunc) {
|
||||
// vertex data
|
||||
const gpu::BufferView& vertexBufferView = getVertexBuffer();
|
||||
gpu::BufferView::Index numVertices = (gpu::BufferView::Index)getNumVertices();
|
||||
gpu::Resource::Size vertexSize = numVertices * sizeof(glm::vec3);
|
||||
unsigned char* resultVertexData = new unsigned char[vertexSize];
|
||||
unsigned char* vertexDataCursor = resultVertexData;
|
||||
|
||||
for (gpu::BufferView::Index i = 0; i < numVertices; i ++) {
|
||||
glm::vec3 pos = vertexFunc(vertexBufferView.get<glm::vec3>(i));
|
||||
memcpy(vertexDataCursor, &pos, sizeof(pos));
|
||||
vertexDataCursor += sizeof(pos);
|
||||
}
|
||||
|
||||
// normal data
|
||||
int attributeTypeNormal = gpu::Stream::InputSlot::NORMAL; // libraries/gpu/src/gpu/Stream.h
|
||||
const gpu::BufferView& normalsBufferView = getAttributeBuffer(attributeTypeNormal);
|
||||
gpu::BufferView::Index numNormals = (gpu::BufferView::Index)normalsBufferView.getNumElements();
|
||||
gpu::Resource::Size normalSize = numNormals * sizeof(glm::vec3);
|
||||
unsigned char* resultNormalData = new unsigned char[normalSize];
|
||||
unsigned char* normalDataCursor = resultNormalData;
|
||||
|
||||
for (gpu::BufferView::Index i = 0; i < numNormals; i ++) {
|
||||
glm::vec3 normal = normalFunc(normalsBufferView.get<glm::vec3>(i));
|
||||
memcpy(normalDataCursor, &normal, sizeof(normal));
|
||||
normalDataCursor += sizeof(normal);
|
||||
}
|
||||
// TODO -- other attributes
|
||||
|
||||
// face data
|
||||
const gpu::BufferView& indexBufferView = getIndexBuffer();
|
||||
gpu::BufferView::Index numIndexes = (gpu::BufferView::Index)getNumIndices();
|
||||
gpu::Resource::Size indexSize = numIndexes * sizeof(uint32_t);
|
||||
unsigned char* resultIndexData = new unsigned char[indexSize];
|
||||
unsigned char* indexDataCursor = resultIndexData;
|
||||
|
||||
for (gpu::BufferView::Index i = 0; i < numIndexes; i ++) {
|
||||
uint32_t index = indexFunc(indexBufferView.get<uint32_t>(i));
|
||||
memcpy(indexDataCursor, &index, sizeof(index));
|
||||
indexDataCursor += sizeof(index);
|
||||
}
|
||||
|
||||
model::MeshPointer result(new model::Mesh());
|
||||
|
||||
gpu::Element vertexElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);
|
||||
gpu::Buffer* resultVertexBuffer = new gpu::Buffer(vertexSize, resultVertexData);
|
||||
gpu::BufferPointer resultVertexBufferPointer(resultVertexBuffer);
|
||||
gpu::BufferView resultVertexBufferView(resultVertexBufferPointer, vertexElement);
|
||||
result->setVertexBuffer(resultVertexBufferView);
|
||||
|
||||
gpu::Element normalElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);
|
||||
gpu::Buffer* resultNormalsBuffer = new gpu::Buffer(normalSize, resultNormalData);
|
||||
gpu::BufferPointer resultNormalsBufferPointer(resultNormalsBuffer);
|
||||
gpu::BufferView resultNormalsBufferView(resultNormalsBufferPointer, normalElement);
|
||||
result->addAttribute(attributeTypeNormal, resultNormalsBufferView);
|
||||
|
||||
gpu::Element indexElement = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::RAW);
|
||||
gpu::Buffer* resultIndexesBuffer = new gpu::Buffer(indexSize, resultIndexData);
|
||||
gpu::BufferPointer resultIndexesBufferPointer(resultIndexesBuffer);
|
||||
gpu::BufferView resultIndexesBufferView(resultIndexesBufferPointer, indexElement);
|
||||
result->setIndexBuffer(resultIndexesBufferView);
|
||||
|
||||
|
||||
// TODO -- shouldn't assume just one part
|
||||
|
||||
std::vector<model::Mesh::Part> parts;
|
||||
parts.emplace_back(model::Mesh::Part((model::Index)0, // startIndex
|
||||
(model::Index)result->getNumIndices(), // numIndices
|
||||
(model::Index)0, // baseVertex
|
||||
model::Mesh::TRIANGLES)); // topology
|
||||
result->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part),
|
||||
(gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void Mesh::forEach(std::function<void(glm::vec3)> vertexFunc,
|
||||
std::function<void(glm::vec3)> normalFunc,
|
||||
std::function<void(uint32_t)> indexFunc) {
|
||||
int attributeTypeNormal = gpu::Stream::InputSlot::NORMAL; // libraries/gpu/src/gpu/Stream.h
|
||||
|
||||
// vertex data
|
||||
const gpu::BufferView& vertexBufferView = getVertexBuffer();
|
||||
gpu::BufferView::Index numVertices = (gpu::BufferView::Index)getNumVertices();
|
||||
for (gpu::BufferView::Index i = 0; i < numVertices; i ++) {
|
||||
vertexFunc(vertexBufferView.get<glm::vec3>(i));
|
||||
}
|
||||
|
||||
// normal data
|
||||
const gpu::BufferView& normalsBufferView = getAttributeBuffer(attributeTypeNormal);
|
||||
gpu::BufferView::Index numNormals = (gpu::BufferView::Index) normalsBufferView.getNumElements();
|
||||
for (gpu::BufferView::Index i = 0; i < numNormals; i ++) {
|
||||
normalFunc(normalsBufferView.get<glm::vec3>(i));
|
||||
}
|
||||
// TODO -- other attributes
|
||||
|
||||
// face data
|
||||
const gpu::BufferView& indexBufferView = getIndexBuffer();
|
||||
gpu::BufferView::Index numIndexes = (gpu::BufferView::Index)getNumIndices();
|
||||
for (gpu::BufferView::Index i = 0; i < numIndexes; i ++) {
|
||||
indexFunc(indexBufferView.get<uint32_t>(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Geometry::Geometry() {
|
||||
}
|
||||
|
||||
|
@ -148,4 +257,3 @@ Geometry::~Geometry() {
|
|||
void Geometry::setMesh(const MeshPointer& mesh) {
|
||||
_mesh = mesh;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,10 @@ typedef AABox Box;
|
|||
typedef std::vector< Box > Boxes;
|
||||
typedef glm::vec3 Vec3;
|
||||
|
||||
class Mesh;
|
||||
using MeshPointer = std::shared_ptr< Mesh >;
|
||||
|
||||
|
||||
class Mesh {
|
||||
public:
|
||||
const static Index PRIMITIVE_RESTART_INDEX = -1;
|
||||
|
@ -114,6 +118,15 @@ public:
|
|||
|
||||
static gpu::Primitive topologyToPrimitive(Topology topo) { return static_cast<gpu::Primitive>(topo); }
|
||||
|
||||
// create a copy of this mesh after passing its vertices, normals, and indexes though the provided functions
|
||||
MeshPointer map(std::function<glm::vec3(glm::vec3)> vertexFunc,
|
||||
std::function<glm::vec3(glm::vec3)> normalFunc,
|
||||
std::function<uint32_t(uint32_t)> indexFunc);
|
||||
|
||||
void forEach(std::function<void(glm::vec3)> vertexFunc,
|
||||
std::function<void(glm::vec3)> normalFunc,
|
||||
std::function<void(uint32_t)> indexFunc);
|
||||
|
||||
protected:
|
||||
|
||||
gpu::Stream::FormatPointer _vertexFormat;
|
||||
|
@ -130,7 +143,6 @@ protected:
|
|||
void evalVertexStream();
|
||||
|
||||
};
|
||||
using MeshPointer = std::shared_ptr< Mesh >;
|
||||
|
||||
|
||||
class Geometry {
|
||||
|
|
|
@ -30,9 +30,8 @@ vec3 fresnelSchlickAmbient(vec3 fresnelColor, vec3 lightDir, vec3 halfDir, float
|
|||
<$declareSkyboxMap()$>
|
||||
<@endif@>
|
||||
|
||||
vec3 evalAmbientSpecularIrradiance(LightAmbient ambient, vec3 fragEyeDir, vec3 fragNormal, float roughness, vec3 fresnel) {
|
||||
vec3 evalAmbientSpecularIrradiance(LightAmbient ambient, vec3 fragEyeDir, vec3 fragNormal, float roughness) {
|
||||
vec3 direction = -reflect(fragEyeDir, fragNormal);
|
||||
vec3 ambientFresnel = fresnelSchlickAmbient(fresnel, fragEyeDir, fragNormal, 1.0 - roughness);
|
||||
vec3 specularLight;
|
||||
<@if supportIfAmbientMapElseAmbientSphere@>
|
||||
if (getLightHasAmbientMap(ambient))
|
||||
|
@ -53,7 +52,7 @@ vec3 evalAmbientSpecularIrradiance(LightAmbient ambient, vec3 fragEyeDir, vec3 f
|
|||
}
|
||||
<@endif@>
|
||||
|
||||
return specularLight * ambientFresnel;
|
||||
return specularLight;
|
||||
}
|
||||
<@endfunc@>
|
||||
|
||||
|
@ -74,12 +73,14 @@ void evalLightingAmbient(out vec3 diffuse, out vec3 specular, LightAmbient ambie
|
|||
<@endif@>
|
||||
) {
|
||||
|
||||
// Fresnel
|
||||
vec3 ambientFresnel = fresnelSchlickAmbient(fresnel, eyeDir, normal, 1.0 - roughness);
|
||||
|
||||
// Diffuse from ambient
|
||||
diffuse = (1.0 - metallic) * sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(ambient), normal).xyz;
|
||||
diffuse = (1.0 - metallic) * (vec3(1.0) - ambientFresnel) * sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(ambient), normal).xyz;
|
||||
|
||||
// Specular highlight from ambient
|
||||
specular = evalAmbientSpecularIrradiance(ambient, eyeDir, normal, roughness, fresnel) * obscurance * getLightAmbientIntensity(ambient);
|
||||
|
||||
specular = evalAmbientSpecularIrradiance(ambient, eyeDir, normal, roughness) * ambientFresnel;
|
||||
|
||||
<@if supportScattering@>
|
||||
float ambientOcclusion = curvatureAO(lowNormalCurvature.w * 20.0f) * 0.5f;
|
||||
|
|
|
@ -75,7 +75,7 @@ void main(void) {
|
|||
vec4(1.0, 1.0, 0.0, 1.0)
|
||||
);
|
||||
|
||||
const vec2 ICON_PIXEL_SIZE = vec2(20, 20);
|
||||
const vec2 ICON_PIXEL_SIZE = vec2(36, 36);
|
||||
const vec2 MARGIN_PIXEL_SIZE = vec2(2, 2);
|
||||
const vec2 ICON_GRID_SLOTS[MAX_NUM_ICONS] = vec2[MAX_NUM_ICONS](vec2(-1.5, 0.5),
|
||||
vec2(-0.5, 0.5),
|
||||
|
@ -114,7 +114,7 @@ void main(void) {
|
|||
varColor = vec4(paintRainbow(abs(iconStatus.y)), 1.0);
|
||||
|
||||
// Pass the texcoord and the z texcoord is representing the texture icon
|
||||
varTexcoord = vec3((quadPos.xy + 1.0) * 0.5, iconStatus.z);
|
||||
varTexcoord = vec3( (quadPos.x + 1.0) * 0.5, (quadPos.y + 1.0) * -0.5, iconStatus.z);
|
||||
|
||||
// Also changes the size of the notification
|
||||
vec2 iconScale = ICON_PIXEL_SIZE;
|
||||
|
|
|
@ -19,11 +19,6 @@ void registerAudioMetaTypes(QScriptEngine* engine) {
|
|||
qScriptRegisterMetaType(engine, soundSharedPointerToScriptValue, soundSharedPointerFromScriptValue);
|
||||
}
|
||||
|
||||
AudioScriptingInterface& AudioScriptingInterface::getInstance() {
|
||||
static AudioScriptingInterface staticInstance;
|
||||
return staticInstance;
|
||||
}
|
||||
|
||||
AudioScriptingInterface::AudioScriptingInterface() :
|
||||
_localAudioInterface(NULL)
|
||||
{
|
||||
|
|
|
@ -14,18 +14,20 @@
|
|||
|
||||
#include <AbstractAudioInterface.h>
|
||||
#include <AudioInjector.h>
|
||||
#include <DependencyManager.h>
|
||||
#include <Sound.h>
|
||||
|
||||
class ScriptAudioInjector;
|
||||
|
||||
class AudioScriptingInterface : public QObject {
|
||||
class AudioScriptingInterface : public QObject, public Dependency {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static AudioScriptingInterface& getInstance();
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
public:
|
||||
void setLocalAudioInterface(AbstractAudioInterface* audioInterface) { _localAudioInterface = audioInterface; }
|
||||
|
||||
protected:
|
||||
|
||||
// this method is protected to stop C++ callers from calling, but invokable from script
|
||||
Q_INVOKABLE ScriptAudioInjector* playSound(SharedSoundPointer sound, const AudioInjectorOptions& injectorOptions = AudioInjectorOptions());
|
||||
|
||||
|
@ -42,6 +44,7 @@ signals:
|
|||
|
||||
private:
|
||||
AudioScriptingInterface();
|
||||
|
||||
AbstractAudioInterface* _localAudioInterface;
|
||||
};
|
||||
|
||||
|
|
|
@ -12,11 +12,12 @@
|
|||
#include <QScriptEngine>
|
||||
#include <QScriptValueIterator>
|
||||
#include <QtScript/QScriptValue>
|
||||
#include "ScriptEngine.h"
|
||||
#include "ModelScriptingInterface.h"
|
||||
#include "OBJWriter.h"
|
||||
|
||||
|
||||
ModelScriptingInterface::ModelScriptingInterface(QObject* parent) : QObject(parent) {
|
||||
_modelScriptEngine = qobject_cast<ScriptEngine*>(parent);
|
||||
}
|
||||
|
||||
QScriptValue meshToScriptValue(QScriptEngine* engine, MeshProxy* const &in) {
|
||||
|
@ -51,3 +52,108 @@ QString ModelScriptingInterface::meshToOBJ(MeshProxyList in) {
|
|||
|
||||
return writeOBJToString(meshes);
|
||||
}
|
||||
|
||||
QScriptValue ModelScriptingInterface::appendMeshes(MeshProxyList in) {
|
||||
// figure out the size of the resulting mesh
|
||||
size_t totalVertexCount { 0 };
|
||||
size_t totalAttributeCount { 0 };
|
||||
size_t totalIndexCount { 0 };
|
||||
foreach (const MeshProxy* meshProxy, in) {
|
||||
MeshPointer mesh = meshProxy->getMeshPointer();
|
||||
totalVertexCount += mesh->getNumVertices();
|
||||
|
||||
int attributeTypeNormal = gpu::Stream::InputSlot::NORMAL; // libraries/gpu/src/gpu/Stream.h
|
||||
const gpu::BufferView& normalsBufferView = mesh->getAttributeBuffer(attributeTypeNormal);
|
||||
gpu::BufferView::Index numNormals = (gpu::BufferView::Index)normalsBufferView.getNumElements();
|
||||
totalAttributeCount += numNormals;
|
||||
|
||||
totalIndexCount += mesh->getNumIndices();
|
||||
}
|
||||
|
||||
// alloc the resulting mesh
|
||||
gpu::Resource::Size combinedVertexSize = totalVertexCount * sizeof(glm::vec3);
|
||||
unsigned char* combinedVertexData = new unsigned char[combinedVertexSize];
|
||||
unsigned char* combinedVertexDataCursor = combinedVertexData;
|
||||
|
||||
gpu::Resource::Size combinedNormalSize = totalAttributeCount * sizeof(glm::vec3);
|
||||
unsigned char* combinedNormalData = new unsigned char[combinedNormalSize];
|
||||
unsigned char* combinedNormalDataCursor = combinedNormalData;
|
||||
|
||||
gpu::Resource::Size combinedIndexSize = totalIndexCount * sizeof(uint32_t);
|
||||
unsigned char* combinedIndexData = new unsigned char[combinedIndexSize];
|
||||
unsigned char* combinedIndexDataCursor = combinedIndexData;
|
||||
|
||||
uint32_t indexStartOffset { 0 };
|
||||
|
||||
foreach (const MeshProxy* meshProxy, in) {
|
||||
MeshPointer mesh = meshProxy->getMeshPointer();
|
||||
mesh->forEach(
|
||||
[&](glm::vec3 position){
|
||||
memcpy(combinedVertexDataCursor, &position, sizeof(position));
|
||||
combinedVertexDataCursor += sizeof(position);
|
||||
},
|
||||
[&](glm::vec3 normal){
|
||||
memcpy(combinedNormalDataCursor, &normal, sizeof(normal));
|
||||
combinedNormalDataCursor += sizeof(normal);
|
||||
},
|
||||
[&](uint32_t index){
|
||||
index += indexStartOffset;
|
||||
memcpy(combinedIndexDataCursor, &index, sizeof(index));
|
||||
combinedIndexDataCursor += sizeof(index);
|
||||
});
|
||||
|
||||
gpu::BufferView::Index numVertices = (gpu::BufferView::Index)mesh->getNumVertices();
|
||||
indexStartOffset += numVertices;
|
||||
}
|
||||
|
||||
model::MeshPointer result(new model::Mesh());
|
||||
|
||||
gpu::Element vertexElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);
|
||||
gpu::Buffer* combinedVertexBuffer = new gpu::Buffer(combinedVertexSize, combinedVertexData);
|
||||
gpu::BufferPointer combinedVertexBufferPointer(combinedVertexBuffer);
|
||||
gpu::BufferView combinedVertexBufferView(combinedVertexBufferPointer, vertexElement);
|
||||
result->setVertexBuffer(combinedVertexBufferView);
|
||||
|
||||
int attributeTypeNormal = gpu::Stream::InputSlot::NORMAL; // libraries/gpu/src/gpu/Stream.h
|
||||
gpu::Element normalElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);
|
||||
gpu::Buffer* combinedNormalsBuffer = new gpu::Buffer(combinedNormalSize, combinedNormalData);
|
||||
gpu::BufferPointer combinedNormalsBufferPointer(combinedNormalsBuffer);
|
||||
gpu::BufferView combinedNormalsBufferView(combinedNormalsBufferPointer, normalElement);
|
||||
result->addAttribute(attributeTypeNormal, combinedNormalsBufferView);
|
||||
|
||||
gpu::Element indexElement = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::RAW);
|
||||
gpu::Buffer* combinedIndexesBuffer = new gpu::Buffer(combinedIndexSize, combinedIndexData);
|
||||
gpu::BufferPointer combinedIndexesBufferPointer(combinedIndexesBuffer);
|
||||
gpu::BufferView combinedIndexesBufferView(combinedIndexesBufferPointer, indexElement);
|
||||
result->setIndexBuffer(combinedIndexesBufferView);
|
||||
|
||||
std::vector<model::Mesh::Part> parts;
|
||||
parts.emplace_back(model::Mesh::Part((model::Index)0, // startIndex
|
||||
(model::Index)result->getNumIndices(), // numIndices
|
||||
(model::Index)0, // baseVertex
|
||||
model::Mesh::TRIANGLES)); // topology
|
||||
result->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part),
|
||||
(gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL));
|
||||
|
||||
|
||||
MeshProxy* resultProxy = new MeshProxy(result);
|
||||
return meshToScriptValue(_modelScriptEngine, resultProxy);
|
||||
}
|
||||
|
||||
|
||||
|
||||
QScriptValue ModelScriptingInterface::transformMesh(glm::mat4 transform, MeshProxy* meshProxy) {
|
||||
if (!meshProxy) {
|
||||
return QScriptValue(false);
|
||||
}
|
||||
MeshPointer mesh = meshProxy->getMeshPointer();
|
||||
if (!mesh) {
|
||||
return QScriptValue(false);
|
||||
}
|
||||
|
||||
model::MeshPointer result = mesh->map([&](glm::vec3 position){ return glm::vec3(transform * glm::vec4(position, 1.0f)); },
|
||||
[&](glm::vec3 normal){ return glm::vec3(transform * glm::vec4(normal, 0.0f)); },
|
||||
[&](uint32_t index){ return index; });
|
||||
MeshProxy* resultProxy = new MeshProxy(result);
|
||||
return meshToScriptValue(_modelScriptEngine, resultProxy);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "MeshProxy.h"
|
||||
|
||||
using MeshPointer = std::shared_ptr<model::Mesh>;
|
||||
class ScriptEngine;
|
||||
|
||||
class ModelScriptingInterface : public QObject {
|
||||
Q_OBJECT
|
||||
|
@ -28,6 +29,11 @@ public:
|
|||
ModelScriptingInterface(QObject* parent);
|
||||
|
||||
Q_INVOKABLE QString meshToOBJ(MeshProxyList in);
|
||||
Q_INVOKABLE QScriptValue appendMeshes(MeshProxyList in);
|
||||
Q_INVOKABLE QScriptValue transformMesh(glm::mat4 transform, MeshProxy* meshProxy);
|
||||
|
||||
private:
|
||||
ScriptEngine* _modelScriptEngine { nullptr };
|
||||
};
|
||||
|
||||
QScriptValue meshToScriptValue(QScriptEngine* engine, MeshProxy* const &in);
|
||||
|
|
|
@ -464,17 +464,17 @@ void ScriptEngine::loadURL(const QUrl& scriptURL, bool reload) {
|
|||
|
||||
void ScriptEngine::scriptErrorMessage(const QString& message) {
|
||||
qCCritical(scriptengine) << qPrintable(message);
|
||||
emit errorMessage(message);
|
||||
emit errorMessage(message, getFilename());
|
||||
}
|
||||
|
||||
void ScriptEngine::scriptWarningMessage(const QString& message) {
|
||||
qCWarning(scriptengine) << message;
|
||||
emit warningMessage(message);
|
||||
emit warningMessage(message, getFilename());
|
||||
}
|
||||
|
||||
void ScriptEngine::scriptInfoMessage(const QString& message) {
|
||||
qCInfo(scriptengine) << message;
|
||||
emit infoMessage(message);
|
||||
emit infoMessage(message, getFilename());
|
||||
}
|
||||
|
||||
// Even though we never pass AnimVariantMap directly to and from javascript, the queued invokeMethod of
|
||||
|
@ -627,6 +627,9 @@ void ScriptEngine::init() {
|
|||
qScriptRegisterMetaType(this, qWSCloseCodeToScriptValue, qWSCloseCodeFromScriptValue);
|
||||
qScriptRegisterMetaType(this, wscReadyStateToScriptValue, wscReadyStateFromScriptValue);
|
||||
|
||||
// NOTE: You do not want to end up creating new instances of singletons here. They will be on the ScriptEngine thread
|
||||
// and are likely to be unusable if we "reset" the ScriptEngine by creating a new one (on a whole new thread).
|
||||
|
||||
registerGlobalObject("Script", this);
|
||||
|
||||
{
|
||||
|
@ -638,7 +641,8 @@ void ScriptEngine::init() {
|
|||
resetModuleCache();
|
||||
}
|
||||
|
||||
registerGlobalObject("Audio", &AudioScriptingInterface::getInstance());
|
||||
registerGlobalObject("Audio", DependencyManager::get<AudioScriptingInterface>().data());
|
||||
|
||||
registerGlobalObject("Entities", entityScriptingInterface.data());
|
||||
registerGlobalObject("Quat", &_quatLibrary);
|
||||
registerGlobalObject("Vec3", &_vec3Library);
|
||||
|
@ -1347,7 +1351,7 @@ QUrl ScriptEngine::resourcesPath() const {
|
|||
}
|
||||
|
||||
void ScriptEngine::print(const QString& message) {
|
||||
emit printedMessage(message);
|
||||
emit printedMessage(message, getFilename());
|
||||
}
|
||||
|
||||
// Script.require.resolve -- like resolvePath, but performs more validation and throws exceptions on invalid module identifiers (for consistency with Node.js)
|
||||
|
|
|
@ -236,10 +236,10 @@ signals:
|
|||
void scriptEnding();
|
||||
void finished(const QString& fileNameString, ScriptEngine* engine);
|
||||
void cleanupMenuItem(const QString& menuItemString);
|
||||
void printedMessage(const QString& message);
|
||||
void errorMessage(const QString& message);
|
||||
void warningMessage(const QString& message);
|
||||
void infoMessage(const QString& message);
|
||||
void printedMessage(const QString& message, const QString& scriptName);
|
||||
void errorMessage(const QString& message, const QString& scriptName);
|
||||
void warningMessage(const QString& message, const QString& scriptName);
|
||||
void infoMessage(const QString& message, const QString& scriptName);
|
||||
void runningStateChanged();
|
||||
void loadScript(const QString& scriptName, bool isUserLoaded);
|
||||
void reloadScript(const QString& scriptName, bool isUserLoaded);
|
||||
|
|
|
@ -34,34 +34,24 @@ ScriptsModel& getScriptsModel() {
|
|||
return scriptsModel;
|
||||
}
|
||||
|
||||
void ScriptEngines::onPrintedMessage(const QString& message) {
|
||||
auto scriptEngine = qobject_cast<ScriptEngine*>(sender());
|
||||
auto scriptName = scriptEngine ? scriptEngine->getFilename() : "";
|
||||
void ScriptEngines::onPrintedMessage(const QString& message, const QString& scriptName) {
|
||||
emit printedMessage(message, scriptName);
|
||||
}
|
||||
|
||||
void ScriptEngines::onErrorMessage(const QString& message) {
|
||||
auto scriptEngine = qobject_cast<ScriptEngine*>(sender());
|
||||
auto scriptName = scriptEngine ? scriptEngine->getFilename() : "";
|
||||
void ScriptEngines::onErrorMessage(const QString& message, const QString& scriptName) {
|
||||
emit errorMessage(message, scriptName);
|
||||
}
|
||||
|
||||
void ScriptEngines::onWarningMessage(const QString& message) {
|
||||
auto scriptEngine = qobject_cast<ScriptEngine*>(sender());
|
||||
auto scriptName = scriptEngine ? scriptEngine->getFilename() : "";
|
||||
void ScriptEngines::onWarningMessage(const QString& message, const QString& scriptName) {
|
||||
emit warningMessage(message, scriptName);
|
||||
}
|
||||
|
||||
void ScriptEngines::onInfoMessage(const QString& message) {
|
||||
auto scriptEngine = qobject_cast<ScriptEngine*>(sender());
|
||||
auto scriptName = scriptEngine ? scriptEngine->getFilename() : "";
|
||||
void ScriptEngines::onInfoMessage(const QString& message, const QString& scriptName) {
|
||||
emit infoMessage(message, scriptName);
|
||||
}
|
||||
|
||||
void ScriptEngines::onErrorLoadingScript(const QString& url) {
|
||||
auto scriptEngine = qobject_cast<ScriptEngine*>(sender());
|
||||
auto scriptName = scriptEngine ? scriptEngine->getFilename() : "";
|
||||
emit errorLoadingScript(url, scriptName);
|
||||
emit errorLoadingScript(url);
|
||||
}
|
||||
|
||||
ScriptEngines::ScriptEngines(ScriptEngine::Context context)
|
||||
|
|
|
@ -79,13 +79,13 @@ signals:
|
|||
void errorMessage(const QString& message, const QString& engineName);
|
||||
void warningMessage(const QString& message, const QString& engineName);
|
||||
void infoMessage(const QString& message, const QString& engineName);
|
||||
void errorLoadingScript(const QString& url, const QString& engineName);
|
||||
void errorLoadingScript(const QString& url);
|
||||
|
||||
public slots:
|
||||
void onPrintedMessage(const QString& message);
|
||||
void onErrorMessage(const QString& message);
|
||||
void onWarningMessage(const QString& message);
|
||||
void onInfoMessage(const QString& message);
|
||||
void onPrintedMessage(const QString& message, const QString& scriptName);
|
||||
void onErrorMessage(const QString& message, const QString& scriptName);
|
||||
void onWarningMessage(const QString& message, const QString& scriptName);
|
||||
void onInfoMessage(const QString& message, const QString& scriptName);
|
||||
void onErrorLoadingScript(const QString& url);
|
||||
|
||||
protected slots:
|
||||
|
|
29
scripts/system/assets/images/icon-particles.svg
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||
<path d="M331.8,283.4c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C342.1,306.6,331.8,296.2,331.8,283.4z"/>
|
||||
<path d="M277.8,350.9c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C288.1,374.2,277.8,363.8,277.8,350.9z"/>
|
||||
<path d="M216.3,368.8c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C226.7,392,216.3,381.6,216.3,368.8z"/>
|
||||
<path d="M169.9,308.9c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C180.3,332.1,169.9,321.7,169.9,308.9z"/>
|
||||
<path d="M251.2,447.4c-4.9-3.6-8.3-9.1-9.2-15.3c-0.9-6,0.6-12.3,4.2-17.2c3.6-4.9,9.1-8.3,15.2-9.1c6-0.9,12.3,0.6,17.3,4.3
|
||||
c4.9,3.6,8.3,9.1,9.1,15.2c0.9,6-0.6,12.3-4.2,17.2s-9.1,8.3-15.2,9.1C262.4,452.6,256.1,451,251.2,447.4z"/>
|
||||
<path d="M67.6,246.1c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C78,269.3,67.6,258.8,67.6,246.1z"/>
|
||||
<path d="M178.8,199.5c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C189.1,222.7,178.8,212.2,178.8,199.5z"/>
|
||||
<path d="M250.3,293.9c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C260.7,317.1,250.3,306.6,250.3,293.9z"/>
|
||||
<path d="M413,242.1c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C423.5,265.3,413,255,413,242.1z"/>
|
||||
<path d="M302.1,203.7c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C312.6,226.9,302.1,216.5,302.1,203.7z"/>
|
||||
<path d="M132.3,113.5c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C142.8,136.6,132.3,126.2,132.3,113.5z"/>
|
||||
<path d="M366.6,136.7c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C377.1,159.9,366.6,149.5,366.6,136.7z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
57
scripts/system/assets/images/icon-point-light.svg
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 960 560" style="enable-background:new 0 0 960 560;" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<path style="fill:#333333;" d="M478.879,127.676c-83.872,0-152.325,68.454-152.325,152.325s68.454,152.325,152.325,152.325
|
||||
s152.325-67.837,152.325-152.325C631.204,196.13,563.366,127.676,478.879,127.676z"/>
|
||||
<path style="fill:#FFFFFF;" d="M478.881,437.281C392.156,437.281,321.6,366.725,321.6,280s70.557-157.281,157.281-157.281
|
||||
S636.157,193.275,636.157,280S565.606,437.281,478.881,437.281z M478.881,132.627c-81.263,0-147.373,66.115-147.373,147.373
|
||||
s66.11,147.373,147.373,147.373c81.258,0,147.368-66.115,147.368-147.373S560.138,132.627,478.881,132.627z"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="459.145" y="4.952" style="fill:#333333;" width="40.086" height="75.237"/>
|
||||
<path style="fill:#FFFFFF;" d="M504.183,85.147h-49.99V0h49.99V85.147z M464.1,75.239h30.174V9.908H464.1V75.239z"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<rect x="272.766" y="90.696" transform="matrix(-0.707 -0.7072 0.7072 -0.707 451.5123 408.5368)" style="fill:#333333;" width="75.236" height="40.085"/>
|
||||
<path style="fill:#FFFFFF;" d="M322.809,158.519l-60.198-60.212l35.351-35.346l60.198,60.212L322.809,158.519z M276.621,98.307
|
||||
l46.188,46.202l21.34-21.335l-46.188-46.202L276.621,98.307z"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="201.98" y="257.8" style="fill:#333333;" width="75.237" height="40.086"/>
|
||||
<path style="fill:#FFFFFF;" d="M282.17,302.845h-85.142V252.85h85.142V302.845z M206.936,292.937h65.327v-30.179h-65.327V292.937z
|
||||
"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<rect x="287.46" y="408.97" transform="matrix(0.7072 0.707 -0.707 0.7072 405.7749 -86.6482)" style="fill:#333333;" width="40.085" height="75.236"/>
|
||||
<path style="fill:#FFFFFF;" d="M295.083,494.359l-35.355-35.346l60.198-60.212l35.355,35.346L295.083,494.359z M273.738,459.013
|
||||
l21.345,21.335l46.187-46.202l-21.345-21.335L273.738,459.013z"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="454.827" y="479.812" style="fill:#333333;" width="40.086" height="75.237"/>
|
||||
<path style="fill:#FFFFFF;" d="M499.868,560h-49.995v-85.137h49.995V560z M459.781,550.091h30.179V484.77h-30.179V550.091z"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<rect x="606.017" y="429.505" transform="matrix(0.707 0.7072 -0.7072 0.707 506.5034 -323.4691)" style="fill:#333333;" width="75.236" height="40.085"/>
|
||||
<path style="fill:#FFFFFF;" d="M656.06,497.32l-60.198-60.212l35.351-35.346l60.198,60.212L656.06,497.32z M609.872,437.107
|
||||
l46.187,46.202l21.34-21.335l-46.188-46.202L609.872,437.107z"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="676.839" y="262.117" style="fill:#333333;" width="75.237" height="40.086"/>
|
||||
<path style="fill:#FFFFFF;" d="M757.032,307.16h-85.147v-49.995h85.147V307.16z M681.792,297.252h65.332v-30.179h-65.332V297.252z
|
||||
"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<rect x="626.205" y="75.756" transform="matrix(-0.7072 -0.707 0.707 -0.7072 1023.1211 650.4535)" style="fill:#333333;" width="40.085" height="75.236"/>
|
||||
<path style="fill:#FFFFFF;" d="M633.825,161.161l-35.351-35.346l60.198-60.212l35.351,35.346L633.825,161.161z M612.485,125.815
|
||||
l21.34,21.335l46.188-46.202l-21.34-21.335L612.485,125.815z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.4 KiB |
37
scripts/system/assets/images/icon-spot-light.svg
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="3.44 0 735.338 557.9" style="enable-background:new 3.44 0 735.338 557.9;" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<rect x="503.95" y="260.767" style="fill:#333333;" width="227.728" height="36.376"/>
|
||||
<path style="fill:#FFFFFF;" d="M738.778,304.24H496.854v-50.566h241.924V304.24z M511.052,290.042H724.58v-22.17H511.052V290.042z
|
||||
"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
|
||||
<rect x="426.085" y="465.518" transform="matrix(-0.9213 -0.3888 0.3888 -0.9213 849.3369 1139.2869)" style="fill:#333333;" width="227.719" height="36.374"/>
|
||||
<path style="fill:#FFFFFF;" d="M641.55,554.032l-222.88-94.06l19.668-46.6l222.88,94.06L641.55,554.032z M437.277,452.401
|
||||
l196.717,83.024l8.617-20.423l-196.717-83.024L437.277,452.401z"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<rect x="426.295" y="56.081" transform="matrix(0.9213 -0.3888 0.3888 0.9213 13.624 215.8596)" style="fill:#333333;" width="227.719" height="36.374"/>
|
||||
<path style="fill:#FFFFFF;" d="M438.545,144.598l-19.668-46.6l222.887-94.06l19.667,46.6L438.545,144.598z M437.484,105.568
|
||||
l8.617,20.423l196.724-83.024l-8.617-20.423L437.484,105.568z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#333333;" d="M430.774,280.311c0-50.839-32.955-93.895-78.642-109.198V13.262L124.404,165.081H10.54v227.728
|
||||
h113.864l227.728,151.819V389.51C397.818,374.206,430.774,331.151,430.774,280.311z"/>
|
||||
<path style="fill:#FFFFFF;" d="M359.23,557.9L122.257,399.908H3.44V157.978h118.816L359.23,0v166.117
|
||||
c47.245,18.038,78.642,63.308,78.642,114.192s-31.397,96.154-78.642,114.192V557.9z M17.638,385.711h108.917l218.478,145.652
|
||||
V384.407l4.846-1.622c44.139-14.794,73.796-55.973,73.796-102.476s-29.657-87.682-73.796-102.476l-4.846-1.622V26.538
|
||||
L126.555,172.176H17.638V385.711z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
|
@ -85,6 +85,7 @@ function Trigger(hand) {
|
|||
}
|
||||
|
||||
var coolInTimeout = null;
|
||||
var ignoredEntities = [];
|
||||
|
||||
var TELEPORTER_STATES = {
|
||||
IDLE: 'idle',
|
||||
|
@ -239,11 +240,11 @@ function Teleporter() {
|
|||
// We might hit an invisible entity that is not a seat, so we need to do a second pass.
|
||||
// * In the second pass we pick against visible entities only.
|
||||
//
|
||||
var intersection = Entities.findRayIntersection(pickRay, true, [], [this.targetEntity], false, true);
|
||||
var intersection = Entities.findRayIntersection(pickRay, true, [], [this.targetEntity].concat(ignoredEntities), false, true);
|
||||
|
||||
var teleportLocationType = getTeleportTargetType(intersection);
|
||||
if (teleportLocationType === TARGET.INVISIBLE) {
|
||||
intersection = Entities.findRayIntersection(pickRay, true, [], [this.targetEntity], true, true);
|
||||
intersection = Entities.findRayIntersection(pickRay, true, [], [this.targetEntity].concat(ignoredEntities), true, true);
|
||||
teleportLocationType = getTeleportTargetType(intersection);
|
||||
}
|
||||
|
||||
|
@ -513,7 +514,7 @@ function cleanup() {
|
|||
Script.scriptEnding.connect(cleanup);
|
||||
|
||||
var isDisabled = false;
|
||||
var handleHandMessages = function(channel, message, sender) {
|
||||
var handleTeleportMessages = function(channel, message, sender) {
|
||||
var data;
|
||||
if (sender === MyAvatar.sessionUUID) {
|
||||
if (channel === 'Hifi-Teleport-Disabler') {
|
||||
|
@ -529,12 +530,20 @@ var handleHandMessages = function(channel, message, sender) {
|
|||
if (message === 'none') {
|
||||
isDisabled = false;
|
||||
}
|
||||
|
||||
} else if (channel === 'Hifi-Teleport-Ignore-Add' && !Uuid.isNull(message) && ignoredEntities.indexOf(message) === -1) {
|
||||
ignoredEntities.push(message);
|
||||
} else if (channel === 'Hifi-Teleport-Ignore-Remove' && !Uuid.isNull(message)) {
|
||||
var removeIndex = ignoredEntities.indexOf(message);
|
||||
if (removeIndex > -1) {
|
||||
ignoredEntities.splice(removeIndex, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Messages.subscribe('Hifi-Teleport-Disabler');
|
||||
Messages.messageReceived.connect(handleHandMessages);
|
||||
Messages.subscribe('Hifi-Teleport-Ignore-Add');
|
||||
Messages.subscribe('Hifi-Teleport-Ignore-Remove');
|
||||
Messages.messageReceived.connect(handleTeleportMessages);
|
||||
|
||||
}()); // END LOCAL_SCOPE
|
||||
|
|
|
@ -33,13 +33,27 @@ Script.include([
|
|||
"libraries/gridTool.js",
|
||||
"libraries/entityList.js",
|
||||
"particle_explorer/particleExplorerTool.js",
|
||||
"libraries/lightOverlayManager.js"
|
||||
"libraries/entityIconOverlayManager.js"
|
||||
]);
|
||||
|
||||
var selectionDisplay = SelectionDisplay;
|
||||
var selectionManager = SelectionManager;
|
||||
|
||||
var lightOverlayManager = new LightOverlayManager();
|
||||
const PARTICLE_SYSTEM_URL = Script.resolvePath("assets/images/icon-particles.svg");
|
||||
const POINT_LIGHT_URL = Script.resolvePath("assets/images/icon-point-light.svg");
|
||||
const SPOT_LIGHT_URL = Script.resolvePath("assets/images/icon-spot-light.svg");
|
||||
entityIconOverlayManager = new EntityIconOverlayManager(['Light', 'ParticleEffect'], function(entityID) {
|
||||
var properties = Entities.getEntityProperties(entityID, ['type', 'isSpotlight']);
|
||||
if (properties.type === 'Light') {
|
||||
return {
|
||||
url: properties.isSpotlight ? SPOT_LIGHT_URL : POINT_LIGHT_URL,
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
url: PARTICLE_SYSTEM_URL,
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var cameraManager = new CameraManager();
|
||||
|
||||
|
@ -53,7 +67,45 @@ var entityListTool = new EntityListTool();
|
|||
|
||||
selectionManager.addEventListener(function () {
|
||||
selectionDisplay.updateHandles();
|
||||
lightOverlayManager.updatePositions();
|
||||
entityIconOverlayManager.updatePositions();
|
||||
|
||||
// Update particle explorer
|
||||
var needToDestroyParticleExplorer = false;
|
||||
if (selectionManager.selections.length === 1) {
|
||||
var selectedEntityID = selectionManager.selections[0];
|
||||
if (selectedEntityID === selectedParticleEntityID) {
|
||||
return;
|
||||
}
|
||||
var type = Entities.getEntityProperties(selectedEntityID, "type").type;
|
||||
if (type === "ParticleEffect") {
|
||||
// Destroy the old particles web view first
|
||||
particleExplorerTool.destroyWebView();
|
||||
particleExplorerTool.createWebView();
|
||||
var properties = Entities.getEntityProperties(selectedEntityID);
|
||||
var particleData = {
|
||||
messageType: "particle_settings",
|
||||
currentProperties: properties
|
||||
};
|
||||
selectedParticleEntityID = selectedEntityID;
|
||||
particleExplorerTool.setActiveParticleEntity(selectedParticleEntityID);
|
||||
|
||||
particleExplorerTool.webView.webEventReceived.connect(function (data) {
|
||||
data = JSON.parse(data);
|
||||
if (data.messageType === "page_loaded") {
|
||||
particleExplorerTool.webView.emitScriptEvent(JSON.stringify(particleData));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
needToDestroyParticleExplorer = true;
|
||||
}
|
||||
} else {
|
||||
needToDestroyParticleExplorer = true;
|
||||
}
|
||||
|
||||
if (needToDestroyParticleExplorer && selectedParticleEntityID !== null) {
|
||||
selectedParticleEntityID = null;
|
||||
particleExplorerTool.destroyWebView();
|
||||
}
|
||||
});
|
||||
|
||||
const KEY_P = 80; //Key code for letter p used for Parenting hotkey.
|
||||
|
@ -82,13 +134,13 @@ var DEFAULT_LIGHT_DIMENSIONS = Vec3.multiply(20, DEFAULT_DIMENSIONS);
|
|||
|
||||
var MENU_AUTO_FOCUS_ON_SELECT = "Auto Focus on Select";
|
||||
var MENU_EASE_ON_FOCUS = "Ease Orientation on Focus";
|
||||
var MENU_SHOW_LIGHTS_IN_EDIT_MODE = "Show Lights in Edit Mode";
|
||||
var MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE = "Show Lights and Particle Systems in Edit Mode";
|
||||
var MENU_SHOW_ZONES_IN_EDIT_MODE = "Show Zones in Edit Mode";
|
||||
|
||||
var SETTING_INSPECT_TOOL_ENABLED = "inspectToolEnabled";
|
||||
var SETTING_AUTO_FOCUS_ON_SELECT = "autoFocusOnSelect";
|
||||
var SETTING_EASE_ON_FOCUS = "cameraEaseOnFocus";
|
||||
var SETTING_SHOW_LIGHTS_IN_EDIT_MODE = "showLightsInEditMode";
|
||||
var SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE = "showLightsAndParticlesInEditMode";
|
||||
var SETTING_SHOW_ZONES_IN_EDIT_MODE = "showZonesInEditMode";
|
||||
|
||||
|
||||
|
@ -506,7 +558,7 @@ var toolBar = (function () {
|
|||
toolBar.writeProperty("shown", false);
|
||||
toolBar.writeProperty("shown", true);
|
||||
}
|
||||
lightOverlayManager.setVisible(isActive && Menu.isOptionChecked(MENU_SHOW_LIGHTS_IN_EDIT_MODE));
|
||||
entityIconOverlayManager.setVisible(isActive && Menu.isOptionChecked(MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE));
|
||||
Entities.setDrawZoneBoundaries(isActive && Menu.isOptionChecked(MENU_SHOW_ZONES_IN_EDIT_MODE));
|
||||
};
|
||||
|
||||
|
@ -571,8 +623,8 @@ function findClickedEntity(event) {
|
|||
}
|
||||
|
||||
var entityResult = Entities.findRayIntersection(pickRay, true); // want precision picking
|
||||
var lightResult = lightOverlayManager.findRayIntersection(pickRay);
|
||||
lightResult.accurate = true;
|
||||
var iconResult = entityIconOverlayManager.findRayIntersection(pickRay);
|
||||
iconResult.accurate = true;
|
||||
|
||||
if (pickZones) {
|
||||
Entities.setZonesArePickable(false);
|
||||
|
@ -580,18 +632,12 @@ function findClickedEntity(event) {
|
|||
|
||||
var result;
|
||||
|
||||
if (!entityResult.intersects && !lightResult.intersects) {
|
||||
return null;
|
||||
} else if (entityResult.intersects && !lightResult.intersects) {
|
||||
if (iconResult.intersects) {
|
||||
result = iconResult;
|
||||
} else if (entityResult.intersects) {
|
||||
result = entityResult;
|
||||
} else if (!entityResult.intersects && lightResult.intersects) {
|
||||
result = lightResult;
|
||||
} else {
|
||||
if (entityResult.distance < lightResult.distance) {
|
||||
result = entityResult;
|
||||
} else {
|
||||
result = lightResult;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!result.accurate) {
|
||||
|
@ -945,18 +991,18 @@ function setupModelMenus() {
|
|||
});
|
||||
Menu.addMenuItem({
|
||||
menuName: "Edit",
|
||||
menuItemName: MENU_SHOW_LIGHTS_IN_EDIT_MODE,
|
||||
menuItemName: MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE,
|
||||
afterItem: MENU_EASE_ON_FOCUS,
|
||||
isCheckable: true,
|
||||
isChecked: Settings.getValue(SETTING_SHOW_LIGHTS_IN_EDIT_MODE) === "true",
|
||||
isChecked: Settings.getValue(SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE) !== "false",
|
||||
grouping: "Advanced"
|
||||
});
|
||||
Menu.addMenuItem({
|
||||
menuName: "Edit",
|
||||
menuItemName: MENU_SHOW_ZONES_IN_EDIT_MODE,
|
||||
afterItem: MENU_SHOW_LIGHTS_IN_EDIT_MODE,
|
||||
afterItem: MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE,
|
||||
isCheckable: true,
|
||||
isChecked: Settings.getValue(SETTING_SHOW_ZONES_IN_EDIT_MODE) === "true",
|
||||
isChecked: Settings.getValue(SETTING_SHOW_ZONES_IN_EDIT_MODE) !== "false",
|
||||
grouping: "Advanced"
|
||||
});
|
||||
|
||||
|
@ -987,7 +1033,7 @@ function cleanupModelMenus() {
|
|||
|
||||
Menu.removeMenuItem("Edit", MENU_AUTO_FOCUS_ON_SELECT);
|
||||
Menu.removeMenuItem("Edit", MENU_EASE_ON_FOCUS);
|
||||
Menu.removeMenuItem("Edit", MENU_SHOW_LIGHTS_IN_EDIT_MODE);
|
||||
Menu.removeMenuItem("Edit", MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE);
|
||||
Menu.removeMenuItem("Edit", MENU_SHOW_ZONES_IN_EDIT_MODE);
|
||||
}
|
||||
|
||||
|
@ -995,7 +1041,7 @@ Script.scriptEnding.connect(function () {
|
|||
toolBar.setActive(false);
|
||||
Settings.setValue(SETTING_AUTO_FOCUS_ON_SELECT, Menu.isOptionChecked(MENU_AUTO_FOCUS_ON_SELECT));
|
||||
Settings.setValue(SETTING_EASE_ON_FOCUS, Menu.isOptionChecked(MENU_EASE_ON_FOCUS));
|
||||
Settings.setValue(SETTING_SHOW_LIGHTS_IN_EDIT_MODE, Menu.isOptionChecked(MENU_SHOW_LIGHTS_IN_EDIT_MODE));
|
||||
Settings.setValue(SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE, Menu.isOptionChecked(MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE));
|
||||
Settings.setValue(SETTING_SHOW_ZONES_IN_EDIT_MODE, Menu.isOptionChecked(MENU_SHOW_ZONES_IN_EDIT_MODE));
|
||||
|
||||
progressDialog.cleanup();
|
||||
|
@ -1184,7 +1230,7 @@ function parentSelectedEntities() {
|
|||
}
|
||||
function deleteSelectedEntities() {
|
||||
if (SelectionManager.hasSelection()) {
|
||||
selectedParticleEntity = 0;
|
||||
selectedParticleEntityID = null;
|
||||
particleExplorerTool.destroyWebView();
|
||||
SelectionManager.saveProperties();
|
||||
var savedProperties = [];
|
||||
|
@ -1283,8 +1329,8 @@ function handeMenuEvent(menuItem) {
|
|||
selectAllEtitiesInCurrentSelectionBox(false);
|
||||
} else if (menuItem === "Select All Entities Touching Box") {
|
||||
selectAllEtitiesInCurrentSelectionBox(true);
|
||||
} else if (menuItem === MENU_SHOW_LIGHTS_IN_EDIT_MODE) {
|
||||
lightOverlayManager.setVisible(isActive && Menu.isOptionChecked(MENU_SHOW_LIGHTS_IN_EDIT_MODE));
|
||||
} else if (menuItem === MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE) {
|
||||
entityIconOverlayManager.setVisible(isActive && Menu.isOptionChecked(MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE));
|
||||
} else if (menuItem === MENU_SHOW_ZONES_IN_EDIT_MODE) {
|
||||
Entities.setDrawZoneBoundaries(isActive && Menu.isOptionChecked(MENU_SHOW_ZONES_IN_EDIT_MODE));
|
||||
}
|
||||
|
@ -1959,43 +2005,13 @@ var showMenuItem = propertyMenu.addMenuItem("Show in Marketplace");
|
|||
|
||||
var propertiesTool = new PropertiesTool();
|
||||
var particleExplorerTool = new ParticleExplorerTool();
|
||||
var selectedParticleEntity = 0;
|
||||
var selectedParticleEntityID = null;
|
||||
entityListTool.webView.webEventReceived.connect(function (data) {
|
||||
data = JSON.parse(data);
|
||||
if(data.type === 'parent') {
|
||||
if (data.type === 'parent') {
|
||||
parentSelectedEntities();
|
||||
} else if(data.type === 'unparent') {
|
||||
unparentSelectedEntities();
|
||||
} else if (data.type === "selectionUpdate") {
|
||||
var ids = data.entityIds;
|
||||
if (ids.length === 1) {
|
||||
if (Entities.getEntityProperties(ids[0], "type").type === "ParticleEffect") {
|
||||
if (JSON.stringify(selectedParticleEntity) === JSON.stringify(ids[0])) {
|
||||
// This particle entity is already selected, so return
|
||||
return;
|
||||
}
|
||||
// Destroy the old particles web view first
|
||||
particleExplorerTool.destroyWebView();
|
||||
particleExplorerTool.createWebView();
|
||||
var properties = Entities.getEntityProperties(ids[0]);
|
||||
var particleData = {
|
||||
messageType: "particle_settings",
|
||||
currentProperties: properties
|
||||
};
|
||||
selectedParticleEntity = ids[0];
|
||||
particleExplorerTool.setActiveParticleEntity(ids[0]);
|
||||
|
||||
particleExplorerTool.webView.webEventReceived.connect(function (data) {
|
||||
data = JSON.parse(data);
|
||||
if (data.messageType === "page_loaded") {
|
||||
particleExplorerTool.webView.emitScriptEvent(JSON.stringify(particleData));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
selectedParticleEntity = 0;
|
||||
particleExplorerTool.destroyWebView();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
var POINT_LIGHT_URL = "http://s3.amazonaws.com/hifi-public/images/tools/point-light.svg";
|
||||
var SPOT_LIGHT_URL = "http://s3.amazonaws.com/hifi-public/images/tools/spot-light.svg";
|
||||
|
||||
LightOverlayManager = function() {
|
||||
var self = this;
|
||||
/* globals EntityIconOverlayManager:true */
|
||||
|
||||
EntityIconOverlayManager = function(entityTypes, getOverlayPropertiesFunc) {
|
||||
var visible = false;
|
||||
|
||||
// List of all created overlays
|
||||
|
@ -22,9 +19,16 @@ LightOverlayManager = function() {
|
|||
for (var id in entityIDs) {
|
||||
var entityID = entityIDs[id];
|
||||
var properties = Entities.getEntityProperties(entityID);
|
||||
Overlays.editOverlay(entityOverlays[entityID], {
|
||||
var overlayProperties = {
|
||||
position: properties.position
|
||||
});
|
||||
};
|
||||
if (getOverlayPropertiesFunc) {
|
||||
var customProperties = getOverlayPropertiesFunc(entityID, properties);
|
||||
for (var key in customProperties) {
|
||||
overlayProperties[key] = customProperties[key];
|
||||
}
|
||||
}
|
||||
Overlays.editOverlay(entityOverlays[entityID], overlayProperties);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -34,7 +38,7 @@ LightOverlayManager = function() {
|
|||
|
||||
if (result.intersects) {
|
||||
for (var id in entityOverlays) {
|
||||
if (result.overlayID == entityOverlays[id]) {
|
||||
if (result.overlayID === entityOverlays[id]) {
|
||||
result.entityID = entityIDs[id];
|
||||
found = true;
|
||||
break;
|
||||
|
@ -50,7 +54,7 @@ LightOverlayManager = function() {
|
|||
};
|
||||
|
||||
this.setVisible = function(isVisible) {
|
||||
if (visible != isVisible) {
|
||||
if (visible !== isVisible) {
|
||||
visible = isVisible;
|
||||
for (var id in entityOverlays) {
|
||||
Overlays.editOverlay(entityOverlays[id], {
|
||||
|
@ -62,12 +66,13 @@ LightOverlayManager = function() {
|
|||
|
||||
// Allocate or get an unused overlay
|
||||
function getOverlay() {
|
||||
if (unusedOverlays.length == 0) {
|
||||
var overlay = Overlays.addOverlay("image3d", {});
|
||||
var overlay;
|
||||
if (unusedOverlays.length === 0) {
|
||||
overlay = Overlays.addOverlay("image3d", {});
|
||||
allOverlays.push(overlay);
|
||||
} else {
|
||||
var overlay = unusedOverlays.pop();
|
||||
};
|
||||
overlay = unusedOverlays.pop();
|
||||
}
|
||||
return overlay;
|
||||
}
|
||||
|
||||
|
@ -79,24 +84,32 @@ LightOverlayManager = function() {
|
|||
}
|
||||
|
||||
function addEntity(entityID) {
|
||||
var properties = Entities.getEntityProperties(entityID);
|
||||
if (properties.type == "Light" && !(entityID in entityOverlays)) {
|
||||
var properties = Entities.getEntityProperties(entityID, ['position', 'type']);
|
||||
if (entityTypes.indexOf(properties.type) > -1 && !(entityID in entityOverlays)) {
|
||||
var overlay = getOverlay();
|
||||
entityOverlays[entityID] = overlay;
|
||||
entityIDs[entityID] = entityID;
|
||||
Overlays.editOverlay(overlay, {
|
||||
var overlayProperties = {
|
||||
position: properties.position,
|
||||
url: properties.isSpotlight ? SPOT_LIGHT_URL : POINT_LIGHT_URL,
|
||||
rotation: Quat.fromPitchYawRollDegrees(0, 0, 270),
|
||||
visible: visible,
|
||||
alpha: 0.9,
|
||||
scale: 0.5,
|
||||
drawInFront: true,
|
||||
isFacingAvatar: true,
|
||||
color: {
|
||||
red: 255,
|
||||
green: 255,
|
||||
blue: 255
|
||||
}
|
||||
});
|
||||
};
|
||||
if (getOverlayPropertiesFunc) {
|
||||
var customProperties = getOverlayPropertiesFunc(entityID, properties);
|
||||
for (var key in customProperties) {
|
||||
overlayProperties[key] = customProperties[key];
|
||||
}
|
||||
}
|
||||
Overlays.editOverlay(overlay, overlayProperties);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,4 +143,4 @@ LightOverlayManager = function() {
|
|||
Overlays.deleteOverlay(allOverlays[i]);
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
|
@ -1032,10 +1032,12 @@ SelectionDisplay = (function() {
|
|||
var pickRay = controllerComputePickRay();
|
||||
if (pickRay) {
|
||||
var entityIntersection = Entities.findRayIntersection(pickRay, true);
|
||||
|
||||
|
||||
var iconIntersection = entityIconOverlayManager.findRayIntersection(pickRay);
|
||||
var overlayIntersection = Overlays.findRayIntersection(pickRay);
|
||||
if (entityIntersection.intersects &&
|
||||
|
||||
if (iconIntersection.intersects) {
|
||||
selectionManager.setSelections([iconIntersection.entityID]);
|
||||
} else if (entityIntersection.intersects &&
|
||||
(!overlayIntersection.intersects || (entityIntersection.distance < overlayIntersection.distance))) {
|
||||
|
||||
if (HMD.tabletID === entityIntersection.entityID) {
|
||||
|
|
80
unpublishedScripts/marketplace/boppo/boppoClownEntity.js
Normal file
|
@ -0,0 +1,80 @@
|
|||
//
|
||||
// boppoClownEntity.js
|
||||
//
|
||||
// Created by Thijs Wenker on 3/15/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
/* globals LookAtTarget */
|
||||
|
||||
(function() {
|
||||
var SFX_PREFIX = 'https://hifi-content.s3-us-west-1.amazonaws.com/caitlyn/production/elBoppo/sfx/';
|
||||
var CHANNEL_PREFIX = 'io.highfidelity.boppo_server_';
|
||||
var PUNCH_SOUNDS = [
|
||||
'punch_1.wav',
|
||||
'punch_2.wav'
|
||||
];
|
||||
var PUNCH_COOLDOWN = 300;
|
||||
|
||||
Script.include('lookAtEntity.js');
|
||||
|
||||
var createBoppoClownEntity = function() {
|
||||
var _this,
|
||||
_entityID,
|
||||
_boppoUserData,
|
||||
_lookAtTarget,
|
||||
_punchSounds = [],
|
||||
_lastPlayedPunch = {};
|
||||
|
||||
var getOwnBoppoUserData = function() {
|
||||
try {
|
||||
return JSON.parse(Entities.getEntityProperties(_entityID, ['userData']).userData).Boppo;
|
||||
} catch (e) {
|
||||
// e
|
||||
}
|
||||
return {};
|
||||
};
|
||||
|
||||
var BoppoClownEntity = function () {
|
||||
_this = this;
|
||||
PUNCH_SOUNDS.forEach(function(punch) {
|
||||
_punchSounds.push(SoundCache.getSound(SFX_PREFIX + punch));
|
||||
});
|
||||
};
|
||||
|
||||
BoppoClownEntity.prototype = {
|
||||
preload: function(entityID) {
|
||||
_entityID = entityID;
|
||||
_boppoUserData = getOwnBoppoUserData();
|
||||
_lookAtTarget = new LookAtTarget(_entityID);
|
||||
},
|
||||
collisionWithEntity: function(boppoEntity, collidingEntity, collisionInfo) {
|
||||
if (collisionInfo.type === 0 &&
|
||||
Entities.getEntityProperties(collidingEntity, ['name']).name.indexOf('Boxing Glove ') === 0) {
|
||||
|
||||
if (_lastPlayedPunch[collidingEntity] === undefined ||
|
||||
Date.now() - _lastPlayedPunch[collidingEntity] > PUNCH_COOLDOWN) {
|
||||
|
||||
// If boxing glove detected here:
|
||||
Messages.sendMessage(CHANNEL_PREFIX + _boppoUserData.gameParentID, 'hit');
|
||||
|
||||
_lookAtTarget.lookAtByAction();
|
||||
var randomPunchIndex = Math.floor(Math.random() * _punchSounds.length);
|
||||
Audio.playSound(_punchSounds[randomPunchIndex], {
|
||||
position: collisionInfo.contactPoint
|
||||
});
|
||||
_lastPlayedPunch[collidingEntity] = Date.now();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return new BoppoClownEntity();
|
||||
};
|
||||
|
||||
return createBoppoClownEntity();
|
||||
});
|
303
unpublishedScripts/marketplace/boppo/boppoServer.js
Normal file
|
@ -0,0 +1,303 @@
|
|||
//
|
||||
// boppoServer.js
|
||||
//
|
||||
// Created by Thijs Wenker on 3/15/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
(function() {
|
||||
var SFX_PREFIX = 'https://hifi-content.s3-us-west-1.amazonaws.com/caitlyn/production/elBoppo/sfx/';
|
||||
var CLOWN_LAUGHS = [
|
||||
'clown_laugh_1.wav',
|
||||
'clown_laugh_2.wav',
|
||||
'clown_laugh_3.wav',
|
||||
'clown_laugh_4.wav'
|
||||
];
|
||||
var TICK_TOCK_SOUND = 'ticktock%20-%20tock.wav';
|
||||
var BOXING_RING_BELL_START = 'boxingRingBell.wav';
|
||||
var BOXING_RING_BELL_END = 'boxingRingBell-end.wav';
|
||||
var BOPPO_MUSIC = 'boppoMusic.wav';
|
||||
var CHANNEL_PREFIX = 'io.highfidelity.boppo_server_';
|
||||
var MESSAGE_HIT = 'hit';
|
||||
var MESSAGE_ENTER_ZONE = 'enter-zone';
|
||||
var MESSAGE_UNLOAD_FIX = 'unload-fix';
|
||||
|
||||
var DEFAULT_SOUND_VOLUME = 0.6;
|
||||
|
||||
// don't set the search radius too high, it might remove boppo's from other nearby instances
|
||||
var BOPPO_SEARCH_RADIUS = 4.0;
|
||||
|
||||
var MILLISECONDS_PER_SECOND = 1000;
|
||||
// Make sure the entities are loaded at startup (TODO: more solid fix)
|
||||
var LOAD_TIMEOUT = 5000;
|
||||
var SECONDS_PER_MINUTE = 60;
|
||||
var DEFAULT_PLAYTIME = 30; // seconds
|
||||
var BASE_TEN = 10;
|
||||
var TICK_TOCK_FROM = 3; // seconds
|
||||
var COOLDOWN_TIME_MS = MILLISECONDS_PER_SECOND * 3;
|
||||
|
||||
var createBoppoServer = function() {
|
||||
var _this,
|
||||
_isInitialized = false,
|
||||
_clownLaughs = [],
|
||||
_musicInjector,
|
||||
_music,
|
||||
_laughingInjector,
|
||||
_tickTockSound,
|
||||
_boxingBellRingStart,
|
||||
_boxingBellRingEnd,
|
||||
_entityID,
|
||||
_boppoClownID,
|
||||
_channel,
|
||||
_boppoEntities,
|
||||
_isGameRunning,
|
||||
_updateInterval,
|
||||
_timeLeft,
|
||||
_hits,
|
||||
_coolDown;
|
||||
|
||||
var getOwnBoppoUserData = function() {
|
||||
try {
|
||||
return JSON.parse(Entities.getEntityProperties(_entityID, ['userData']).userData).Boppo;
|
||||
} catch (e) {
|
||||
// e
|
||||
}
|
||||
return {};
|
||||
};
|
||||
|
||||
var updateBoppoEntities = function() {
|
||||
Entities.getChildrenIDs(_entityID).forEach(function(entityID) {
|
||||
try {
|
||||
var userData = JSON.parse(Entities.getEntityProperties(entityID, ['userData']).userData);
|
||||
if (userData.Boppo.type !== undefined) {
|
||||
_boppoEntities[userData.Boppo.type] = entityID;
|
||||
}
|
||||
} catch (e) {
|
||||
// e
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var clearUntrackedBoppos = function() {
|
||||
var position = Entities.getEntityProperties(_entityID, ['position']).position;
|
||||
Entities.findEntities(position, BOPPO_SEARCH_RADIUS).forEach(function(entityID) {
|
||||
try {
|
||||
if (JSON.parse(Entities.getEntityProperties(entityID, ['userData']).userData).Boppo.type === 'boppo') {
|
||||
Entities.deleteEntity(entityID);
|
||||
}
|
||||
} catch (e) {
|
||||
// e
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var updateTimerDisplay = function() {
|
||||
if (_boppoEntities['timer']) {
|
||||
var secondsString = _timeLeft % SECONDS_PER_MINUTE;
|
||||
if (secondsString < BASE_TEN) {
|
||||
secondsString = '0' + secondsString;
|
||||
}
|
||||
var minutesString = Math.floor(_timeLeft / SECONDS_PER_MINUTE);
|
||||
Entities.editEntity(_boppoEntities['timer'], {
|
||||
text: minutesString + ':' + secondsString
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var updateScoreDisplay = function() {
|
||||
if (_boppoEntities['score']) {
|
||||
Entities.editEntity(_boppoEntities['score'], {
|
||||
text: 'SCORE: ' + _hits
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var playSoundAtBoxingRing = function(sound, properties) {
|
||||
var _properties = properties ? properties : {};
|
||||
if (_properties['volume'] === undefined) {
|
||||
_properties['volume'] = DEFAULT_SOUND_VOLUME;
|
||||
}
|
||||
_properties['position'] = Entities.getEntityProperties(_entityID, ['position']).position;
|
||||
// play beep
|
||||
return Audio.playSound(sound, _properties);
|
||||
};
|
||||
|
||||
var onUpdate = function() {
|
||||
_timeLeft--;
|
||||
|
||||
if (_timeLeft > 0 && _timeLeft <= TICK_TOCK_FROM) {
|
||||
// play beep
|
||||
playSoundAtBoxingRing(_tickTockSound);
|
||||
}
|
||||
if (_timeLeft === 0) {
|
||||
if (_musicInjector !== undefined && _musicInjector.isPlaying()) {
|
||||
_musicInjector.stop();
|
||||
_musicInjector = undefined;
|
||||
}
|
||||
playSoundAtBoxingRing(_boxingBellRingEnd);
|
||||
_isGameRunning = false;
|
||||
Script.clearInterval(_updateInterval);
|
||||
_updateInterval = null;
|
||||
_coolDown = true;
|
||||
Script.setTimeout(function() {
|
||||
_coolDown = false;
|
||||
_this.resetBoppo();
|
||||
}, COOLDOWN_TIME_MS);
|
||||
}
|
||||
updateTimerDisplay();
|
||||
};
|
||||
|
||||
var onMessage = function(channel, message, sender) {
|
||||
if (channel === _channel) {
|
||||
if (message === MESSAGE_HIT) {
|
||||
_this.hit();
|
||||
} else if (message === MESSAGE_ENTER_ZONE && !_isGameRunning) {
|
||||
_this.resetBoppo();
|
||||
} else if (message === MESSAGE_UNLOAD_FIX && _isInitialized) {
|
||||
_this.unload();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var BoppoServer = function () {
|
||||
_this = this;
|
||||
_hits = 0;
|
||||
_boppoClownID = null;
|
||||
_coolDown = false;
|
||||
CLOWN_LAUGHS.forEach(function(clownLaugh) {
|
||||
_clownLaughs.push(SoundCache.getSound(SFX_PREFIX + clownLaugh));
|
||||
});
|
||||
_tickTockSound = SoundCache.getSound(SFX_PREFIX + TICK_TOCK_SOUND);
|
||||
_boxingBellRingStart = SoundCache.getSound(SFX_PREFIX + BOXING_RING_BELL_START);
|
||||
_boxingBellRingEnd = SoundCache.getSound(SFX_PREFIX + BOXING_RING_BELL_END);
|
||||
_music = SoundCache.getSound(SFX_PREFIX + BOPPO_MUSIC);
|
||||
_boppoEntities = {};
|
||||
};
|
||||
|
||||
BoppoServer.prototype = {
|
||||
preload: function(entityID) {
|
||||
_entityID = entityID;
|
||||
_channel = CHANNEL_PREFIX + entityID;
|
||||
|
||||
Messages.sendLocalMessage(_channel, MESSAGE_UNLOAD_FIX);
|
||||
Script.setTimeout(function() {
|
||||
clearUntrackedBoppos();
|
||||
updateBoppoEntities();
|
||||
Messages.subscribe(_channel);
|
||||
Messages.messageReceived.connect(onMessage);
|
||||
_this.resetBoppo();
|
||||
_isInitialized = true;
|
||||
}, LOAD_TIMEOUT);
|
||||
},
|
||||
resetBoppo: function() {
|
||||
if (_boppoClownID !== null) {
|
||||
print('deleting boppo: ' + _boppoClownID);
|
||||
Entities.deleteEntity(_boppoClownID);
|
||||
}
|
||||
var boppoBaseProperties = Entities.getEntityProperties(_entityID, ['position', 'rotation']);
|
||||
_boppoClownID = Entities.addEntity({
|
||||
angularDamping: 0.0,
|
||||
collisionSoundURL: 'https://hifi-content.s3.amazonaws.com/caitlyn/production/elBoppo/51460__andre-rocha-nascimento__basket-ball-01-bounce.wav',
|
||||
collisionsWillMove: true,
|
||||
compoundShapeURL: 'https://hifi-content.s3.amazonaws.com/caitlyn/production/elBoppo/bopo_phys.obj',
|
||||
damping: 1.0,
|
||||
density: 10000,
|
||||
dimensions: {
|
||||
x: 1.2668079137802124,
|
||||
y: 2.0568051338195801,
|
||||
z: 0.88563752174377441
|
||||
},
|
||||
dynamic: 1.0,
|
||||
friction: 1.0,
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: -25,
|
||||
z: 0
|
||||
},
|
||||
modelURL: 'https://hifi-content.s3.amazonaws.com/caitlyn/production/elBoppo/elBoppo3_VR.fbx',
|
||||
name: 'El Boppo the Punching Bag Clown',
|
||||
registrationPoint: {
|
||||
x: 0.5,
|
||||
y: 0,
|
||||
z: 0.3
|
||||
},
|
||||
restitution: 0.99,
|
||||
rotation: boppoBaseProperties.rotation,
|
||||
position: Vec3.sum(boppoBaseProperties.position,
|
||||
Vec3.multiplyQbyV(boppoBaseProperties.rotation, {
|
||||
x: 0.08666179329156876,
|
||||
y: -1.5698202848434448,
|
||||
z: 0.1847127377986908
|
||||
})),
|
||||
script: Script.resolvePath('boppoClownEntity.js'),
|
||||
shapeType: 'compound',
|
||||
type: 'Model',
|
||||
userData: JSON.stringify({
|
||||
lookAt: {
|
||||
targetID: _boppoEntities['lookAtThis'],
|
||||
disablePitch: true,
|
||||
disableYaw: false,
|
||||
disableRoll: true,
|
||||
clearDisabledAxis: true,
|
||||
rotationOffset: { x: 0.0, y: 180.0, z: 0.0}
|
||||
},
|
||||
Boppo: {
|
||||
type: 'boppo',
|
||||
gameParentID: _entityID
|
||||
},
|
||||
grabbableKey: {
|
||||
grabbable: false
|
||||
}
|
||||
})
|
||||
});
|
||||
updateBoppoEntities();
|
||||
_boppoEntities['boppo'] = _boppoClownID;
|
||||
},
|
||||
laugh: function() {
|
||||
if (_laughingInjector !== undefined && _laughingInjector.isPlaying()) {
|
||||
return;
|
||||
}
|
||||
var randomLaughIndex = Math.floor(Math.random() * _clownLaughs.length);
|
||||
_laughingInjector = Audio.playSound(_clownLaughs[randomLaughIndex], {
|
||||
position: Entities.getEntityProperties(_boppoClownID, ['position']).position
|
||||
});
|
||||
},
|
||||
hit: function() {
|
||||
if (_coolDown) {
|
||||
return;
|
||||
}
|
||||
if (!_isGameRunning) {
|
||||
var boxingRingBoppoData = getOwnBoppoUserData();
|
||||
_updateInterval = Script.setInterval(onUpdate, MILLISECONDS_PER_SECOND);
|
||||
_timeLeft = boxingRingBoppoData.playTimeSeconds ? parseInt(boxingRingBoppoData.playTimeSeconds) :
|
||||
DEFAULT_PLAYTIME;
|
||||
_isGameRunning = true;
|
||||
_hits = 0;
|
||||
playSoundAtBoxingRing(_boxingBellRingStart);
|
||||
_musicInjector = playSoundAtBoxingRing(_music, {loop: true, volume: 0.6});
|
||||
}
|
||||
_hits++;
|
||||
updateTimerDisplay();
|
||||
updateScoreDisplay();
|
||||
_this.laugh();
|
||||
},
|
||||
unload: function() {
|
||||
print('unload called');
|
||||
if (_updateInterval) {
|
||||
Script.clearInterval(_updateInterval);
|
||||
}
|
||||
Messages.messageReceived.disconnect(onMessage);
|
||||
Messages.unsubscribe(_channel);
|
||||
Entities.deleteEntity(_boppoClownID);
|
||||
print('endOfUnload');
|
||||
}
|
||||
};
|
||||
|
||||
return new BoppoServer();
|
||||
};
|
||||
|
||||
return createBoppoServer();
|
||||
});
|
154
unpublishedScripts/marketplace/boppo/clownGloveDispenser.js
Normal file
|
@ -0,0 +1,154 @@
|
|||
//
|
||||
// clownGloveDispenser.js
|
||||
//
|
||||
// Created by Thijs Wenker on 8/2/16.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Based on examples/winterSmashUp/targetPractice/shooterPlatform.js
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
(function() {
|
||||
var _this = this;
|
||||
|
||||
var CHANNEL_PREFIX = 'io.highfidelity.boppo_server_';
|
||||
|
||||
var leftBoxingGlove = undefined;
|
||||
var rightBoxingGlove = undefined;
|
||||
|
||||
var inZone = false;
|
||||
|
||||
var wearGloves = function() {
|
||||
leftBoxingGlove = Entities.addEntity({
|
||||
position: MyAvatar.position,
|
||||
collisionsWillMove: true,
|
||||
dimensions: {
|
||||
x: 0.24890634417533875,
|
||||
y: 0.28214839100837708,
|
||||
z: 0.21127720177173615
|
||||
},
|
||||
dynamic: true,
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: -9.8,
|
||||
z: 0
|
||||
},
|
||||
modelURL: "https://hifi-content.s3.amazonaws.com/caitlyn/production/elBoppo/LFT_glove_VR3.fbx",
|
||||
name: "Boxing Glove - Left",
|
||||
registrationPoint: {
|
||||
x: 0.5,
|
||||
y: 0,
|
||||
z: 0.5
|
||||
},
|
||||
shapeType: "simple-hull",
|
||||
type: "Model",
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
invertSolidWhileHeld: true
|
||||
},
|
||||
wearable: {
|
||||
joints: {
|
||||
LeftHand: [
|
||||
{x: 0, y: 0.0, z: 0.02 },
|
||||
Quat.fromVec3Degrees({x: 0, y: 0, z: 0})
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
Messages.sendLocalMessage('Hifi-Hand-Grab', JSON.stringify({hand: 'left', entityID: leftBoxingGlove}));
|
||||
// Allows teleporting while glove is wielded
|
||||
Messages.sendLocalMessage('Hifi-Teleport-Ignore-Add', leftBoxingGlove);
|
||||
|
||||
rightBoxingGlove = Entities.addEntity({
|
||||
position: MyAvatar.position,
|
||||
collisionsWillMove: true,
|
||||
dimensions: {
|
||||
x: 0.24890634417533875,
|
||||
y: 0.28214839100837708,
|
||||
z: 0.21127720177173615
|
||||
},
|
||||
dynamic: true,
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: -9.8,
|
||||
z: 0
|
||||
},
|
||||
modelURL: "https://hifi-content.s3.amazonaws.com/caitlyn/production/elBoppo/RT_glove_VR2.fbx",
|
||||
name: "Boxing Glove - Right",
|
||||
registrationPoint: {
|
||||
x: 0.5,
|
||||
y: 0,
|
||||
z: 0.5
|
||||
},
|
||||
shapeType: "simple-hull",
|
||||
type: "Model",
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
invertSolidWhileHeld: true
|
||||
},
|
||||
wearable: {
|
||||
joints: {
|
||||
RightHand: [
|
||||
{x: 0, y: 0.0, z: 0.02 },
|
||||
Quat.fromVec3Degrees({x: 0, y: 0, z: 0})
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
Messages.sendLocalMessage('Hifi-Hand-Grab', JSON.stringify({hand: 'right', entityID: rightBoxingGlove}));
|
||||
// Allows teleporting while glove is wielded
|
||||
Messages.sendLocalMessage('Hifi-Teleport-Ignore-Add', rightBoxingGlove);
|
||||
};
|
||||
|
||||
var cleanUpGloves = function() {
|
||||
if (leftBoxingGlove !== undefined) {
|
||||
Entities.deleteEntity(leftBoxingGlove);
|
||||
leftBoxingGlove = undefined;
|
||||
}
|
||||
if (rightBoxingGlove !== undefined) {
|
||||
Entities.deleteEntity(rightBoxingGlove);
|
||||
rightBoxingGlove = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
var wearGlovesIfHMD = function() {
|
||||
// cleanup your old gloves if they're still there (unlikely)
|
||||
cleanUpGloves();
|
||||
if (HMD.active) {
|
||||
wearGloves();
|
||||
}
|
||||
};
|
||||
|
||||
_this.preload = function(entityID) {
|
||||
HMD.displayModeChanged.connect(function() {
|
||||
if (inZone) {
|
||||
wearGlovesIfHMD();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
_this.unload = function() {
|
||||
cleanUpGloves();
|
||||
};
|
||||
|
||||
_this.enterEntity = function(entityID) {
|
||||
inZone = true;
|
||||
print('entered boxing glove dispenser entity');
|
||||
wearGlovesIfHMD();
|
||||
|
||||
// Reset boppo if game is not running:
|
||||
var parentID = Entities.getEntityProperties(entityID, ['parentID']).parentID;
|
||||
Messages.sendMessage(CHANNEL_PREFIX + parentID, 'enter-zone');
|
||||
};
|
||||
|
||||
_this.leaveEntity = function(entityID) {
|
||||
inZone = false;
|
||||
cleanUpGloves();
|
||||
};
|
||||
|
||||
_this.unload = _this.leaveEntity;
|
||||
});
|
430
unpublishedScripts/marketplace/boppo/createElBoppo.js
Normal file
|
@ -0,0 +1,430 @@
|
|||
//
|
||||
// createElBoppo.js
|
||||
//
|
||||
// Created by Thijs Wenker on 3/17/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
/* globals SCRIPT_IMPORT_PROPERTIES */
|
||||
|
||||
var MODELS_PATH = 'https://hifi-content.s3.amazonaws.com/DomainContent/Welcome%20Area/production/models/boxingRing/';
|
||||
var WANT_CLEANUP_ON_SCRIPT_ENDING = false;
|
||||
|
||||
var getScriptPath = function(localPath) {
|
||||
if (this.isCleanupAndSpawnScript) {
|
||||
return 'https://hifi-content.s3.amazonaws.com/DomainContent/Welcome%20Area/Scripts/boppo/' + localPath;
|
||||
}
|
||||
return Script.resolvePath(localPath);
|
||||
};
|
||||
|
||||
var getCreatePosition = function() {
|
||||
// can either return position defined by resetScript or avatar position
|
||||
if (this.isCleanupAndSpawnScript) {
|
||||
return SCRIPT_IMPORT_PROPERTIES.rootPosition;
|
||||
}
|
||||
return Vec3.sum(MyAvatar.position, {x: 1, z: -2});
|
||||
};
|
||||
|
||||
var boxingRing = Entities.addEntity({
|
||||
dimensions: {
|
||||
x: 4.0584001541137695,
|
||||
y: 4.0418000221252441,
|
||||
z: 3.0490000247955322
|
||||
},
|
||||
modelURL: MODELS_PATH + 'assembled/boppoBoxingRingAssembly.fbx',
|
||||
name: 'Boxing Ring Assembly',
|
||||
rotation: {
|
||||
w: 0.9996337890625,
|
||||
x: -1.52587890625e-05,
|
||||
y: -0.026230275630950928,
|
||||
z: -4.57763671875e-05
|
||||
},
|
||||
position: getCreatePosition(),
|
||||
scriptTimestamp: 1489612158459,
|
||||
serverScripts: getScriptPath('boppoServer.js'),
|
||||
shapeType: 'static-mesh',
|
||||
type: 'Model',
|
||||
userData: JSON.stringify({
|
||||
Boppo: {
|
||||
type: 'boxingring',
|
||||
playTimeSeconds: 15
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
var boppoEntities = [
|
||||
{
|
||||
dimensions: {
|
||||
x: 0.36947935819625854,
|
||||
y: 0.25536194443702698,
|
||||
z: 0.059455446898937225
|
||||
},
|
||||
modelURL: MODELS_PATH + 'boxingGameSign/boppoSignFrame.fbx',
|
||||
parentID: boxingRing,
|
||||
localPosition: {
|
||||
x: -1.0251024961471558,
|
||||
y: 0.51661628484725952,
|
||||
z: -1.1176263093948364
|
||||
},
|
||||
rotation: {
|
||||
w: 0.996856689453125,
|
||||
x: 0.013321161270141602,
|
||||
y: 0.0024566650390625,
|
||||
z: 0.078049898147583008
|
||||
},
|
||||
shapeType: 'box',
|
||||
type: 'Model'
|
||||
},
|
||||
{
|
||||
dimensions: {
|
||||
x: 0.33255371451377869,
|
||||
y: 0.1812121719121933,
|
||||
z: 0.0099999997764825821
|
||||
},
|
||||
lineHeight: 0.125,
|
||||
name: 'Boxing Ring - High Score Board',
|
||||
parentID: boxingRing,
|
||||
localPosition: {
|
||||
x: -1.0239436626434326,
|
||||
y: 0.52212876081466675,
|
||||
z: -1.0971509218215942
|
||||
},
|
||||
rotation: {
|
||||
w: 0.9876401424407959,
|
||||
x: 0.013046503067016602,
|
||||
y: 0.0012359619140625,
|
||||
z: 0.15605401992797852
|
||||
},
|
||||
text: '0:00',
|
||||
textColor: {
|
||||
blue: 0,
|
||||
green: 0,
|
||||
red: 255
|
||||
},
|
||||
type: 'Text',
|
||||
userData: JSON.stringify({
|
||||
Boppo: {
|
||||
type: 'timer'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
dimensions: {
|
||||
x: 0.50491130352020264,
|
||||
y: 0.13274604082107544,
|
||||
z: 0.0099999997764825821
|
||||
},
|
||||
lineHeight: 0.090000003576278687,
|
||||
name: 'Boxing Ring - Score Board',
|
||||
parentID: boxingRing,
|
||||
localPosition: {
|
||||
x: -0.77596306800842285,
|
||||
y: 0.37797555327415466,
|
||||
z: -1.0910623073577881
|
||||
},
|
||||
rotation: {
|
||||
w: 0.9518122673034668,
|
||||
x: 0.004237703513354063,
|
||||
y: -0.0010041374480351806,
|
||||
z: 0.30455198884010315
|
||||
},
|
||||
text: 'SCORE: 0',
|
||||
textColor: {
|
||||
blue: 0,
|
||||
green: 0,
|
||||
red: 255
|
||||
},
|
||||
type: 'Text',
|
||||
userData: JSON.stringify({
|
||||
Boppo: {
|
||||
type: 'score'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
dimensions: {
|
||||
x: 0.58153259754180908,
|
||||
y: 0.1884911060333252,
|
||||
z: 0.059455446898937225
|
||||
},
|
||||
modelURL: MODELS_PATH + 'boxingGameSign/boppoSignFrame.fbx',
|
||||
parentID: boxingRing,
|
||||
localPosition: {
|
||||
x: -0.78200173377990723,
|
||||
y: 0.35684797167778015,
|
||||
z: -1.108180046081543
|
||||
},
|
||||
rotation: {
|
||||
w: 0.97814905643463135,
|
||||
x: 0.0040436983108520508,
|
||||
y: -0.0005645751953125,
|
||||
z: 0.20778214931488037
|
||||
},
|
||||
shapeType: 'box',
|
||||
type: 'Model'
|
||||
},
|
||||
{
|
||||
dimensions: {
|
||||
x: 4.1867804527282715,
|
||||
y: 3.5065803527832031,
|
||||
z: 5.6845207214355469
|
||||
},
|
||||
name: 'El Boppo the Clown boxing area & glove maker',
|
||||
parentID: boxingRing,
|
||||
localPosition: {
|
||||
x: -0.012308252975344658,
|
||||
y: 0.054641719907522202,
|
||||
z: 0.98782551288604736
|
||||
},
|
||||
rotation: {
|
||||
w: 1,
|
||||
x: -1.52587890625e-05,
|
||||
y: -1.52587890625e-05,
|
||||
z: -1.52587890625e-05
|
||||
},
|
||||
script: getScriptPath('clownGloveDispenser.js'),
|
||||
shapeType: 'box',
|
||||
type: 'Zone',
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
color: {
|
||||
blue: 255,
|
||||
green: 5,
|
||||
red: 255
|
||||
},
|
||||
dimensions: {
|
||||
x: 0.20000000298023224,
|
||||
y: 0.20000000298023224,
|
||||
z: 0.20000000298023224
|
||||
},
|
||||
name: 'LookAtBox',
|
||||
parentID: boxingRing,
|
||||
localPosition: {
|
||||
x: -0.1772226095199585,
|
||||
y: -1.7072629928588867,
|
||||
z: 1.3122396469116211
|
||||
},
|
||||
rotation: {
|
||||
w: 0.999969482421875,
|
||||
x: 1.52587890625e-05,
|
||||
y: 0.0043793916702270508,
|
||||
z: 1.52587890625e-05
|
||||
},
|
||||
shape: 'Cube',
|
||||
type: 'Box',
|
||||
userData: JSON.stringify({
|
||||
Boppo: {
|
||||
type: 'lookAtThis'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
color: {
|
||||
blue: 209,
|
||||
green: 157,
|
||||
red: 209
|
||||
},
|
||||
dimensions: {
|
||||
x: 1.6913000345230103,
|
||||
y: 1.2124500274658203,
|
||||
z: 0.2572999894618988
|
||||
},
|
||||
name: 'boppoBackBoard',
|
||||
parentID: boxingRing,
|
||||
localPosition: {
|
||||
x: -0.19500596821308136,
|
||||
y: -1.1044719219207764,
|
||||
z: -0.55993378162384033
|
||||
},
|
||||
rotation: {
|
||||
w: 0.9807126522064209,
|
||||
x: -0.19511711597442627,
|
||||
y: 0.0085297822952270508,
|
||||
z: 0.0016937255859375
|
||||
},
|
||||
shape: 'Cube',
|
||||
type: 'Box',
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
color: {
|
||||
blue: 0,
|
||||
green: 0,
|
||||
red: 255
|
||||
},
|
||||
dimensions: {
|
||||
x: 1.8155574798583984,
|
||||
y: 0.92306196689605713,
|
||||
z: 0.51203572750091553
|
||||
},
|
||||
name: 'boppoBackBoard',
|
||||
parentID: boxingRing,
|
||||
localPosition: {
|
||||
x: -0.11036647111177444,
|
||||
y: -0.051978692412376404,
|
||||
z: -0.79054081439971924
|
||||
},
|
||||
rotation: {
|
||||
w: 0.9807431697845459,
|
||||
x: 0.19505608081817627,
|
||||
y: 0.0085602998733520508,
|
||||
z: -0.0017547607421875
|
||||
},
|
||||
shape: 'Cube',
|
||||
type: 'Box',
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
color: {
|
||||
blue: 209,
|
||||
green: 157,
|
||||
red: 209
|
||||
},
|
||||
dimensions: {
|
||||
x: 1.9941408634185791,
|
||||
y: 1.2124500274658203,
|
||||
z: 0.2572999894618988
|
||||
},
|
||||
name: 'boppoBackBoard',
|
||||
localPosition: {
|
||||
x: 0.69560068845748901,
|
||||
y: -1.3840068578720093,
|
||||
z: 0.059689953923225403
|
||||
},
|
||||
rotation: {
|
||||
w: 0.73458456993103027,
|
||||
x: -0.24113833904266357,
|
||||
y: -0.56545358896255493,
|
||||
z: -0.28734266757965088
|
||||
},
|
||||
shape: 'Cube',
|
||||
type: 'Box',
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
color: {
|
||||
blue: 82,
|
||||
green: 82,
|
||||
red: 82
|
||||
},
|
||||
dimensions: {
|
||||
x: 8.3777303695678711,
|
||||
y: 0.87573593854904175,
|
||||
z: 7.9759469032287598
|
||||
},
|
||||
parentID: boxingRing,
|
||||
localPosition: {
|
||||
x: -0.38302639126777649,
|
||||
y: -2.121284008026123,
|
||||
z: 0.3699878454208374
|
||||
},
|
||||
rotation: {
|
||||
w: 0.70711839199066162,
|
||||
x: -7.62939453125e-05,
|
||||
y: 0.70705735683441162,
|
||||
z: -1.52587890625e-05
|
||||
},
|
||||
shape: 'Triangle',
|
||||
type: 'Shape'
|
||||
},
|
||||
{
|
||||
color: {
|
||||
blue: 209,
|
||||
green: 157,
|
||||
red: 209
|
||||
},
|
||||
dimensions: {
|
||||
x: 1.889795184135437,
|
||||
y: 0.86068248748779297,
|
||||
z: 0.2572999894618988
|
||||
},
|
||||
name: 'boppoBackBoard',
|
||||
parentID: boxingRing,
|
||||
localPosition: {
|
||||
x: -0.95167744159698486,
|
||||
y: -1.4756947755813599,
|
||||
z: -0.042313352227210999
|
||||
},
|
||||
rotation: {
|
||||
w: 0.74004733562469482,
|
||||
x: -0.24461740255355835,
|
||||
y: 0.56044864654541016,
|
||||
z: 0.27998781204223633
|
||||
},
|
||||
shape: 'Cube',
|
||||
type: 'Box',
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
color: {
|
||||
blue: 0,
|
||||
green: 0,
|
||||
red: 255
|
||||
},
|
||||
dimensions: {
|
||||
x: 4.0720257759094238,
|
||||
y: 0.50657749176025391,
|
||||
z: 1.4769613742828369
|
||||
},
|
||||
name: 'boppo-stepsRamp',
|
||||
parentID: boxingRing,
|
||||
localPosition: {
|
||||
x: -0.002939039608463645,
|
||||
y: -1.9770187139511108,
|
||||
z: 2.2165381908416748
|
||||
},
|
||||
rotation: {
|
||||
w: 0.99252307415008545,
|
||||
x: 0.12184333801269531,
|
||||
y: -1.52587890625e-05,
|
||||
z: -1.52587890625e-05
|
||||
},
|
||||
shape: 'Cube',
|
||||
type: 'Box',
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
color: {
|
||||
blue: 150,
|
||||
green: 150,
|
||||
red: 150
|
||||
},
|
||||
cutoff: 90,
|
||||
dimensions: {
|
||||
x: 5.2220535278320312,
|
||||
y: 5.2220535278320312,
|
||||
z: 5.2220535278320312
|
||||
},
|
||||
falloffRadius: 2,
|
||||
intensity: 15,
|
||||
name: 'boxing ring light',
|
||||
parentID: boxingRing,
|
||||
localPosition: {
|
||||
x: -1.4094564914703369,
|
||||
y: -0.36021926999092102,
|
||||
z: 0.81797939538955688
|
||||
},
|
||||
rotation: {
|
||||
w: 0.9807431697845459,
|
||||
x: 1.52587890625e-05,
|
||||
y: -0.19520866870880127,
|
||||
z: -1.52587890625e-05
|
||||
},
|
||||
type: 'Light'
|
||||
}
|
||||
];
|
||||
|
||||
boppoEntities.forEach(function(entityProperties) {
|
||||
entityProperties['parentID'] = boxingRing;
|
||||
Entities.addEntity(entityProperties);
|
||||
});
|
||||
|
||||
if (WANT_CLEANUP_ON_SCRIPT_ENDING) {
|
||||
Script.scriptEnding.connect(function() {
|
||||
Entities.deleteEntity(boxingRing);
|
||||
});
|
||||
}
|
98
unpublishedScripts/marketplace/boppo/lookAtEntity.js
Normal file
|
@ -0,0 +1,98 @@
|
|||
//
|
||||
// lookAtTarget.js
|
||||
//
|
||||
// Created by Thijs Wenker on 3/15/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
/* globals LookAtTarget:true */
|
||||
|
||||
LookAtTarget = function(sourceEntityID) {
|
||||
/* private variables */
|
||||
var _this,
|
||||
_options,
|
||||
_sourceEntityID,
|
||||
_sourceEntityProperties,
|
||||
REQUIRED_PROPERTIES = ['position', 'rotation', 'userData'],
|
||||
LOOK_AT_TAG = 'lookAtTarget';
|
||||
|
||||
LookAtTarget = function(sourceEntityID) {
|
||||
_this = this;
|
||||
_sourceEntityID = sourceEntityID;
|
||||
_this.updateOptions();
|
||||
};
|
||||
|
||||
/* private functions */
|
||||
var updateEntitySourceProperties = function() {
|
||||
_sourceEntityProperties = Entities.getEntityProperties(_sourceEntityID, REQUIRED_PROPERTIES);
|
||||
};
|
||||
|
||||
var getUpdatedActionProperties = function() {
|
||||
return {
|
||||
targetRotation: _this.getLookAtRotation(),
|
||||
angularTimeScale: 0.1,
|
||||
ttl: 10
|
||||
};
|
||||
};
|
||||
|
||||
var getNewActionProperties = function() {
|
||||
var newActionProperties = getUpdatedActionProperties();
|
||||
newActionProperties.tag = LOOK_AT_TAG;
|
||||
return newActionProperties;
|
||||
};
|
||||
|
||||
LookAtTarget.prototype = {
|
||||
/* public functions */
|
||||
updateOptions: function() {
|
||||
updateEntitySourceProperties();
|
||||
_options = JSON.parse(_sourceEntityProperties.userData).lookAt;
|
||||
},
|
||||
getTargetPosition: function() {
|
||||
return Entities.getEntityProperties(_options.targetID).position;
|
||||
},
|
||||
getLookAtRotation: function() {
|
||||
_this.updateOptions();
|
||||
|
||||
var newRotation = Quat.lookAt(_sourceEntityProperties.position, _this.getTargetPosition(), Vec3.UP);
|
||||
if (_options.rotationOffset !== undefined) {
|
||||
newRotation = Quat.multiply(newRotation, Quat.fromVec3Degrees(_options.rotationOffset));
|
||||
}
|
||||
if (_options.disablePitch || _options.disableYaw || _options.disablePitch) {
|
||||
var disabledAxis = _options.clearDisabledAxis ? Vec3.ZERO :
|
||||
Quat.safeEulerAngles(_sourceEntityProperties.rotation);
|
||||
var newEulers = Quat.safeEulerAngles(newRotation);
|
||||
newRotation = Quat.fromVec3Degrees({
|
||||
x: _options.disablePitch ? disabledAxis.x : newEulers.x,
|
||||
y: _options.disableYaw ? disabledAxis.y : newEulers.y,
|
||||
z: _options.disableRoll ? disabledAxis.z : newEulers.z
|
||||
});
|
||||
}
|
||||
return newRotation;
|
||||
},
|
||||
lookAtDirectly: function() {
|
||||
Entities.editEntity(_sourceEntityID, {rotation: _this.getLookAtRotation()});
|
||||
},
|
||||
lookAtByAction: function() {
|
||||
var actionIDs = Entities.getActionIDs(_sourceEntityID);
|
||||
var actionFound = false;
|
||||
actionIDs.forEach(function(actionID) {
|
||||
if (actionFound) {
|
||||
return;
|
||||
}
|
||||
var actionArguments = Entities.getActionArguments(_sourceEntityID, actionID);
|
||||
if (actionArguments.tag === LOOK_AT_TAG) {
|
||||
actionFound = true;
|
||||
Entities.updateAction(_sourceEntityID, actionID, getUpdatedActionProperties());
|
||||
}
|
||||
});
|
||||
if (!actionFound) {
|
||||
Entities.addAction('spring', _sourceEntityID, getNewActionProperties());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return new LookAtTarget(sourceEntityID);
|
||||
};
|