Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebXR Input Sources #1873

Merged
merged 23 commits into from
Feb 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build/dependencies.txt
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@
../src/vr/vr-manager.js
../src/vr/vr-display.js
../src/xr/xr-manager.js
../src/xr/xr-input.js
../src/xr/xr-input-source.js
../src/net/http.js
../src/script/script-registry.js
../src/script/script.js
Expand Down
5 changes: 4 additions & 1 deletion examples/examples.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ var categories = [
name: "xr",
examples: [
'augmented-reality-basic',
'virtual-reality-basic'
'virtual-reality-basic',
'xr-picking',
'vr-controllers',
'vr-movement'
]
}
];
14 changes: 7 additions & 7 deletions examples/xr/augmented-reality-basic.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<title>PlayCanvas Virtual Reality</title>
<title>PlayCanvas Augmented Reality</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link rel="icon" type="image/png" href="../playcanvas-favicon.png" />
Expand Down Expand Up @@ -117,11 +117,11 @@
if (app.xr.supported) {
var activate = function () {
if (app.xr.isAvailable(pc.XRTYPE_AR)) {
c.camera.startXr(pc.XRTYPE_AR, function (err) {
c.camera.startXr(pc.XRTYPE_AR, pc.XRSPACE_VIEWER, function (err) {
if (err) message("WebXR Immersive AR failed to start: " + err.message);
});
} else {
message("WebXR Immersive AR is not available");
message("Immersive AR is not available");
}
};

Expand Down Expand Up @@ -150,17 +150,17 @@
});

app.xr.on('start', function () {
message("WebXR Immersive AR session has started");
message("Immersive AR session has started");
});
app.xr.on('end', function () {
message("WebXR Immersive AR session has ended");
message("Immersive AR session has ended");
});
app.xr.on('available:' + pc.XRTYPE_AR, function (available) {
message("WebXR Immersive AR is now " + (available ? 'available' : 'unavailable'));
message("Immersive AR is " + (available ? 'available' : 'unavailable'));
});

if (! app.xr.isAvailable(pc.XRTYPE_AR)) {
message("WebXR Immersive AR is not available");
message("Immersive AR is not available");
}
} else {
message("WebXR is not supported");
Expand Down
17 changes: 10 additions & 7 deletions examples/xr/virtual-reality-basic.html
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,11 @@
if (app.xr.supported) {
var activate = function () {
if (app.xr.isAvailable(pc.XRTYPE_VR)) {
c.camera.startXr(pc.XRTYPE_VR, function (err) {
c.camera.startXr(pc.XRTYPE_VR, pc.XRSPACE_LOCAL, function (err) {
if (err) message("WebXR Immersive VR failed to start: " + err.message);
});
} else {
message("WebXR Immersive VR is not available");
message("Immersive VR is not available");
}
};

Expand All @@ -131,14 +131,17 @@
});

if (app.touch) {
app.touch.on("touchend", function () {
app.touch.on("touchend", function (evt) {
if (! app.xr.active) {
// if not in VR, activate
activate();
} else {
// otherwise reset camera
c.camera.endXr();
}

evt.preventDefault();
evt.stopPropagation();
});
}

Expand All @@ -150,17 +153,17 @@
});

app.xr.on('start', function () {
message("WebXR Immersive VR session has started");
message("Immersive VR session has started");
});
app.xr.on('end', function () {
message("WebXR Immersive VR session has ended");
message("Immersive VR session has ended");
});
app.xr.on('available:' + pc.XRTYPE_VR, function (available) {
message("WebXR Immersive VR is now " + (available ? 'available' : 'unavailable'));
message("Immersive VR is " + (available ? 'available' : 'unavailable'));
});

if (! app.xr.isAvailable(pc.XRTYPE_VR)) {
message("WebXR Immersive VR is not available");
message("Immersive VR is not available");
}
} else {
message("WebXR is not supported");
Expand Down
200 changes: 200 additions & 0 deletions examples/xr/vr-controllers.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
<!DOCTYPE html>
<html>
<head>
<title>PlayCanvas VR Controllers</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link rel="icon" type="image/png" href="../playcanvas-favicon.png" />
<script src="../../build/output/playcanvas.js"></script>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
}
canvas {
width:100%;
height:100%;

}
.message {
position: absolute;
padding: 8px 16px;
left: 20px;
bottom: 0px;
color: #ccc;
background-color: rgba(0, 0, 0, .5);
font-family: "Proxima Nova", Arial, sans-serif;
}
</style>
</head>

<body>
<canvas id="application-canvas"></canvas>
<div>
<p class="message"></p>
</div>
<script>
// draw some axes
var drawAxes = function (pos, scale) {
var color = new pc.Color(1,0,0);

var axis = new pc.Vec3();
var end = new pc.Vec3().copy(pos).add(axis.set(scale,0,0));

app.renderLine(pos, end, color);

color.set(0, 1, 0);
end.sub(axis.set(scale,0,0)).add(axis.set(0,scale,0));
app.renderLine(pos, end, color);

color.set(0, 0, 1);
end.sub(axis.set(0,scale,0)).add(axis.set(0,0,scale));
app.renderLine(pos, end, color);
}
</script>


<script>
var message = function (msg) {
var el = document.querySelector('.message');
el.textContent = msg;
}

var canvas = document.getElementById('application-canvas');
var app = new pc.Application(canvas, {
mouse: new pc.Mouse(canvas),
touch: new pc.TouchDevice(canvas),
keyboard: new pc.Keyboard(window)
});
app.setCanvasFillMode(pc.FILLMODE_FILL_WINDOW);
app.setCanvasResolution(pc.RESOLUTION_AUTO);

window.addEventListener("resize", function () {
app.resizeCanvas(canvas.width, canvas.height);
});

// use device pixel ratio
app.graphicsDevice.maxPixelRatio = window.devicePixelRatio;

app.start();

// create camera
var c = new pc.Entity();
c.addComponent('camera', {
clearColor: new pc.Color(44/255, 62/255, 80/255),
farClip: 10000
});
app.root.addChild(c);

var l = new pc.Entity();
l.addComponent("light", {
type: "spot",
range: 30
});
l.translate(0,10,0);
app.root.addChild(l);

var createCube = function(x,y,z) {
var cube = new pc.Entity();
cube.addComponent("model", {
type: "box",
material: new pc.StandardMaterial()
});
cube.setLocalScale(1,1,1);
cube.translate(x, y, z);
app.root.addChild(cube);
};

var controllers = [ ];
// create controller box
var createController = function(inputSource) {
var entity = new pc.Entity();
entity.addComponent('model', {
type: 'box'
});
entity.setLocalScale(0.05, 0.05, 0.05);
app.root.addChild(entity);
entity.inputSource = inputSource;
controllers.push(entity);

// destroy input source related entity
// when input source is removed
inputSource.on('remove', function() {
controllers.splice(controllers.indexOf(entity), 1);
entity.destroy();
});
};

// create a grid of cubes
var SIZE = 4;
for (var x = 0; x <= SIZE; x++) {
for (var y = 0; y <= SIZE; y++) {
createCube(2*x - SIZE, -1.5, 2*y - SIZE);
}
}

if (app.xr.supported) {
var activate = function () {
if (app.xr.isAvailable(pc.XRTYPE_VR)) {
c.camera.startXr(pc.XRTYPE_VR, pc.XRSPACE_LOCAL, function (err) {
if (err) message("Immersive VR failed to start: " + err.message);
});
} else {
message("Immersive VR is not available");
}
};

app.mouse.on("mousedown", function () {
if (! app.xr.active)
activate();
});

if (app.touch) {
app.touch.on("touchend", function () {
if (! app.xr.active) {
// if not in VR, activate
activate();
} else {
// otherwise reset camera
c.camera.endXr();
}
});
}

// end session by keyboard ESC
app.keyboard.on('keydown', function (evt) {
if (evt.key === pc.KEY_ESCAPE && app.xr.active) {
app.xr.end();
}
});

// when new input source added
app.xr.input.on('add', function(inputSource) {
message("Controller Added");
createController(inputSource);
});

message("Tap on screen to enter VR, and see controllers");

// update position and rotation for each controller
app.on('update', function() {
for(var i = 0; i < controllers.length; i++) {
var inputSource = controllers[i].inputSource;
if (inputSource.grip) {
// some controllers can be gripped
controllers[i].enabled = true;
controllers[i].setPosition(inputSource.position);
controllers[i].setRotation(inputSource.rotation);
} else {
// some controllers cannot be gripped
controllers[i].enabled = false;
}
}
});
} else {
message("WebXR is not supported");
}
</script>
</body>
</html>
Loading