|
|
@ -9,12 +9,14 @@ homeContainer.add(home) |
|
|
|
|
|
|
|
|
|
|
|
var areaNames = [ ] |
|
|
|
var areaNames = [ ] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var areasWithEntitiesToUpdate = { } |
|
|
|
|
|
|
|
|
|
|
|
const renderer = new THREE.WebGLRenderer() |
|
|
|
const renderer = new THREE.WebGLRenderer() |
|
|
|
renderer.setSize( window.innerWidth, window.innerHeight ) |
|
|
|
renderer.setSize( window.innerWidth, window.innerHeight ) |
|
|
|
document.body.appendChild( renderer.domElement ) |
|
|
|
document.body.appendChild( renderer.domElement ) |
|
|
|
|
|
|
|
|
|
|
|
const light = new THREE.AmbientLight(0xFFAAAA, 1) |
|
|
|
const light = new THREE.AmbientLight(0xFFAAAA, 1) |
|
|
|
// light.position.z = 100
|
|
|
|
light.position.z = 100 |
|
|
|
scene.add(light) |
|
|
|
scene.add(light) |
|
|
|
scene.background = new THREE.Color("white") |
|
|
|
scene.background = new THREE.Color("white") |
|
|
|
|
|
|
|
|
|
|
@ -27,8 +29,44 @@ home.rotation.x = Math.PI |
|
|
|
// Rotate container a bit for comfort
|
|
|
|
// Rotate container a bit for comfort
|
|
|
|
homeContainer.rotation.x = 0.6 * (-Math.PI / 2) |
|
|
|
homeContainer.rotation.x = 0.6 * (-Math.PI / 2) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Returns the first child (or container) whose name matches
|
|
|
|
|
|
|
|
function childWithName(container, name) { |
|
|
|
|
|
|
|
if (container.userData.name == name) { |
|
|
|
|
|
|
|
return container; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
for (var child of container.children) { |
|
|
|
|
|
|
|
let childMatches = childWithName(child, name) |
|
|
|
|
|
|
|
if (childMatches != null) { |
|
|
|
|
|
|
|
return childMatches |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return null |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function animate() { |
|
|
|
function animate() { |
|
|
|
requestAnimationFrame( animate ) |
|
|
|
requestAnimationFrame( animate ) |
|
|
|
|
|
|
|
TWEEN.update() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var areasToUpdate = new Set() |
|
|
|
|
|
|
|
for (var area of Object.keys(areasWithEntitiesToUpdate)) { |
|
|
|
|
|
|
|
let updatedEntities = areasWithEntitiesToUpdate[area] |
|
|
|
|
|
|
|
if (updatedEntities.length > 0) { |
|
|
|
|
|
|
|
areasToUpdate.add(area) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
for (var area of areasToUpdate) { |
|
|
|
|
|
|
|
let areaContainer = childWithName(scene, area) |
|
|
|
|
|
|
|
let box = childWithName(areaContainer, "box") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let fadeIn = new TWEEN.Tween(box.material) |
|
|
|
|
|
|
|
.to( { opacity: 1.0 }, 1000) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let fadeOut = new TWEEN.Tween(box.material) |
|
|
|
|
|
|
|
.to( { opacity: 0.1 }, 1000) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fadeIn.chain(fadeOut) |
|
|
|
|
|
|
|
fadeIn.start() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
homeContainer.rotation.z += 0.005 |
|
|
|
homeContainer.rotation.z += 0.005 |
|
|
|
|
|
|
|
|
|
|
@ -62,11 +100,14 @@ function createTextMesh(text, colorName) { |
|
|
|
return mesh |
|
|
|
return mesh |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var lastUpdateTime = new Date() |
|
|
|
function updateWithHAData(data) { |
|
|
|
function updateWithHAData(data) { |
|
|
|
// `data` is an array of entities. loop through and group by area
|
|
|
|
// `data` is an array of entities. loop through and group by area
|
|
|
|
var areasToEntities = { } |
|
|
|
var areasToEntities = { } |
|
|
|
|
|
|
|
var areasToUpdatedEntities = { } |
|
|
|
for (var area of areaNames) { |
|
|
|
for (var area of areaNames) { |
|
|
|
areasToEntities[area] = new Array() |
|
|
|
areasToEntities[area] = new Array() |
|
|
|
|
|
|
|
areasToUpdatedEntities[area] = new Array() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
let sortedAreaNames = areaNames |
|
|
|
let sortedAreaNames = areaNames |
|
|
@ -88,10 +129,19 @@ function updateWithHAData(data) { |
|
|
|
let areaEntities = areasToEntities[area] |
|
|
|
let areaEntities = areasToEntities[area] |
|
|
|
areaEntities.push(entity) |
|
|
|
areaEntities.push(entity) |
|
|
|
areasToEntities[area] = areaEntities |
|
|
|
areasToEntities[area] = areaEntities |
|
|
|
break |
|
|
|
|
|
|
|
|
|
|
|
let lastUpdate = new Date(entity.last_changed) |
|
|
|
|
|
|
|
if (lastUpdate > lastUpdateTime) { |
|
|
|
|
|
|
|
let areaUpdatedEntities = areasToUpdatedEntities[area] |
|
|
|
|
|
|
|
areaUpdatedEntities.push(entity) |
|
|
|
|
|
|
|
areasToUpdatedEntities[area] = areaUpdatedEntities |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lastUpdateTime = new Date() |
|
|
|
|
|
|
|
areasWithEntitiesToUpdate = areasToUpdatedEntities |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async function loadHAData() { |
|
|
|
async function loadHAData() { |
|
|
@ -102,6 +152,10 @@ async function loadHAData() { |
|
|
|
}) |
|
|
|
}) |
|
|
|
.then(json => { |
|
|
|
.then(json => { |
|
|
|
updateWithHAData(json) |
|
|
|
updateWithHAData(json) |
|
|
|
|
|
|
|
new Promise(resolve => setTimeout(resolve, 250)) |
|
|
|
|
|
|
|
.then(_ => { |
|
|
|
|
|
|
|
loadHAData() |
|
|
|
|
|
|
|
}) |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -127,25 +181,26 @@ function configureScene(data) { |
|
|
|
for (var room of data.rooms) { |
|
|
|
for (var room of data.rooms) { |
|
|
|
areaNames.push(room.name) |
|
|
|
areaNames.push(room.name) |
|
|
|
let roomContainer = new THREE.Group() |
|
|
|
let roomContainer = new THREE.Group() |
|
|
|
roomContainer.userData = room.name |
|
|
|
roomContainer.userData.name = room.name |
|
|
|
|
|
|
|
|
|
|
|
let roomGeo = new THREE.BoxGeometry(room.w, room.h, room.d) |
|
|
|
let roomGeo = new THREE.BoxGeometry(room.w, room.h, room.d) |
|
|
|
let roomColor = new THREE.Color(room.color) |
|
|
|
let roomColor = new THREE.Color(room.color) |
|
|
|
let roomBoxMaterial = new THREE.MeshPhysicalMaterial({ color: roomColor }) |
|
|
|
let roomBoxMaterial = new THREE.MeshPhysicalMaterial({ color: roomColor }) |
|
|
|
roomBoxMaterial.transparent = true |
|
|
|
roomBoxMaterial.transparent = true |
|
|
|
roomBoxMaterial.opacity = 0.3 |
|
|
|
roomBoxMaterial.opacity = 0.1 |
|
|
|
let roomMesh = new THREE.Mesh(roomGeo, roomBoxMaterial) |
|
|
|
let roomMesh = new THREE.Mesh(roomGeo, roomBoxMaterial) |
|
|
|
roomMesh.userData = "box" |
|
|
|
roomMesh.userData.name = "box" |
|
|
|
roomContainer.add(roomMesh) |
|
|
|
roomContainer.add(roomMesh) |
|
|
|
|
|
|
|
|
|
|
|
let roomEdgesGeo = new THREE.EdgesGeometry(roomGeo) |
|
|
|
let roomEdgesGeo = new THREE.EdgesGeometry(roomGeo) |
|
|
|
let roomLinesMaterial = new THREE.LineBasicMaterial({ color: roomColor }) |
|
|
|
let roomLinesMaterial = new THREE.LineBasicMaterial({ color: roomColor }) |
|
|
|
|
|
|
|
roomLinesMaterial.linewidth = 3 |
|
|
|
let roomLines = new THREE.LineSegments(roomEdgesGeo, roomLinesMaterial) |
|
|
|
let roomLines = new THREE.LineSegments(roomEdgesGeo, roomLinesMaterial) |
|
|
|
roomLines.userData = "lines" |
|
|
|
roomLines.userData.name = "lines" |
|
|
|
roomContainer.add(roomLines) |
|
|
|
roomContainer.add(roomLines) |
|
|
|
|
|
|
|
|
|
|
|
let roomLabel = createTextMesh("test", "red") |
|
|
|
let roomLabel = createTextMesh("A test or something", "red") |
|
|
|
roomLabel.userData = "label" |
|
|
|
roomLabel.userData.name = "label" |
|
|
|
roomContainer.add(roomLabel) |
|
|
|
roomContainer.add(roomLabel) |
|
|
|
|
|
|
|
|
|
|
|
setPosition(roomContainer, room.x, room.y, room.z || 0, room.w, room.h, room.d) |
|
|
|
setPosition(roomContainer, room.x, room.y, room.z || 0, room.w, room.h, room.d) |
|
|
|