// Předpoklad: Vytvořená základní scéna s kamerou a světelným zdrojem
function (scene) {
var data = {};
// text ve 3D scéně
var textPlane = new BABYLON.Mesh.CreatePlane("planeForText", 20, scene);
var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateForMesh(textPlane, 2048, 2048);
var text = new BABYLON.GUI.TextBlock();
text.fontSize = 200;
text.outlineWidth = 5;
// propojení textu a datového modelu aplikace pomocí mapy
new MW.TwoWayMap({
end1: data,
map1: MAP.TEXT.to3DModel,
end2: text,
map2: MAP.TEXT.toDataModel,
data1: {
text: 'Hello world!',
diffuseColor: '#dd3300',
outlineColor: '#ee9966',
}
});
advancedTexture.addControl(text);
// Vue aplikace
var app1 = new Vue({
el: '#app1',
data: data
});
}
<form>
<div>
<label>Text</label>
<input type="text" v-model="text" />
</div>
<div class="grid">
<div>
<label>Základní barva</label>
<div>
<input type="color" v-model="diffuseColor" />
<span :style="'color: ' + diffuseColor"> {{ diffuseColor }} </span>
</div>
</div>
<div>
<label>Barva lesku</label>
<div>
<input type="color" v-model="specularColor" />
<span :style="'color: ' + specularColor"> {{ specularColor }} </span>
</div>
</div>
</div>
</form>
// Předpoklad: Vytvořená základní scéna s kamerou a světelným zdrojem
function (scene) {
var group = new BABYLON.AbstractMesh("group", scene);
// fukce pro vytvoření 3D kostky
function createCube(index) {
var data = {};
var material = new BABYLON.StandardMaterial("material" + index, scene);
var cube = new BABYLON.Mesh.CreateBox("box" + index, 1, scene);
cube.material = material;
group.addChild(cube);
// propojení kostky s datovým modelem
new MW.TwoWayMap({
end1: data,
map1: MAP.CUBE.to3DModel,
end2: cube,
map2: MAP.CUBE.toDataModel,
data1: {
color: getRandomColor(),
element: cube,
index: index
}
});
group.position.x = - index;
cube.position.x = index * 2;
return data;
}
// Vue aplikace
var app2 = new Vue({
el: '#app2',
data: {
items: [
createCube(0),
createCube(1)
],
},
methods: {
// metoda pro přidání kostky
add: function () {
this.items.push(createCube(this.items.length));
},
// metoda pro smazání kostky
remove: function (index) {
var mesh = this.items[index].element;
group.removeChild(mesh);
scene.removeMesh(mesh);
this.items.splice(index, 1);
for (var i = index; i < this.items.length; i++) {
var oldX = this.items[i].position.x;
this.items[i].index = i;
this.items[i].element.position.x = this.items[i].element.position.x - 2;
}
group.position.x = - (this.items.length - 1);
}
}
});
}
<form>
<ul>
<li v-for="(item, index) in items">
<div class="grid">
<div>
<label>Objekt #{{index + 1}}</label>
<div>
<input type="color" v-model="item.color" />
<span :style="'color: ' + item.color"> {{ item.color }} </span>
</div>
</div>
<div>
<label>Šířka {{ Math.floor(item.size.x * 100) }}%</label>
<input type="range" v-model="item.size.x" min="0.1" max="2" step="0.1" />
</div>
<div>
<label>Výška {{ Math.floor(item.size.y * 100) }}%</label>
<input type="range" v-model="item.size.y" min="0.1" max="2" step="0.1" />
</div>
<div>
<label>Délka {{ Math.floor(item.size.z * 100) }}%</label>
<input type="range" v-model="item.size.z" min="0.1" max="2" step="0.1" />
</div>
<div>
<label>X {{ item.position.x }}</label>
<input type="range" v-model="item.position.x" min="-1" max="1" step="0.1" />
</div>
<div>
<label>Y {{ item.position.y }}</label>
<input type="range" v-model="item.position.y" min="-1" max="1" step="0.1" />
</div>
<div>
<label>Z {{ item.position.z }}</label>
<input type="range" v-model="item.position.z" min="-1" max="1" step="0.1" />
</div>
<div>
<a v-on:click="remove(index)">Smazat</a>
</div>
</div>
</li>
</ul>
<a v-on:click="add()" > Přidat nový objekt</a>
</form>
// Předpoklad: Vytvořená základní scéna s kamerou a světelným zdrojem
function (scene) {
// "Vlákno" 3D scény
window.sceneWorker = new MW.SyncWorker(function (worker) {
// optimalizovaná funkce pro odeslání zprávy po kliknutí na tlačítko
var numberUpdater = getDebounced(function (number) { worker.postMessage({ type: "number", value: number }); }, 50);
var leds = [], number = 0;
// "glow" efekt
var gl = new BABYLON.GlowLayer("glow", scene, {
mainTextureSamples: 4,
renderingGroupId: 0
});
gl.intensity = 4;
// základní deska
var node = new BABYLON.TransformNode("node");
node.rotation.x = - (Math.PI / 2) * 0.7;
node.scaling = new BABYLON.Vector3(0.8, 0.8, 0.8);
var boardMaterial = new BABYLON.StandardMaterial("board", scene);
boardMaterial.diffuseColor = new BABYLON.Color3(0.05, 0.4, 0.05);
boardMaterial.maxSimultaneousLights = 10;
boardMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
var board = BABYLON.MeshBuilder.CreateBox("board", { width: 16, height: 0.1, depth: 6 }, scene);
board.material = boardMaterial;
board.parent = node;
// Zlatý text
function GoldText(text, size, z) {
var textPlane = new BABYLON.Mesh.CreatePlane("planeForText", 10, scene);
textPlane.rotation.x = (Math.PI / 2);
textPlane.position.y = 0.06;
textPlane.position.z = z;
var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateForMesh(textPlane, 1024, 1024);
var textBlock = new BABYLON.GUI.TextBlock();
textBlock.text = text;
textBlock.fontSize = size;
textBlock.outlineWidth = 0;
textBlock.color = "#ff9900";
advancedTexture.addControl(textBlock);
this.mesh = textPlane;
}
var heading = new GoldText("LED Diody (8 bitů)", 100, 1.6);
heading.mesh.parent = node;
// materiály pro LED diodu
var ledOffMaterial = new BABYLON.StandardMaterial("ledOff", scene);
ledOffMaterial.diffuseColor = new BABYLON.Color3(0.4, 0.4, 0.4);
ledOffMaterial.emissiveColor = new BABYLON.Color3(0.6, 0.6, 0.6);
ledOffMaterial.alpha = 0.8;
ledOffMaterial.maxSimultaneousLights = 10;
var ledOnMaterial = new BABYLON.StandardMaterial("ledOn", scene);
ledOnMaterial.alpha = 0.8;
ledOnMaterial.maxSimultaneousLights = 10;
// LED Dioda
function Led(index) {
var led = new BABYLON.TransformNode("led" + index);
var sphere = BABYLON.MeshBuilder.CreateSphere("sphere" + index, { diameter: 0.8 }, scene);
sphere.position.y = 0.86;
var cylinder = BABYLON.MeshBuilder.CreateCylinder("cylinder" + index, { diameter: 0.8, height: 0.9 }, scene);
cylinder.position.y = 0.46;
var bottom = BABYLON.MeshBuilder.CreateCylinder("cylinder" + index, { diameter: 0.9, height: 0.2 }, scene);
bottom.position.y = 0.11;
sphere.parent = led;
cylinder.parent = led;
bottom.parent = led;
this.switch = function (state) {
if (state) {
sphere.material = ledOnMaterial;
cylinder.material = ledOnMaterial;
bottom.material = ledOnMaterial;
gl.addIncludedOnlyMesh(sphere);
gl.addIncludedOnlyMesh(cylinder);
} else {
sphere.material = ledOffMaterial;
cylinder.material = ledOffMaterial;
bottom.material = ledOffMaterial;
gl.removeIncludedOnlyMesh(sphere);
gl.removeIncludedOnlyMesh(cylinder);
}
sphere.markAsDirty();
cylinder.markAsDirty();
bottom.markAsDirty();
}
this.mesh = led;
}
// materiály pro tlačítko
var buttonMaterial = new BABYLON.StandardMaterial("button", scene);
buttonMaterial.diffuseColor = new BABYLON.Color3(0.5, 0.5, 0.8);
buttonMaterial.maxSimultaneousLights = 10;
var bottomMaterial = new BABYLON.StandardMaterial("bottom", scene);
bottomMaterial.diffuseColor = new BABYLON.Color3(0.1, 0.1, 0.1);
// Tlačítko
function Button(index, switchableLed) {
var button = new BABYLON.TransformNode("button" + index);
var cylinder = BABYLON.MeshBuilder.CreateCylinder("buttonCylinder" + index, { diameter: 0.8, height: 0.8, updatable: true }, scene);
cylinder.position.y = 0.51;
var bottom = BABYLON.MeshBuilder.CreateBox("buttonBottom" + index, { width: 1, height: 0.5, depth: 1 }, scene);
bottom.position.y = 0.26;
cylinder.material = buttonMaterial;
bottom.material = bottomMaterial;
cylinder.parent = button;
bottom.parent = button;
button.position.z = -2;
cylinder.actionManager = new BABYLON.ActionManager(scene);
cylinder.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger, function () {
switchableLed.switch(!switchableLed.state);
number = (number * 1) + (Math.pow(2, index) * (switchableLed.state ? 1 : -1));
gl.intensity = number == 0 ? 0 : 4;
numberUpdater(number);
}));
this.switch = function (state) {
cylinder.scaling.y = state ? 0.5 : 1;
cylinder.markAsDirty();
}
this.mesh = button;
}
// LED Dioda s tlačítkem
function SwitchableLed(index) {
var group = new BABYLON.TransformNode("group" + i);
var led = new Led(index);
var button = new Button(index, this);
var text = new GoldText((Math.pow(2, index)).toString(), 60, -1);
led.mesh.parent = group;
button.mesh.parent = group;
text.mesh.parent = group;
group.position.x = ((((8 - index) - (8 / 2)) * 2) - 1);
group.parent = node;
this.switch = function (state) {
led.switch(state);
button.switch(state);
this.state = state == true;
}
this.state = false;
}
// inicializace LED Diod s tlačítky
for (var i = 0; i < 8; i++) {
leds.push(new SwitchableLed(i));
}
// funkce pro nastavení čísla
function setNumber(value) {
number = value;
var bin = toBin(number);
gl.intensity = number == 0 ? 0 : 4;
for (var i = 0; i < leds.length; i++) {
leds[leds.length - i - 1].switch(bin[i] == "1");
}
}
// funkce pro nastavení barvy světla
function setColor(value) {
ledOnMaterial.diffuseColor.copyFrom(BABYLON.Color3.FromHexString(value));
ledOnMaterial.emissiveColor.copyFrom(BABYLON.Color3.FromHexString(value));
ledOnMaterial.markAsDirty();
}
// zpracování přijatých zpráv
worker.addEventListener("message", function (data) {
switch (data.type) {
case "init":
setNumber(data.number * 1);
setColor(data.color);
break;
case "number":
setNumber(data.value * 1);
break;
case "color":
setColor(data.value);
break;
default: break;
}
});
});
}
// VUE Aplikace v rámci SyncWorker
function () {
// "Vlákno" Vue aplikace
window.appWorker = new MW.SyncWorker(function (worker) {
// Optimalizovaná funkce pro odeslání zprávy o změně čísla
var numberUpdater = getDebounced(function (number) { worker.postMessage({ type: "number", value: number }); }, 50);
// výchozí stav datového modelu
var data = {
int: 50,
color: '#ff0000'
};
// pojistka proti nekonzistenci
var prevent = false;
// zpracování přijatých zpráv
worker.addEventListener("message", function (message) {
switch (message.type) {
case "number":
prevent = true;
data.int = message.value;
break;
default: break;
}
});
// Vue aplikace
var app3 = new Vue({
el: '#app3',
data: data,
// dopočítáváné vlastnosti pro hexadecimální a binární zápis
computed: {
hex: {
get: function () { return toHex(this.int); },
set: function (v) { this.int = parseInt(v, 16); }
},
bin: {
get: function () { return toBin(this.int); },
set: function (v) { this.int = parseInt(v, 2); }
}
},
// sledování změn čísla a barvy
watch: {
int: function (v) {
if (!prevent) {
numberUpdater(v);
}
prevent = false;
},
color: function (v) {
worker.postMessage({ type: "color", value: v });
}
}
});
worker.postMessage({ type: "init", number: data.int, color: data.color });
});
// samotné propojení zasílání zpráv
window.appWorker.addEventListener("message", window.sceneWorker.postMessage);
window.sceneWorker.addEventListener("message", window.appWorker.postMessage);
}
<form>
<div>
<label>
<span class="left">0</span>
<span class="right">255</span>
</label>
<div>
<input type="range" v-model="int" min="0" max="255" step="1" />
</div>
</div>
<div>
<div class="grid">
<div>
<label>Číslo</label>
<input type="text" v-model="int" />
</div>
<div>
<label>Binární zápis</label>
<input type="text" v-model="bin" />
</div>
<div>
<label>Hexadecimální zápis</label>
<input type="text" v-model="hex" />
</div>
<div>
<label>Barva světla</label>
<input type="color" v-model="color" />
<span :style="'color: ' + color"> {{ color }} </span>
</div>
</div>
</div>
</form>