Skip to content

Instantly share code, notes, and snippets.

@positlabs
Last active April 14, 2023 15:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save positlabs/6bd8e32e698bb7d21f1670ac0628a051 to your computer and use it in GitHub Desktop.
Save positlabs/6bd8e32e698bb7d21f1670ac0628a051 to your computer and use it in GitHub Desktop.
Object placement for Lens Studio
/*
REQUIRED: Create a ground plane with a collider
so we can hit test against it to place the object on the surface.
*/
/* API */
script.api.enablePlacement = function (bool) { placementEnabled = bool }
script.api.setScreenPoint = function (pt) { screenPoint = pt }
//@input SceneObject targetObject
/** @type {SceneObject} */
var targetObject = script.targetObject || script.getSceneObject()
//@input Component.DeviceTracking deviceTracking
/** @type {DeviceTracking} */
var deviceTracking = script.deviceTracking
//@input vec2 screenPoint = {0.5, 0.5} "Screen Point"
/** @type {vec2} */
var screenPoint = script.screenPoint
//@input bool lookAtCamera = true "Rotate to face camera"
/** @type {boolean} */
var lookAtCamera = script.lookAtCamera
//@input bool autoStart = true "Auto start"
/** @type {boolean} */
var autoStart = script.autoStart
//@input bool repositionWithTap = true "Reposition with tap"
/** @type {boolean} */
var repositionWithTap = script.repositionWithTap
//@input float lerpSpeed = 0.8 "Lerp Speed"
/** @type {number} */
var lerpSpeed = script.lerpSpeed
//@input bool debug = true "Debug"
/** @type {boolean} */
var debug = script.debug
//@input Physics.ColliderComponent groundCollider
/** @type {ColliderComponent} */
var groundCollider = script.groundCollider
var transform = targetObject.getTransform()
var camera = deviceTracking.getSceneObject().getComponent("Component.Camera")
var cameraTransform = camera.getTransform()
var placementEnabled = autoStart
var probe = Physics.createGlobalProbe()
probe.debugDrawEnabled = debug
probe.filter.onlyColliders = [groundCollider]
script.createEvent('UpdateEvent').bind(function () {
if (!placementEnabled) return
placeObjectOnSurface()
if (lookAtCamera) rotateTowardCamera()
})
var touchStart = script.createEvent("TouchStartEvent")
touchStart.bind(function (eventData) {
print(eventData.getTouchPosition())
screenPoint = eventData.getTouchPosition()
})
function rotateTowardCamera() {
// look at the camera
var forward = cameraTransform.getWorldPosition().sub(transform.getWorldPosition()).normalize()
forward.y = 0 // Remove Y-axis component to lock rotation to the Y-axis
var newRotation = quat.lookAt(forward, vec3.up())
transform.setWorldRotation(quat.slerp(newRotation, transform.getWorldRotation(), lerpSpeed))
}
function placeObjectOnSurface() {
// Use raycast to find the surface
const rayTarget = camera.screenSpaceToWorldSpace(screenPoint, 10000)
var camPos = cameraTransform.getWorldPosition()
probe.rayCast(camPos, rayTarget, function (hit) {
if (!hit) return
print(hit)
// place the object on the surface
var currentPosition = transform.getWorldPosition()
transform.setWorldPosition(vec3.lerp(hit.position, currentPosition, lerpSpeed))
})
// NOTE only works for world tracking
// do a hit test on the world mesh
// var surfacePosition = deviceTracking.hitTestWorldMesh(screenPoint)
// if (surfacePosition && surfacePosition[0]) {
// // place the object on the surface
// transform.setLocalPosition(vec3.lerp(surfacePosition[0].position, transform.getLocalPosition(), .8))
// if (lookAtCamera) {
// // look at the camera
// var newRotation = quat.lookAt(cameraTransform.getWorldPosition().sub(transform.getWorldPosition()), vec3.up())
// newRotation = new quat.fromEulerAngles(0, newRotation.toEulerAngles().y, 0) // NOTE locking the x and z rotation
// transform.setWorldRotation(quat.slerp(newRotation, transform.getWorldRotation(), .8))
// }
// }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment