mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:24:00 +02:00
merge James' doppelganger changes into Tony's
This commit is contained in:
parent
6ca17a904a
commit
182ae22b44
7 changed files with 584 additions and 0 deletions
160
examples/dressing_room/createPlatformWithLights.js
Normal file
160
examples/dressing_room/createPlatformWithLights.js
Normal file
|
@ -0,0 +1,160 @@
|
|||
//
|
||||
// createDressingPlatform.js
|
||||
//
|
||||
// Created by James B. Pollack @imgntn on 1/7/2016
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// This script shows how to hook up a model entity to your avatar to act as a doppelganger.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
var basePlatform;
|
||||
var basePosition = Vec3.sum(Vec3.sum(MyAvatar.position, {
|
||||
x: 0,
|
||||
y: -1,
|
||||
z: 0
|
||||
}), Vec3.multiply(2, Quat.getFront(Camera.getOrientation())));
|
||||
|
||||
var loadArea;
|
||||
var LOAD_AREA_SCRIPT_URL = Script.resolvePath('loadingAreaEntity.js');
|
||||
|
||||
function createBasePlatform() {
|
||||
var properties = {
|
||||
type: 'Box',
|
||||
name: 'Hifi-Dressing-Room-Base',
|
||||
dimensions: {
|
||||
x: 4,
|
||||
y: 0.10,
|
||||
z: 4
|
||||
},
|
||||
color: {
|
||||
red: 255,
|
||||
green: 0,
|
||||
blue: 255
|
||||
},
|
||||
position: basePosition,
|
||||
collisionsWillMove: false,
|
||||
ignoreForCollisions: false,
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
grabbable: false
|
||||
}
|
||||
})
|
||||
}
|
||||
basePlatform = Entities.addEntity(properties);
|
||||
}
|
||||
|
||||
function createLoadArea() {
|
||||
// on enter, load the wearables manager and the doppelganger manager;
|
||||
// on exit, stop the scripts (at least call cleanup);
|
||||
var properties = {
|
||||
type: 'Box',
|
||||
shapeType: 'box',
|
||||
name: 'Hifi-Dressing-Room-Load-Area',
|
||||
dimensions: {
|
||||
x: 0.25,
|
||||
y: 0.25,
|
||||
z: 0.25
|
||||
},
|
||||
color: {
|
||||
red: 0,
|
||||
green: 255,
|
||||
blue: 0
|
||||
},
|
||||
visible: true,
|
||||
position: basePosition,
|
||||
collisionsWillMove: false,
|
||||
ignoreForCollisions: true,
|
||||
script: LOAD_AREA_SCRIPT_URL,
|
||||
|
||||
}
|
||||
loadArea = Entities.addEntity(properties);
|
||||
}
|
||||
var lights = [];
|
||||
|
||||
function createLightAtPosition(position) {
|
||||
var lightProperties = {
|
||||
name: 'Hifi-Spotlight',
|
||||
type: "Light",
|
||||
isSpotlight: true,
|
||||
dimensions: {
|
||||
x: 2,
|
||||
y: 2,
|
||||
z: 8
|
||||
},
|
||||
color: {
|
||||
red: 255,
|
||||
green: 255,
|
||||
blue: 255
|
||||
},
|
||||
intensity: 0.035,
|
||||
exponent: 1,
|
||||
cutoff: 40,
|
||||
lifetime: -1,
|
||||
position: position,
|
||||
rotation: getLightRotation(position)
|
||||
};
|
||||
|
||||
light = Entities.addEntity(lightProperties);
|
||||
lights.push(light);
|
||||
}
|
||||
|
||||
function createLights() {
|
||||
var lightPosition = {
|
||||
x: basePosition.x - 2,
|
||||
y: basePosition.y + 3,
|
||||
z: basePosition.z
|
||||
}
|
||||
createLightAtPosition(lightPosition);
|
||||
|
||||
var lightPosition = {
|
||||
x: basePosition.x + 2,
|
||||
y: basePosition.y + 3,
|
||||
z: basePosition.z
|
||||
}
|
||||
|
||||
createLightAtPosition(lightPosition);
|
||||
var lightPosition = {
|
||||
x: basePosition.x,
|
||||
y: basePosition.y + 3,
|
||||
z: basePosition.z + 2
|
||||
}
|
||||
|
||||
createLightAtPosition(lightPosition);
|
||||
var lightPosition = {
|
||||
x: basePosition.x,
|
||||
y: basePosition.y + 3,
|
||||
z: basePosition.z - 2
|
||||
}
|
||||
|
||||
createLightAtPosition(lightPosition);
|
||||
|
||||
}
|
||||
|
||||
function getLightRotation(myPosition) {
|
||||
|
||||
var sourceToTargetVec = Vec3.subtract(basePosition, myPosition);
|
||||
var emitOrientation = Quat.rotationBetween(Vec3.UNIT_NEG_Z, sourceToTargetVec);
|
||||
|
||||
return emitOrientation
|
||||
}
|
||||
|
||||
function init() {
|
||||
createBasePlatform();
|
||||
createLights();
|
||||
// createLoadArea();
|
||||
}
|
||||
|
||||
|
||||
function cleanup() {
|
||||
Entities.deleteEntity(basePlatform);
|
||||
|
||||
while (lights.length > 0) {
|
||||
Entities.deleteEntity(lights.pop());
|
||||
}
|
||||
// Entities.deleteEntity(loadArea);
|
||||
}
|
||||
init();
|
||||
Script.scriptEnding.connect(cleanup)
|
117
examples/dressing_room/createTableWithItems.js
Normal file
117
examples/dressing_room/createTableWithItems.js
Normal file
|
@ -0,0 +1,117 @@
|
|||
//
|
||||
// createTableWithItems.js
|
||||
//
|
||||
// Created by James B. Pollack @imgntn on 1/7/2016
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// This script shows how to hook up a model entity to your avatar to act as a doppelganger.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
|
||||
var table, wearable;
|
||||
|
||||
var TABLE_MODEL_URL = 'http://hifi-content.s3.amazonaws.com/james/doppelganger/table.FBX';
|
||||
var TABLE_DIMENSIONS = {
|
||||
x: 0.76,
|
||||
y: 1.06,
|
||||
z: 0.76
|
||||
};
|
||||
|
||||
function createTable() {
|
||||
var avatarRot = Quat.fromPitchYawRollDegrees(0, MyAvatar.bodyYaw, 0.0);
|
||||
var position, rotation;
|
||||
var ids = Entities.findEntities(MyAvatar.position, 20);
|
||||
var hasBase = false;
|
||||
for (var i = 0; i < ids.length; i++) {
|
||||
var entityID = ids[i];
|
||||
var props = Entities.getEntityProperties(entityID, "name");
|
||||
var name = props.name;
|
||||
if (name === "Hifi-Dressing-Room-Base") {
|
||||
var details = Entities.getEntityProperties(entityID, ["position", "dimensions", "rotation"]);
|
||||
var rightVector = Quat.getRight(details.rotation);
|
||||
var rightDistance = 1.5;
|
||||
position = Vec3.sum(Vec3.multiply(rightDistance, rightVector), details.position);
|
||||
position.y = details.position.y += TABLE_DIMENSIONS.y / 2
|
||||
rotation = details.rotation;
|
||||
hasBase = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasBase === false) {
|
||||
position = Vec3.sum(MyAvatar.position, Vec3.multiply(1.5, Quat.getFront(avatarRot)));
|
||||
rotation = avatarRot;
|
||||
}
|
||||
|
||||
var tableProperties = {
|
||||
name: 'Hifi-Dressing-Room-Table',
|
||||
type: 'Model',
|
||||
shapeType:'box',
|
||||
modelURL: TABLE_MODEL_URL,
|
||||
dimensions: TABLE_DIMENSIONS,
|
||||
position: position,
|
||||
rotation: rotation,
|
||||
collisionsWillMove: false,
|
||||
ignoreForCollisions: false,
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
grabbable: false
|
||||
}
|
||||
})
|
||||
}
|
||||
print('TABLE PROPS', JSON.stringify(tableProperties))
|
||||
table = Entities.addEntity(tableProperties);
|
||||
}
|
||||
|
||||
|
||||
function createWearable() {
|
||||
var tableProperties = Entities.getEntityProperties(table);
|
||||
var properties = {
|
||||
type: 'Model',
|
||||
modelURL: 'https://s3.amazonaws.com/hifi-public/tony/cowboy-hat.fbx',
|
||||
name: 'Hifi-Wearable',
|
||||
dimensions: {
|
||||
x: 0.25,
|
||||
y: 0.25,
|
||||
z: 0.25
|
||||
},
|
||||
color: {
|
||||
red: 0,
|
||||
green: 255,
|
||||
blue: 0
|
||||
},
|
||||
position: {
|
||||
x: tableProperties.position.x,
|
||||
y: tableProperties.position.y + tableProperties.dimensions.y / 1.5,
|
||||
z: tableProperties.position.z
|
||||
},
|
||||
userData: JSON.stringify({
|
||||
"grabbableKey": {
|
||||
"invertSolidWhileHeld": false
|
||||
},
|
||||
"wearable": {
|
||||
"joints": ["head", "Head", "hair", "neck"]
|
||||
},
|
||||
handControllerKey: {
|
||||
disableReleaseVelocity: true,
|
||||
disableMoveWithHead: true,
|
||||
}
|
||||
})
|
||||
}
|
||||
wearable = Entities.addEntity(properties);
|
||||
}
|
||||
|
||||
function init() {
|
||||
createTable();
|
||||
createWearable();
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
Entities.deleteEntity(table);
|
||||
Entities.deleteEntity(wearable);
|
||||
|
||||
}
|
||||
init();
|
||||
Script.scriptEnding.connect(cleanup)
|
76
examples/dressing_room/freezeToggler.js
Normal file
76
examples/dressing_room/freezeToggler.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
//
|
||||
// dopppelgangerEntity.js
|
||||
//
|
||||
// Created by James B. Pollack @imgntn on 1/6/2016
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// for freezing / unfreezing the doppelganger
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
(function() {
|
||||
var COUNTDOWN_LENGTH = 0;
|
||||
var _this;
|
||||
|
||||
Dopppelganger = function() {
|
||||
|
||||
_this = this;
|
||||
};
|
||||
|
||||
Dopppelganger.prototype = {
|
||||
isFrozen: false,
|
||||
startNearTrigger: function() {
|
||||
print('DOPPELGANGER NEAR TRIGGER')
|
||||
},
|
||||
startFarTrigger: function() {
|
||||
print('DOPPELGANGER FAR TRIGGER')
|
||||
if (this.isFrozen === false) {
|
||||
this.freeze();
|
||||
} else {
|
||||
this.unfreeze();
|
||||
}
|
||||
|
||||
},
|
||||
clickReleaseOnEntity: function(entityID, mouseEvent) {
|
||||
print('DOPPELGANGER CLICK')
|
||||
if (!mouseEvent.isLeftButton) {
|
||||
return;
|
||||
}
|
||||
if (this.isFrozen === false) {
|
||||
this.freeze();
|
||||
} else {
|
||||
this.unfreeze();
|
||||
}
|
||||
|
||||
},
|
||||
freeze: function() {
|
||||
print('FREEZE YO')
|
||||
this.isFrozen = true;
|
||||
var data = {
|
||||
action: 'freeze'
|
||||
}
|
||||
|
||||
Script.setTimeout(function() {
|
||||
Messages.sendMessage('Hifi-Doppelganger-Freeze', JSON.stringify(data));
|
||||
}, COUNTDOWN_LENGTH)
|
||||
|
||||
},
|
||||
unfreeze: function() {
|
||||
this.isFrozen = false;
|
||||
var data = {
|
||||
action: 'unfreeze'
|
||||
}
|
||||
Messages.sendMessage('Hifi-Doppelganger-Freeze', JSON.stringify(data));
|
||||
},
|
||||
|
||||
preload: function(entityID) {
|
||||
this.entityID = entityID;
|
||||
this.initialProperties = Entities.getEntityProperties(this.entityID);
|
||||
this.userData = JSON.parse(this.initialProperties.userData);
|
||||
},
|
||||
};
|
||||
|
||||
return new Dopppelganger();
|
||||
})
|
34
examples/dressing_room/loadingAreaEntity.js
Normal file
34
examples/dressing_room/loadingAreaEntity.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
//
|
||||
// loadingAreaEntity.js
|
||||
//
|
||||
// Created by James B. Pollack @imgntn on 1/7/2016
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// This script shows how to hook up a model entity to your avatar to act as a doppelganger.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
(function() {
|
||||
|
||||
var WEARABLES_MANAGER_SCRIPT = Script.resolvePath('wearablesManager.js');
|
||||
var DOPPELGANGER_SCRIPT = Script.resolvePath('doppelganger.js');
|
||||
var CREATE_TEST_WEARABLE_SCRIPT = Script.resolvePath('createTestWearable.js');
|
||||
this.preload = function(entityID) {
|
||||
print("preload(" + entityID + ")");
|
||||
};
|
||||
|
||||
this.enterEntity = function(entityID) {
|
||||
print("enterEntity(" + entityID + ")");
|
||||
// Script.load(WEARABLES_MANAGER_SCRIPT);
|
||||
// Script.load(DOPPELGANGER_SCRIPT);
|
||||
// Script.load(CREATE_TEST_WEARABLE_SCRIPT);
|
||||
|
||||
};
|
||||
|
||||
this.leaveEntity = function(entityID) {
|
||||
print("leaveEntity(" + entityID + ")");
|
||||
};
|
||||
|
||||
})
|
48
examples/dressing_room/mirroredEntity.js
Normal file
48
examples/dressing_room/mirroredEntity.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
//
|
||||
// mirroredEntity.js
|
||||
//
|
||||
// Created by James B. Pollack @imgntn on 1/6/2016
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// when grabbed, this entity relays updates to update the base entity
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
(function() {
|
||||
|
||||
var _this;
|
||||
|
||||
MirroredEntity = function() {
|
||||
_this = this;
|
||||
};
|
||||
|
||||
MirroredEntity.prototype = {
|
||||
startNearGrab: function () {
|
||||
print("I was just grabbed... entity:" + this.entityID);
|
||||
},
|
||||
continueNearGrab: function () {
|
||||
print("I am still being grabbed... entity:" + this.entityID);
|
||||
var data = {
|
||||
action:'updateBase',
|
||||
baseEntity:this.userData.doppelgangerKey.baseEntity,
|
||||
mirrorEntity:this.entityID,
|
||||
doppelganger:this.userData.doppelgangerKey.doppelganger
|
||||
}
|
||||
Messages.sendMessage('Hifi-Doppelganger-Wearable',data)
|
||||
},
|
||||
|
||||
releaseGrab: function () {
|
||||
print("I was released... entity:" + this.entityID);
|
||||
},
|
||||
|
||||
preload: function(entityID) {
|
||||
this.entityID = entityID;
|
||||
this.initialProperties = Entities.getEntityProperties(this.entityID);
|
||||
this.userData = JSON.parse(this.initialProperties.userData);
|
||||
},
|
||||
};
|
||||
|
||||
return new MirroredEntity();
|
||||
})
|
11
examples/dressing_room/setupDressingRoom.js
Normal file
11
examples/dressing_room/setupDressingRoom.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
var createPlatformWithLights = Script.resolvePath('createPlatformWithLights.js?'+Math.random(0,100));
|
||||
Script.include(createPlatformWithLights);
|
||||
var createTableWithItems = Script.resolvePath('createTableWithItems.js?'+Math.random(0,100));
|
||||
Script.include(createTableWithItems);
|
||||
var doppelganger = Script.resolvePath('doppelganger.js?'+Math.random(0,100));
|
||||
Script.include(doppelganger);
|
||||
var wearablesManager = Script.resolvePath('wearablesManager.js?'+Math.random(0,100));
|
||||
Script.include(wearablesManager);
|
||||
var handControllerGrab = Script.resolvePath('../controllers/handControllerGrab.js?'+Math.random(0,100));
|
||||
Script.include(handControllerGrab);
|
||||
//put it in an interior
|
138
examples/dressing_room/wearablesManager.js
Normal file
138
examples/dressing_room/wearablesManager.js
Normal file
|
@ -0,0 +1,138 @@
|
|||
//
|
||||
// wearablesManager.js
|
||||
//
|
||||
// Created by James B. Pollack @imgntn on 1/7/2016
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// This script handles messages from the grab script related to wearables, and interacts with a doppelganger.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// todo:
|
||||
// add camera countdown / freezing unfreezing the doppelganger
|
||||
// add ability to drop wearables on doppelganger
|
||||
// which means creating a mirror entity on the avatar ...
|
||||
|
||||
Script.include("../libraries/utils.js");
|
||||
|
||||
var NULL_UUID = "{00000000-0000-0000-0000-000000000000}";
|
||||
var DEFAULT_WEARABLE_DATA = {
|
||||
joints: {}
|
||||
};
|
||||
|
||||
function WearablesManager() {
|
||||
|
||||
this.wearables = [];
|
||||
|
||||
this.subscribeToMessages = function() {
|
||||
Messages.subscribe('Hifi-Object-Manipulation');
|
||||
Messages.messageReceived.connect(this.handleWearableMessages);
|
||||
}
|
||||
|
||||
this.handleWearableMessages = function(channel, message, sender) {
|
||||
// print('wearablesManager messageReceived ::: ' + channel + " ::: " + message)
|
||||
if (channel !== 'Hifi-Object-Manipulation') {
|
||||
return;
|
||||
}
|
||||
// if (sender !== MyAvatar.sessionUUID) {
|
||||
// print('wearablesManager got message from wrong sender');
|
||||
// return;
|
||||
// }
|
||||
|
||||
var parsedMessage = null;
|
||||
|
||||
try {
|
||||
parsedMessage = JSON.parse(message);
|
||||
} catch (e) {
|
||||
print('error parsing wearable message');
|
||||
}
|
||||
|
||||
if (parsedMessage.action === 'update' && manager.wearables.length !== 0) {
|
||||
manager.updateWearable(parsedMessage.grabbedEntity)
|
||||
} else if (parsedMessage.action === 'update' && manager.wearables.length === 0) {
|
||||
} else if (parsedMessage.action === 'release') {
|
||||
manager.checkIfWearable(parsedMessage.grabbedEntity)
|
||||
} else {
|
||||
print('unknown actions: ' + parsedMessage.action);
|
||||
}
|
||||
}
|
||||
|
||||
this.updateWearable = function(grabbedEntity) {
|
||||
if (this.wearables.length > 0) {
|
||||
|
||||
//only do this check if we already have some wearables for the doppelganger
|
||||
var hasWearableAlready = this.wearables.indexOf(grabbedEntity);
|
||||
var props = Entities.getEntityProperties(grabbedEntity);
|
||||
|
||||
if (hasWearableAlready > -1) {
|
||||
var data = {
|
||||
action: 'update',
|
||||
baseEntity: grabbedEntity,
|
||||
}
|
||||
|
||||
Messages.sendMessage('Hifi-Doppelganger-Wearable', JSON.stringify(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.checkIfWearableOnDoppelganger = function(grabbedEntity) {
|
||||
var allowedJoints = getEntityCustomData('wearable', grabbedEntity, DEFAULT_WEARABLE_DATA).joints;
|
||||
|
||||
var props = Entities.getEntityProperties(grabbedEntity, ["position", "parentID"]);
|
||||
if (props.parentID === NULL_UUID || props.parentID === MyAvatar.sessionUUID) {
|
||||
var bestJointName = "";
|
||||
var bestJointIndex = -1;
|
||||
var bestJointDistance = 0;
|
||||
for (var jointName in allowedJoints) {
|
||||
//do this for the model
|
||||
var jointIndex = Entities.getJointIndex(doppelganger.id,jointName);
|
||||
var jointPosition = Entities.getJointPosition(doppelganger.id,jointIndex);
|
||||
var distanceFromJoint = Vec3.distance(jointPosition, props.position);
|
||||
if (distanceFromJoint < 0.4) {
|
||||
if (bestJointIndex == -1 || distanceFromJoint < bestJointDistance) {
|
||||
bestJointName = jointName;
|
||||
bestJointIndex = jointIndex;
|
||||
bestJointDistance = distanceFromJoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestJointIndex != -1) {
|
||||
Entities.editEntity(grabbedEntity, {
|
||||
parentID: doppelganger.id,
|
||||
parentJointIndex: bestJointIndex
|
||||
});
|
||||
|
||||
if (this.wearables.indexOf(grabbedEntity) < 0) {
|
||||
var data = {
|
||||
action: 'addToDoppelganger',
|
||||
baseEntity: grabbedEntity,
|
||||
}
|
||||
Messages.sendMessage('Hifi-Doppelganger-Wearable-Avatar', JSON.stringify(data));
|
||||
this.wearables.push(grabbedEntity)
|
||||
}
|
||||
} else {
|
||||
Entities.editEntity(grabbedEntity, {
|
||||
parentID: NULL_UUID
|
||||
});
|
||||
|
||||
var hasWearableAlready = this.wearables.indexOf(grabbedEntity);
|
||||
if (hasWearableAlready > -1) {
|
||||
var data = {
|
||||
action: 'removeFromDoppelganger',
|
||||
baseEntity: grabbedEntity
|
||||
}
|
||||
|
||||
Messages.sendMessage('Hifi-Doppelganger-Wearable-Avatar', JSON.stringify(data));
|
||||
}
|
||||
|
||||
this.wearables.splice(hasWearableAlready, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var manager = new WearablesManager();
|
||||
manager.subscribeToMessages();
|
Loading…
Reference in a new issue