### Thing.js WallComponent Example Usage Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/components_WallComponent Demonstrates how to create a wall object using the WallComponent. This example shows the instantiation of a THING.Object3D, adding the WallComponent to it, and loading texture-based wall data with material definitions. ```javascript // 模拟数据 const points = [[0, 0], [2, 0], [2, 2], [0, 2]] const materialResource = { map: './images/camera.png' } // 创建对象作为墙体 const wall = new THING.Object3D({ tags: ['BuildingElement', 'Wall'] }); // 实例化平面组件 const wallComponent = new THING.WallComponent(); wall.addComponent(wallComponent, 'wallComponent'); wallComponent.load({ type: 'TextureWall', walls: [ { points: [...points[0], ...points[1]], leftMaterial: materialResource, rightMaterial: materialResource, edgeMaterial: materialResource }, { points: [...points[1], ...points[2]], leftMaterial: materialResource, rightMaterial: materialResource, edgeMaterial: materialResource }, { points: [...points[2], ...points[3]], leftMaterial: materialResource, rightMaterial: materialResource, edgeMaterial: materialResource }, { points: [...points[3], ...points[0]], leftMaterial: materialResource, rightMaterial: materialResource, edgeMaterial: materialResource } ], }).then(() => { console.log('墙体加载完成'); }) ``` -------------------------------- ### Create and Load WallComponent using TextureWall Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/WallComponent This example demonstrates how to instantiate a WallComponent and load a TextureWall. It takes an array of points to define wall segments and specifies material resources for the left, right, and edge surfaces. The `load` method returns a Promise that resolves when the wall is successfully loaded. ```javascript // Simulate data const points = [[0, 0], [2, 0], [2, 2], [0, 2]] const materialResource = { map: './images/camera.png' } // Create an object as a wall const wall = new THING.Object3D({ tags: ['BuildingElement', 'Wall'] }); // Instantiate the plane component const wallComponent = new THING.WallComponent(); wall.addComponent(wallComponent, 'wallComponent'); wallComponent.load({ type: 'TextureWall', walls: [ { points: [...points[0], ...points[1]], leftMaterial: materialResource, rightMaterial: materialResource, edgeMaterial: materialResource }, { points: [...points[1], ...points[2]], leftMaterial: materialResource, rightMaterial: materialResource, edgeMaterial: materialResource }, { points: [...points[2], ...points[3]], leftMaterial: materialResource, rightMaterial: materialResource, edgeMaterial: materialResource }, { points: [...points[3], ...points[0]], leftMaterial: materialResource, rightMaterial: materialResource, edgeMaterial: materialResource } ], }).then(() => { console.log('Wall loaded'); }) ``` -------------------------------- ### On Enter Level Logic - JavaScript Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/level_controls_DefaultLevelControl Handles the logic executed when entering a new level. This method manages parameters, skipping logic based on `jumping` and `enableSkipLevel` flags, camera setup, effect application, dynamic loading, event registration, and camera transitions. ```javascript async onEnter(param) { super.onEnter(param); let _private = this[__.private]; _private.levelParam = param; let options = param.options; let isSkip = false; if (options.jumping && param.target !== param.current) { isSkip = true; } if (_private.enableSkipLevel) { _private._isSkipLevel = this.onSkipLevel(param); if (_private._isSkipLevel) { isSkip = true; } } // 跳过 只执行 on set effect if (isSkip) { this.onSetEffect(param); return; } // 相机优先 if (_private.isCameraFirst) { await this.onSetCamera(param); } await this.onSetEffect(param); if (this.app.root.dynamicLoad.enable) { await this.app.root.dynamicLoad.waitForComplete(); } // 如果动态加载结束后,当前层级已经退出,就不能再注册事件以及相机飞行 if (!this.isRunning) { return; } this.onRegisterEvent(param); // 相机不优先 if (!_private.isCameraFirst) { await this.onSetCamera(param); } } ``` -------------------------------- ### Thing.js WallComponent Class Definition Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/components_WallComponent Defines the WallComponent class, extending THING.Component, for creating and managing wall objects in a 3D scene. It includes methods for setting and getting wall data, handling different wall types (ModelWall, TextureWall), and parsing model wall data. ```javascript class WallComponent extends Component { constructor(param) { super(param); let _private = this[__.private] = {}; _private.data = null; _private.dataType = null; _private.pickIds = null; /** * Sets the wall data and options. * @param {Object} data - The wall data. * @param {Object} options - The options. */ _private.setData = (data, options) => { if (!data) { return; } _private.toolkit = options; _private.data = data; _private.dataType = data.type; _private.pickIds = data.pickIds; _private.walls = data.walls; _private.materialExtendOptions = { defineUsePickId: !!_private.pickIds }; if (data.type === WallType.ModelWall) { _private._parseModelWalls(data.walls); } } /** * Returns the wall data. * @returns {Object} The wall data. */ _private.getData = (options) => { let exportData = { type: _private.dataType }; if (_private.pickIds) { exportData.pickIds = _private.pickIds; } if (_private.walls) { // 浅拷贝wall,防止多次导出时 数据源被修改 const walls = []; _private.walls.forEach(wall => { walls.push(Object.assign({}, wall)); }); exportData.walls = walls; } return exportData; } /** * Loads the wall object. * @param {Object} wallObject - The wall object. * @returns {Promise} A promise that resolves when the loading is complete. ``` -------------------------------- ### Get Model Size using ResourceManager Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/components_WallComponent Asynchronously retrieves the dimensions (size) of a loaded model. It uses the ResourceManager to load the model, calculates its oriented bounding box (OBB), extracts the half-size, computes the full model size, and then disposes of the loaded node. Returns a Promise that resolves with the model dimensions. ```javascript _private._getModelSize = async (url, wallObject) => { return new Promise((resolve, reject) => { wallObject.app.resourceManager.loadModel(url, function (e) { const box = e.node.getOBB({ center: defCenter, halfSize: defHalfSize, rotation: defRotation }); const halfSize = box.halfSize; const modelSize = [halfSize[0] * 2, halfSize[1] * 2, halfSize[2] * 2]; e.node.dispose(); resolve(modelSize); }, function () { }, reject); }) } ``` -------------------------------- ### Get Room Ceiling - JavaScript Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/Room Retrieves the ceiling component of the room. This member returns a THING.Object3D representing the room's ceiling. It is a read-only property. ```javascript let ceiling = room.ceiling; console.log(ceiling); ``` -------------------------------- ### Get Room Slab (Floor) - JavaScript Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/Room Retrieves the floor component of the room. This member returns a THING.Object3D representing the room's floor slab. It is a read-only property. ```javascript let slab = room.slab; console.log(slab); ``` -------------------------------- ### Calculate Wall Lines using MathUtils Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/components_WallComponent Calculates line segments for walls based on start and end positions, accounting for hole percentages. It utilizes MathUtils.getPointOnLine to determine precise points on a line segment. Handles cases with and without pre-defined holes, and ensures the last line segment is added if the total length is less than 1. ```javascript let subLineStart, subLineEnd; if (!preHolePercent) { subLineStart = MathUtils.getPointOnLine(startPosition, endPosition, 0); subLineEnd = MathUtils.getPointOnLine(startPosition, endPosition, subLineEndPercent); } else { subLineStart = MathUtils.getPointOnLine(startPosition, endPosition, preHolePercent); subLineEnd = MathUtils.getPointOnLine(startPosition, endPosition, subLineEndPercent); } lines.push({ start: subLineStart, end: subLineEnd }); preHolePercent = subLineEndPercent + sizexPercent; // add last line if (preHolePercent < 1) { lines.push({ start: MathUtils.getPointOnLine(startPosition, endPosition, preHolePercent), end: MathUtils.getPointOnLine(startPosition, endPosition, 1) }); } else { // direct use root line lines.push({ start: startPosition, end: endPosition }); } return lines; ``` -------------------------------- ### Get Room Doors - JavaScript Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/objects_Room Retrieves a collection of door objects associated with the room. It ensures a SpaceComponent is initialized and then filters the parent's doors to find those within the room's line segments. Returns a THING.Selector. ```javascript get doors() { if (!this._internalSpace) { this._internalSpace = new SpaceComponent(); this.addComponent(this._internalSpace, '_internalSpace'); } const points = this.points; const doors = this.parent.doors; return this._internalSpace.filterObjectsInLineSegments(points, doors); } ``` -------------------------------- ### Get Room Area - JavaScript Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/objects_Room Retrieves the calculated area of the room. It caches the area after the first calculation for efficiency. Dependencies include Utils and MathUtils. ```javascript get area() { if (Utils.isNull(this._area)) { this._area = Math.abs(MathUtils.getArea(this._selfPoints)); } return this._area; } ``` -------------------------------- ### Get Room Perimeter - JavaScript Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/Room Retrieves the perimeter of the room. This member returns a Number representing the room's perimeter. It is a read-only property. ```javascript let perimeter = room.perimeter; console.log(perimeter); ``` -------------------------------- ### DefaultLevelControl Methods Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/DefaultLevelControl Documentation for the methods available in the DefaultLevelControl class, including handling object processing, level entry and exit, mouse interactions, and camera flight. ```APIDOC ## DefaultLevelControl Methods ### Description Methods that perform actions related to level control, object interaction, and event handling. ### Methods #### filterObject(object) - **Description**: Processes an object. - **Parameters**: - **object** (Object) - The object to process. - **Returns**: Object | null - The processed object for further handling, or null if no suitable object is found. #### onBackToParentLevel() - **Description**: Callback function for returning to the parent level. #### async onEnter(param) - **Description**: Called when entering a level. - **Parameters**: - **param** (Object) - Parameters for entering the level. - **Returns**: Promise #### onEnterObjectLevel(ev) - **Description**: Callback function for entering an object's level. - **Parameters**: - **ev** (THING.Object3D) - The object. #### onFlyTo(flyParam) - **Description**: Initiates a fly animation to the specified parameters. - **Parameters**: - **flyParam** (THING.LerpFlyToArgs) - An object containing parameters for the fly animation. - **Returns**: Promise #### async onLeave(param) - **Description**: Called when leaving a level. - **Parameters**: - **param** (Object) - Parameters for leaving the level. #### onMouseEnter(ev) - **Description**: Handles the mouse enter object event (defaults to setting the outline color). - **Parameters**: - **ev** (THING.EventCallback) - The mouse enter event. #### onMouseLeave(ev) - **Description**: Handles the mouse leave object event (defaults to clearing the outline color). - **Parameters**: - **ev** (THING.EventCallback) - The mouse leave event. #### onRegisterEvent(param) - **Description**: Called when an event is registered. - **Parameters**: - **param** (Object) - Parameters for entering the level. #### onResetEffect(param) - **Description**: Resets effects when leaving a level. - **Parameters**: - **param** (Object) - Parameters for leaving the level. #### onSetEffect(param) - **Description**: Applies effects when entering a level. - **Parameters**: - **param** (Object) - Parameters for entering the level. #### onSkipLevel(param) - **Description**: Checks if the given path involves skipping a level (by default, sibling nodes are skipped). - **Parameters**: - **param** (Object) - An object containing parameters for level changes. - **Returns**: boolean - Returns true to skip, false otherwise. #### onUnregisterEvent(param) - **Description**: Called when an event is unregistered. - **Parameters**: - **param** (Object) - Parameters for leaving the level. ``` -------------------------------- ### Instantiate and Load PlaneComponent in JavaScript Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/PlaneComponent This snippet demonstrates how to instantiate and load a PlaneComponent independently. It shows the creation of a THING.Object3D, adding a PlaneComponent to it, and then loading plane data including points, holes, and material resources. The load method returns a Promise, allowing for asynchronous handling of the loading process. ```javascript // 1. 单独使用(不作为房间的子) // 模拟数据 const points = [[0, 0], [2, 0], [2, 2], [0, 2]] const holes = [[[0.25, 0.25], [0.75, 0.25], [0.75, 0.75], [0.25, 0.75],]] const materialResource = { sideType: 'Double', map: './images/camera.png' } // 创建对象作为平面 const plane = new THING.Object3D(); // 实例化平面组件 const planeComponent = new THING.PlaneComponent(); plane.addComponent(planeComponent, 'planeComponent'); planeComponent.load({ points, holes, materialResource }).then(() => { console.log('平面加载完成'); }) ``` -------------------------------- ### Get Room Area - JavaScript Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/Room Retrieves the area of the room. This member returns a Number representing the room's area. It is a read-only property. ```javascript let area = room.area; console.log(area); ``` -------------------------------- ### JavaScript Door Class for 3D Environments Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/objects_Door Defines a 'Door' class for 3D environments, extending a base entity. It manages door state (open/closed), transformations, and animations. Dependencies include '@uino/thing' and a custom 'Utils' module. Handles initialization from parameters and provides methods for opening and closing the door. ```javascript import { BaseEntity, LoopType } from '@uino/thing'; import { Utils } from '../common/Utils'; /** * @class Door * 门 * @extends THING.BaseEntity * @public */ class Door extends BaseEntity { static defaultTagArray = ['Door']; constructor(param) { super(param); this._isOpen = Utils.parseBoolean(param['isOpen'], false); this._transformCorrection = Utils.parseBoolean(param['transformCorrection'], false); this._dirIdx = Utils.parseNumber(param['dirIdx'], 0); } onLoadComplete() { super.onLoadComplete(); if (!this._transformCorrection) { return; } const dirIdx = this.external.dirIdx || 0; const doorDirInfo = _getDoorOpenDirectionInfo(this); if (!doorDirInfo.isSingle && !doorDirInfo.hasAnimation && !doorDirInfo.hasController) { this.body.localAngles = [0, 180, 0]; } if (doorDirInfo.isSingle) { if (dirIdx == 1) { this.body.localScale = [-1, 1, 1]; } else if (dirIdx == 2) { this.body.localScale = [1, 1, -1]; } else if (dirIdx == 3) { this.body.localScale = [-1, 1, -1]; } } else { if (dirIdx == 1) { this.body.localScale = [-1, 1, -1]; } } if (this._isOpen) { openDoor(this, true); } } /** * 获取门是否打开 * @type {Boolean} * @public */ get isOpen() { return this._isOpen; } /** * 开门 * @public */ open() { if (this._isOpen) { return; } openDoor(this, true); this._isOpen = true; } /** * 关门 * @public */ close() { if (!this._isOpen) { return; } openDoor(this, false); this._isOpen = false; } } export { Door }; function openDoor(door, isOpen = true) { let animationName = isOpen ? 'Auto_Open' : 'Auto_Close'; const names = door.animationNames; if (names.indexOf(animationName) != -1) { door.playAnimation(animationName); return; } if (isOpen) { if (names.indexOf('_defaultAnim_') != -1) { door.playAnimation({ name: "_defaultAnim_", loopType: LoopType.Repeat }); } } else { door.stopAnimation("_defaultAnim_") } } function _getDoorOpenDirectionInfo(door) { let isSingle = false; let hasAnimation = false; let hasController = false; if (door.animations.length) { hasAnimation = true; } let count = 0; door.body.traverseNodes((e) => { if (e.name == 'LeftPiovt' || e.name == 'RightPiovt') { ++count; } else if (e.name == 'Controller') { hasController = true; } }); if (count == 1) { isSingle = true; } return { isSingle, hasAnimation, hasController }; } ``` -------------------------------- ### Get Room Roof - JavaScript Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/Room Retrieves the roof component of the room. This member returns a THING.Object3D representing the room's roof. It is a read-only property. ```javascript let roof = room.roof; console.log(roof); ``` -------------------------------- ### Get Room Doors - JavaScript Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/Room Retrieves a collection of door objects within the room. This member returns a THING.Selector of THING.Door objects. It is a read-only property. ```javascript let doors = room.doors; console.log(doors); ``` -------------------------------- ### Thing.js PlaneComponent: Room Floor Creation Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/components_PlaneComponent Illustrates creating a room floor using the PlaneComponent. A THING.Room is created, and then a THING.Object3D is designated as the room floor, to which the PlaneComponent is added and loaded with specific material resources. ```javascript const points = [[0, 0], [2, 0], [2, 2], [0, 2]]; const holes = [[[0.25, 0.25], [0.75, 0.25], [0.75, 0.75], [0.25, 0.75]]]; const room = new THING.Room({ position: [10, 0, 10], points, holes }); const roomFloor = new THING.Object3D({ parent: room, tags: ['BuildingElement', 'RoomFloor'] }); const roomFloorComponent = new THING.PlaneComponent(); roomFloor.addComponent(roomFloorComponent, 'planeComponent'); const roomFloorMaterialResource = { sideType: 'Double', map: './images/camera.png' }; roomFloorComponent.load({ materialResource: roomFloorMaterialResource }).then(() => { console.log('房间地面加载完成'); }); ``` -------------------------------- ### Thing.js PlaneComponent: Room Roof Creation Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/components_PlaneComponent Details the creation of a room roof using the PlaneComponent. It involves setting up a THING.Room and a THING.Object3D for the roof, then applying the PlaneComponent with designated material resources. ```javascript const points = [[0, 0], [2, 0], [2, 2], [0, 2]]; const holes = [[[0.25, 0.25], [0.75, 0.25], [0.75, 0.75], [0.25, 0.75]]]; const room = new THING.Room({ position: [10, 0, 10], points, holes }); const roomRoof = new THING.Object3D({ parent: room, localPosition: [0, 3, 0], tags: ['BuildingElement', 'RoomRoof'] }); const roomRoofComponent = new THING.PlaneComponent(); roomRoof.addComponent(roomRoofComponent, 'planeComponent'); const roomRoofMaterialResource = { sideType: 'Front', map: './images/camera.png' }; roomRoofComponent.load({ materialResource: roomRoofMaterialResource }).then(() => { console.log('房间房顶加载完成'); }); ``` -------------------------------- ### Thing.js PlaneComponent: Room Ceiling Creation Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/components_PlaneComponent Shows how to create a room ceiling using the PlaneComponent. Similar to the floor, a THING.Room is established, and a THING.Object3D is configured as the ceiling, incorporating the PlaneComponent with its material resources. ```javascript const points = [[0, 0], [2, 0], [2, 2], [0, 2]]; const holes = [[[0.25, 0.25], [0.75, 0.25], [0.75, 0.75], [0.25, 0.75]]]; const room = new THING.Room({ position: [10, 0, 10], points, holes }); const roomCeiling = new THING.Object3D({ parent: room, localPosition: [0, 2.9, 0], tags: ['BuildingElement', 'RoomCeiling'] }); const roomCeilingComponent = new THING.PlaneComponent(); roomCeiling.addComponent(roomCeilingComponent, 'planeComponent'); const roomCeilingMaterialResource = { sideType: 'Back', map: './images/camera.png' }; roomCeilingComponent.load({ materialResource: roomCeilingMaterialResource }).then(() => { console.log('房间天花板加载完成'); }); ``` -------------------------------- ### Access Floor Level Number in JavaScript Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/Floor Retrieves the numerical identifier for the floor, starting from 1. This is useful for ordering or referencing specific floors in a multi-level structure. ```javascript let levelNumber = floor.levelNumber; console.log(levelNumber); ``` -------------------------------- ### Get Room Misc Objects - JavaScript Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/Room Retrieves other miscellaneous objects within the room. This member returns a THING.Object3D containing additional room elements. It is a read-only property. ```javascript let misc = room.misc; console.log(misc); ``` -------------------------------- ### Performing Fly-to Action with Bounding Box Calculation in BuildingLevelControl Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/level_controls_BuildingLevelControl The onFlyTo method handles camera movements to a target object. If the target has floors, it identifies walls within those floors and calculates a bounding box. The camera then flies to a position derived from this bounding box's center, ensuring a good view of the relevant building section. If no walls are found, it performs a default fly-to action. ```javascript onFlyTo(flyParam) { const target = flyParam.target; if (target && target.isObject3D) { const floors = target.children.queryByTags('Floor'); const walls = new Selector(); floors.forEach(floor => { floor.children.forEach(child => { if (child.tags && child.tags.has('Wall')) { walls.push(child); } }) }); if (walls.length === 0) { flyParam.target = target; return super.onFlyTo(flyParam); } const boundingBox = walls.getBoundingBox(); flyParam.position = LevelControlHelper.getNearestObjectPosition({ target: target, boundingBox: boundingBox, camera: this.app.camera, }); flyParam.target = boundingBox.center; } return super.onFlyTo(flyParam); } ``` -------------------------------- ### WallComponent API Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/components_WallComponent Provides methods to load, configure, and retrieve data for wall components in a ThingJS scene. ```APIDOC ## WallComponent Class ### Description Represents a component for creating and managing wall geometry and appearance in a 3D scene. ### Constructor Initializes a new instance of the WallComponent. ### Methods #### `load(data)` ##### Description Loads wall data and configurations into the component. This method can handle both `TextureWall` and `ModelWall` types. ##### Parameters - **data** (Object) - Required - An object containing the wall data. It should include: - **type** (string) - Required - The type of wall, either 'ModelWall' or 'TextureWall'. - **walls** (Array) - Required for TextureWall - An array of objects, where each object defines a segment of the wall with `points`, `leftMaterial`, `rightMaterial`, and `edgeMaterial` properties. - **pickIds** (Array) - Optional - Identifiers for picking wall segments. ##### Request Example ```json { "type": "TextureWall", "walls": [ { "points": [0, 0, 0, 2, 0, 0], "leftMaterial": { "map": "./images/texture.png" }, "rightMaterial": { "map": "./images/texture.png" }, "edgeMaterial": { "map": "./images/edge.png" } } ], "pickIds": ["wall1", "wall2"] } ``` ##### Response Example (This method returns a Promise that resolves upon completion) ```json { "message": "Wall loaded successfully" } ``` #### `getData(options)` ##### Description Exports the current wall data from the component. ##### Parameters - **options** (Object) - Optional - An object for potential future options, currently not used. ##### Response #### Success Response (200) - **type** (string) - The type of the wall ('ModelWall' or 'TextureWall'). - **pickIds** (Array) - Optional - The picking identifiers for the wall segments. - **walls** (Array) - Optional - An array representing the wall segments, each with its properties. ##### Response Example ```json { "type": "TextureWall", "walls": [ { "points": [0, 0, 0, 2, 0, 0], "leftMaterial": { "map": "./images/texture.png" }, "rightMaterial": { "map": "./images/texture.png" }, "edgeMaterial": { "map": "./images/edge.png" } } ] } ``` ``` -------------------------------- ### Get Always Hide Property - JavaScript Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/components_PlaneComponent A getter method that returns the boolean value of the `alwaysHide` property from the component's private store. This property likely controls whether the plane should be visible or loaded. ```javascript get alwaysHide() { let _private = this[__.private]; return _private.alwaysHide; } ``` -------------------------------- ### DefaultLevelControl Constructor Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/DefaultLevelControl Initializes a new instance of the DefaultLevelControl class with specified options. This class extends THING.BaseLevelControl and is responsible for handling default level control behaviors. ```APIDOC ## new DefaultLevelControl(options) ### Description Constructor for the DefaultLevelControl class. ### Method Constructor ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **options** (Object) - Required - Options for the level control. ### Request Example ```json { "options": { "someOption": "value" } } ``` ### Response #### Success Response (200) This constructor does not return a value directly, but initializes the object. #### Response Example None ``` -------------------------------- ### Manage Level Change Event Types (JavaScript) Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/level_controls_DefaultLevelControl Allows setting and getting the event types for entering and leaving levels. It specifically supports 'THING.EventType.Click' or 'THING.EventType.DBLClick' for leaving events. This functionality is crucial for handling user interactions related to level navigation. ```javascript get leaveLevelEventType() { let _private = this[__.private]; return _private.leaveLevelEventType; } set leaveLevelEventType(value) { let _private = this[__.private]; _private.setLevelChangeEventType('leaveLevelEventType', value) } ``` -------------------------------- ### Use PlaneComponent with Room Elements in JavaScript Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/PlaneComponent This snippet illustrates how to integrate PlaneComponent with THING.Room objects to define floor, ceiling, and roof elements. It shows the creation of a THING.Room with specified points and holes, followed by the instantiation of PlaneComponents for each room surface (floor, ceiling, roof) with distinct material resources. Each component's load method is called to apply the materials. ```javascript // 2. 配合房间一起使用 const roomFloorMaterialResource = { sideType: 'Double', map: './images/camera.png' } const roomCeilingMaterialResource = { sideType: 'Back', map: './images/camera.png' } const roomRoofMaterialResource = { sideType: 'Front', map: './images/camera.png' } // 创建房间 const room = new THING.Room({ position: [10, 0, 10], points, holes }); // 创建对象作为房间地面 const roomFloor = new THING.Object3D({ parent: room, tags: ['BuildingElement', 'RoomFloor'] }); // 实例化平面组件 const roomFloorComponent = new THING.PlaneComponent(); roomFloor.addComponent(roomFloorComponent, 'planeComponent'); roomFloorComponent.load({ materialResource: roomFloorMaterialResource }).then(() => { console.log('房间地面加载完成'); }) // 创建对象作为房间天花板 const roomCeiling = new THING.Object3D({ parent: room, localPosition: [0, 2.9, 0], tags: ['BuildingElement', 'RoomCeiling'] }); // 实例化平面组件 const roomCeilingComponent = new THING.PlaneComponent(); roomCeiling.addComponent(roomCeilingComponent, 'planeComponent'); roomCeilingComponent.load({ materialResource: roomCeilingMaterialResource }).then(() => { console.log('房间天花板加载完成'); }) // 创建对象作为房间天花板 const roomRoof = new THING.Object3D({ parent: room, localPosition: [0, 3, 0], tags: ['BuildingElement', 'RoomRoof'] }); // 实例化平面组件 const roomRoofComponent = new THING.PlaneComponent(); roomRoof.addComponent(roomRoofComponent, 'planeComponent'); roomRoofComponent.load({ materialResource: roomRoofMaterialResource }).then(() => { console.log('房间房顶加载完成'); }) ``` -------------------------------- ### JavaScript: Initialize and Manage Level Controls Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/level_LevelControls This JavaScript code defines the LevelControls class, responsible for initializing and managing hierarchical controls within a Thing.js application. It handles control registration, dynamic property creation for access, and setting control options across different levels. Dependencies include the THING.App instance and its level control manager. ```javascript const DefaultTag = 'default'; const defaultPriority = 0; const __ = { private: Symbol('private') } const controlClassMap = new Map(); class LevelControls { static setLevelControlClass(levelName, levelCondition, controlClass) { controlClassMap.set(levelName, { condition: levelCondition, cls: controlClass }); }; constructor(app) { this.app = app; let _private = this[__.private] = {}; _private.controlsMap = new Map(); _private.addControlProperty = (name, condition, control) => { let contorlOption = { control, condition, tag: DefaultTag }; _private.controlsMap.set(name, contorlOption); Object.defineProperty(this, name, { get: () => { const controlParam = _private.controlsMap.get(name); if (controlParam) { return controlParam.control; } else { return null; } }, set: (control) => { const controlParam = _private.controlsMap.get(name); if (controlParam) { this.addControl(controlParam.condition, name, control); } }, configurable: true }); }; // Initialize the level control controlClassMap.forEach((val, key) => { app.level.levelControlManager.registerClass(val.cls, { condition: val.condition, name: key, tag: DefaultTag }); }); app.level.levelControlManager.enableControls(DefaultTag); // 兼容campus原来的接口 const controls = app.level.levelControlManager.getControlsByTag(DefaultTag); for (let i = 0; i < controls.length; i++) { const control = controls[i]; const options = control.options; _private.addControlProperty(options.name, options.condition, control); } } /** * 批量设置所有已注册控件的选项 * @param {string} option - 要设置的选项名 * @param {*} value - 要设置的值 * @public * * 遍历 private.controlsMap,将每个控件的对应 option 设置为 value。 */ setControlOption(option, value) { let _private = this[__.private]; _private.controlsMap.forEach((controlParam) => { controlParam.control[option] = value; }) } /** * 添加(注册)控件实例到 level 管理器,并在当前实例上建立访问属性 * @param {String} condition - 控件的启用条件 * @param {string} name - 控件名称(用于在 this 上创建属性) * @param {DefaultLevelControl} control - 控件实例(需满足 isDefaultLevelControl) * @param {Object} [options] - 注册时的额外选项(会与默认 tag 和优先级合并) * @public * * 行为: * - 若 control 不合法则忽略 * - 先注销同名控件(若存在) * - 调用 app.level.register 注册控件 * - 在私有表中添加属性并在 this 上定义可访问属性 */ addControl(condition, name, control, options) { if (!control || !control.isDefaultLevelControl) { return; } // unregister this.removeControl(name); // register this.app.level.register(condition, control, { tag: DefaultTag, priority: defaultPriority, ...options }); this[__.private].addControlProperty(name, condition, control); } /** * 移除(注销)指定名称的控件 * @param {string} name - 要移除的控件名 * @public * */ removeControl(name) { // Implementation for removing control would go here. } } ``` -------------------------------- ### ThingJS Campus Class Definition and Initialization Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/objects_Campus Defines the Campus class extending ThingJS's Object3D. It includes a constructor for initializing private properties and setting up the component. The class is designed to manage a virtual campus environment. ```javascript import { Object3D, Selector } from '@uino/thing'; const __ = { private: Symbol('private') } /** * @class Campus * 园区 * @extends THING.Object3D * @public */ class Campus extends Object3D { static defaultTagArray = ['Campus']; constructor(params) { super(params); let _private = this[__.private] = {}; _private.autoEnvMap = null; } onLoadRenderableResource(options, resolve, reject) { if (this.destroyed) { reject(`The object had been destroyed, skip to load resources`); return } // Load resouce as entity const nodeName = options['nodeName']; if (nodeName) { super.onLoadRenderableResource(options, resolve, reject); return } // Load resource as campus let loadOptions = Object.assign({}, options); loadOptions['onComplete'] = loadOptions['complete'] = resolve; loadOptions['onError'] = loadOptions['error'] = reject; loadOptions['owner'] = this; delete loadOptions.url; this.app.load(this.resource.url, loadOptions); } onBeforeDestroy() { this.setAutoEnvMap(null); return super.onBeforeDestroy(); } setAutoEnvMap(envMap) { let _private = this[__.private]; if (_private.autoEnvMap) { if (_private.autoEnvMap.outer) { _private.autoEnvMap.outer.dispose(); } if (_private.autoEnvMap.inner) { _private.autoEnvMap.inner.dispose(); } } _private.autoEnvMap = envMap; } getAutoEnvMap() { let _private = this[__.private]; return _private.autoEnvMap; } /** * 获取园区下的放置物对象集合 * @type {THING.Selector} * @example * let placements = campus.placements; * @public */ get placements() { let placements = new Selector(); this.children.forEach(child => { let tags = child.tags; if (tags.has('Placement')) { placements.push(child); } else if (tags.has('Group')) { placements.push(child.queryByTags('Placement')); } }); return placements; } /** * 获取园区下的建筑物对象集合 * @type {THING.Selector} * @example * let buildings = campus.buildings; * @public */ get buildings() { return this.children.query('tags:or(Building)'); } /** * 获取园区下的地面对象集合 * @type {THING.Object3D} * @example * let ground = campus.ground; * @public */ get ground() { const result = this.children.find('tags:or(Ground)'); return result; } /** * 获取杂项对象 * @type {THING.Object3D} * @example * let misc = campus.misc; * console.log(misc); * @public */ get misc() { return this.children.find('tags:or(Misc)'); } } export { Campus } ``` -------------------------------- ### RoomLevelControl Class Definition and Methods (JavaScript) Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/level_controls_RoomLevelControl Defines the RoomLevelControl class, responsible for managing room-level hierarchy in a campus space. It includes methods for setting and resetting effects on objects, filtering objects, and handling fly-to camera actions. Dependencies include DefaultLevelControl and LevelControlHelper. ```javascript import { DefaultLevelControl } from "./DefaultLevelControl"; import { LevelControlHelper } from "../LevelControlHelper"; const __ = { private: Symbol('private') } /** * @class RoomLevelControl * 园区的房间层级控制类。 * @extends THING.DefaultLevelControl * @public */ class RoomLevelControl extends DefaultLevelControl { static levelCondition = 'tags:or(Room)'; static levelName = 'room'; constructor(options) { super(options); let _private = this[__.private] = {}; _private.transparentObjects = []; _private.isObjectTransparent = false; } onSetEffect(param) { let _private = this[__.private]; const object = param.current; if (object) { const brothers = object.brothers; LevelControlHelper.traverseByIgnore(object, 'ignoreStyle', (child) => { const style = child.body.style; if (style) { style.opacity = null; style.transparent = null; } }); brothers.forEach(element => { const roomFloor = element.children.queryByTags(_private.isObjectTransparent ? 'RoomFloor||Placement||Entity||Line||Geometry||Region||Window||Door' : 'RoomFloor'); if (roomFloor) { LevelControlHelper.traverseByIgnore(roomFloor, 'ignoreStyle', (child) => { const style = child.body.style; if (style) { style.opacity = 0.25; style.transparent = true; } _private.transparentObjects.push(child); }); } });; } } onResetEffect(param) { let _private = this[__.private]; // 如果开启了隐藏对象,并且接下来要进入的是子层级,就不用恢复半透明了 if (_private.isObjectTransparent) { if (param.next.parent === param.current) { return; } } _private.transparentObjects.forEach(element => { const style = element.style; if (style) { style.opacity = null; style.transparent = null; } }); _private.transparentObjects.length = 0; } filterObject(object) { const tags = object.tags; if (object.tags.has('Wall')) { return null; } if (tags.has('RoomFloor') || tags.has('RoomCeiling') || tags.has('RoomRoof')) { if (object.parent == object.app.level.current) { return null; } } if (object.parents.find('tags:or(Misc,Wall)')) { return null; } return super.filterObject(object); } onFlyTo(flyParam) { const target = flyParam.target; if (target && target.isObject3D) { const boundingBox = target.boundingBox; flyParam.position = LevelControlHelper.getNearestObjectPosition({ target: target, boundingBox: boundingBox, camera: this.app.camera, }); flyParam.target = boundingBox.center; } return super.onFlyTo(flyParam); } /** * 开启/关闭 物体半透明。(默认关闭,开启后进入房间时会半透明其他房间下的物体。并且在继续进入子层级时不会主动恢复其他房间的半透明,只有返回父层级才会恢复其他房间的半透明。) * @type {boolean} * @public */ get isObjectTransparent() { const _private = this[__.private]; return _private.isObjectTransparent; } set isObjectTransparent(value) { ``` -------------------------------- ### Thing.js PlaneComponent: Constructor and Private Data Handling Source: https://cdn.uino.cn/thingjs/thing-campus-space/docs/components_PlaneComponent Shows the constructor for PlaneComponent and how it initializes private properties like 'dynamic', 'points', 'holes', and 'alwaysHide'. It also demonstrates the use of a Symbol for private members and utility functions for parsing boolean values. ```javascript class PlaneComponent extends Component { constructor(param = emptyParam) { super(param); let _private = this[__.private] = { dynamic: param.dynamic, points: null, holes: null, alwaysHide: false }; _defaultQuat[1] = getTransformOffset(); _private.setData = (data) => { _private.materialResourceData = data['materialResource']; _private.alwaysHide = Utils.parseBoolean(data.alwaysHide, false); _private.uv = data.uv; _private.selfPoints = data.points; _private.selfHoles = data.holes; if (!_private.selfPoints) { _private.selfPoints = this.object.parent._selfPoints; } if (!_private.selfHoles) { _private.selfHoles = this.object.parent._selfHoles; } }; } } ```