1
0
mirror of https://github.com/beestat/app.git synced 2026-02-26 05:00:21 -05:00
2026-02-22 12:14:59 -05:00

117 lines
3.3 KiB
JavaScript

/**
* Scene methods split from scene.js.
*/
/**
* Get a finite bounding box for scene layout. Empty floor plans can report
* Infinity bounds; clamp those to a reasonable fallback around origin.
*
* @return {{left:number,right:number,top:number,bottom:number,width:number,height:number,x:number,y:number}}
*/
beestat.component.scene.prototype.get_scene_bounding_box_ = function() {
const bounding_box = beestat.floor_plan.get_bounding_box(this.floor_plan_id_);
const is_finite_box =
Number.isFinite(bounding_box.left) &&
Number.isFinite(bounding_box.right) &&
Number.isFinite(bounding_box.top) &&
Number.isFinite(bounding_box.bottom);
if (is_finite_box === true) {
return bounding_box;
}
const fallback_half_size = 180;
return {
'left': -fallback_half_size,
'right': fallback_half_size,
'top': -fallback_half_size,
'bottom': fallback_half_size,
'width': fallback_half_size * 2,
'height': fallback_half_size * 2,
'x': -fallback_half_size,
'y': -fallback_half_size
};
};
/**
* Add a group containing all of the extruded geometry that can be transformed
* all together.
*/
beestat.component.scene.prototype.add_main_group_ = function() {
const bounding_box = this.get_scene_bounding_box_();
// Main group handles orientation and centering
this.main_group_ = new THREE.Group();
// Center the floor plan at origin (accounting for bounding box offset)
this.main_group_.position.set(
(bounding_box.right + bounding_box.left) / -2,
0,
(bounding_box.bottom + bounding_box.top) / -2
);
// Apply X rotation to orient the floor plan
this.main_group_.rotation.x = Math.PI / 2;
this.scene_.add(this.main_group_);
};
/**
* Add the floor plan to the scene.
*/
beestat.component.scene.prototype.add_floor_plan_ = function() {
const self = this;
const floor_plan = beestat.cache.floor_plan[this.floor_plan_id_];
// Initialize layers if not already done
if (this.layers_ === undefined) {
this.layers_ = {};
}
// Create floor plan group for walls, rooms, and roofs
this.floor_plan_group_ = new THREE.Group();
this.main_group_.add(this.floor_plan_group_);
this.layers_['floor_plan'] = this.floor_plan_group_;
const walls_layer = new THREE.Group();
self.floor_plan_group_.add(walls_layer);
self.layers_['walls'] = walls_layer;
floor_plan.data.groups.forEach(function(group) {
const layer = new THREE.Group();
self.floor_plan_group_.add(layer);
self.layers_[group.group_id] = layer;
group.rooms.forEach(function(room) {
self.add_room_(layer, group, room);
});
self.add_walls_(walls_layer, group);
});
this.apply_opening_cuts_(walls_layer, floor_plan);
const openings_layer = new THREE.Group();
this.floor_plan_group_.add(openings_layer);
this.layers_['openings'] = openings_layer;
floor_plan.data.groups.forEach(function(group) {
self.add_opening_fixtures_(openings_layer, group);
});
this.light_sources_ = [];
const light_sources_layer = new THREE.Group();
this.floor_plan_group_.add(light_sources_layer);
this.layers_['light_sources'] = light_sources_layer;
floor_plan.data.groups.forEach(function(group) {
self.add_light_sources_(light_sources_layer, group);
});
// Add roofs using straight skeleton
this.add_roofs_();
this.add_environment_();
};