Appearance
Placing objects in AR
The place-object
components provide a complete system for placing virtual objects in AR environments. The components work together to create an intuitive and consistent object placement experience with advanced features like preview, surface detection, and object management.
Component Structure
The system consists of three main parts:
- place-object - Component applied to individual objects that users can place
- place-object-manager - Scene-level component that manages all placed objects
- ar-placement-utils - Core utility library that handles surface detection, validation, and placement logic
This modular design provides a consistent placement experience while allowing flexibility in how the system is used.
Basic Example
Here's a simple example of the complete AR placement system:
html
<a-scene webxr="optionalFeatures: hit-test">
<!-- Place object manager to handle hit testing and object tracking -->
<a-entity place-object-manager="maxObjects: 10; showPreview: true"></a-entity>
<!-- Placeable object template -->
<a-entity
id="chair-template"
gltf-model="#chair-model"
place-object="
surfaceTypes: horizontal;
scale: 0.5;
faceCamera: true"
visible="false">
</a-entity>
</a-scene>
End-to-End Placement Flow
Setup:
place-object-manager
initializes AR hit testingplace-object
components are applied to template objects (usually hidden)
Detection:
- User points device at real-world surfaces
- WebXR hit test API detects surfaces
place-object-manager
shows hit test marker at detected points
Preview:
- Manager creates semi-transparent copy of template object
- Preview follows hit test position
ARPlacementUtils
positions preview correctly based on surface type
Placement:
- User taps to place (triggers WebXR "select" event)
place-object
validates surface and creates a copy of the templateARPlacementUtils
handles proper positioning and orientationplace-object-manager
adds object to its tracking list
Management:
place-object-manager
provides methods to remove objects- Enforces maximum object limit
- Fires events when objects are placed or removed
Supported Surface Types
The system can detect and place objects on three types of surfaces:
- Horizontal (floors, tables): Detected when surface normal points upward
- Wall (vertical surfaces): Detected when surface normal is near-horizontal
- Ceiling (overhead surfaces): Detected when surface normal points downward
Special Placement Modes
Regular Object Placement
Standard 3D models are positioned appropriately for each surface:
- On floors: Upright, optionally facing the camera
- On walls: "Standing" on the wall, facing outward
- On ceilings: Attached upside-down
Advanced Features
Custom Rotation
After basic placement, you can apply custom rotation in degrees:
html
<a-entity
place-object="customRotation: 0 45 0"
visible="false">
</a-entity>
Multi-Surface Support
Allow placement on multiple surface types:
html
<a-entity
place-object="surfaceTypes: horizontal, wall"
visible="false">
</a-entity>
Object Management
Access and manage placed objects programmatically:
javascript
const manager = document.querySelector('[place-object-manager]').components['place-object-manager'];
// Clear all objects
manager.removeAllObjects();
// Remove most recent object
manager.removeLastObject();
// Check how many objects have been placed
console.log(manager.placedObjects.length);
Technical Implementation
The system uses a shared utility (ARPlacementUtils
) to ensure consistent placement behavior across components. This approach:
- Maintains consistent positioning logic
- Centralizes complex calculations
- Makes the system easier to extend
- Ensures the preview matches the final placement
Usage Tips
- Template Setup: Keep template objects hidden (
visible="false"
) - Scene Configuration: Ensure WebXR is configured with
hit-test
feature - Surface Filtering: Use
surfaceTypes
to restrict where objects can be placed - Preview: Enable
showPreview
for better user experience - Object Limits: Set appropriate
maxObjects
to manage scene complexity - Event Handling: Listen for
object-placed
andobject-managed
events
For more detailed information on each component, see their individual documentation pages.