mirror of
https://github.com/overte-org/overte.git
synced 2025-07-10 22:38:33 +02:00
Merge branch 'master' into 20681
Conflicts: libraries/entities/src/EntityItemProperties.cpp
This commit is contained in:
commit
812ab9b7c6
57 changed files with 990 additions and 765 deletions
|
@ -10,72 +10,71 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
Script.include("../libraries/utils.js");
|
Script.include("../libraries/utils.js");
|
||||||
|
|
||||||
var RADIUS_FACTOR = 4;
|
|
||||||
|
|
||||||
var RIGHT_HAND_CLICK = Controller.findAction("RIGHT_HAND_CLICK");
|
/////////////////////////////////////////////////////////////////
|
||||||
var rightTriggerAction = RIGHT_HAND_CLICK;
|
//
|
||||||
|
// these tune time-averaging and "on" value for analog trigger
|
||||||
|
//
|
||||||
|
|
||||||
|
var TRIGGER_SMOOTH_RATIO = 0.0; // 0.0 disables smoothing of trigger value
|
||||||
|
var TRIGGER_ON_VALUE = 0.2;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// distant manipulation
|
||||||
|
//
|
||||||
|
|
||||||
|
var DISTANCE_HOLDING_RADIUS_FACTOR = 5; // multiplied by distance between hand and object
|
||||||
|
var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position
|
||||||
|
var DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR = 2.0; // object rotates this much more than hand did
|
||||||
|
var NO_INTERSECT_COLOR = {red: 10, green: 10, blue: 255}; // line color when pick misses
|
||||||
|
var INTERSECT_COLOR = {red: 250, green: 10, blue: 10}; // line color when pick hits
|
||||||
|
var LINE_ENTITY_DIMENSIONS = {x: 1000, y: 1000, z: 1000};
|
||||||
|
var LINE_LENGTH = 500;
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// near grabbing
|
||||||
|
//
|
||||||
|
|
||||||
|
var GRAB_RADIUS = 0.3; // if the ray misses but an object is this close, it will still be selected
|
||||||
|
var NEAR_GRABBING_ACTION_TIMEFRAME = 0.05; // how quickly objects move to their new position
|
||||||
|
var NEAR_GRABBING_VELOCITY_SMOOTH_RATIO = 1.0; // adjust time-averaging of held object's velocity. 1.0 to disable.
|
||||||
|
var NEAR_PICK_MAX_DISTANCE = 0.6; // max length of pick-ray for close grabbing to be selected
|
||||||
|
var RELEASE_VELOCITY_MULTIPLIER = 1.5; // affects throwing things
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// other constants
|
||||||
|
//
|
||||||
|
|
||||||
|
var RIGHT_HAND = 1;
|
||||||
|
var LEFT_HAND = 0;
|
||||||
|
|
||||||
|
var ZERO_VEC = {x: 0, y: 0, z: 0};
|
||||||
|
var NULL_ACTION_ID = "{00000000-0000-0000-000000000000}";
|
||||||
|
var MSEC_PER_SEC = 1000.0;
|
||||||
|
|
||||||
|
// these control how long an abandoned pointer line will hang around
|
||||||
|
var startTime = Date.now();
|
||||||
|
var LIFETIME = 10;
|
||||||
|
|
||||||
|
// states for the state machine
|
||||||
|
var STATE_SEARCHING = 0;
|
||||||
|
var STATE_DISTANCE_HOLDING = 1;
|
||||||
|
var STATE_CONTINUE_DISTANCE_HOLDING = 2;
|
||||||
|
var STATE_NEAR_GRABBING = 3;
|
||||||
|
var STATE_CONTINUE_NEAR_GRABBING = 4;
|
||||||
|
var STATE_RELEASE = 5;
|
||||||
|
|
||||||
var GRAB_USER_DATA_KEY = "grabKey";
|
var GRAB_USER_DATA_KEY = "grabKey";
|
||||||
|
|
||||||
var LEFT_HAND_CLICK = Controller.findAction("LEFT_HAND_CLICK");
|
function controller(hand, triggerAction) {
|
||||||
var leftTriggerAction = LEFT_HAND_CLICK;
|
|
||||||
|
|
||||||
var LIFETIME = 10;
|
|
||||||
var EXTRA_TIME = 5;
|
|
||||||
var POINTER_CHECK_TIME = 5000;
|
|
||||||
|
|
||||||
var ZERO_VEC = {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
z: 0
|
|
||||||
}
|
|
||||||
var LINE_LENGTH = 500;
|
|
||||||
var THICK_LINE_WIDTH = 7;
|
|
||||||
var THIN_LINE_WIDTH = 2;
|
|
||||||
|
|
||||||
var NO_INTERSECT_COLOR = {
|
|
||||||
red: 10,
|
|
||||||
green: 10,
|
|
||||||
blue: 255
|
|
||||||
};
|
|
||||||
var INTERSECT_COLOR = {
|
|
||||||
red: 250,
|
|
||||||
green: 10,
|
|
||||||
blue: 10
|
|
||||||
};
|
|
||||||
|
|
||||||
var GRAB_RADIUS = 0.3;
|
|
||||||
|
|
||||||
var GRAB_COLOR = {
|
|
||||||
red: 250,
|
|
||||||
green: 10,
|
|
||||||
blue: 250
|
|
||||||
};
|
|
||||||
var SHOW_LINE_THRESHOLD = 0.2;
|
|
||||||
var DISTANCE_HOLD_THRESHOLD = 0.8;
|
|
||||||
|
|
||||||
var right4Action = 18;
|
|
||||||
var left4Action = 17;
|
|
||||||
|
|
||||||
var RIGHT = 1;
|
|
||||||
var LEFT = 0;
|
|
||||||
var rightController = new controller(RIGHT, rightTriggerAction, right4Action, "right");
|
|
||||||
var leftController = new controller(LEFT, leftTriggerAction, left4Action, "left");
|
|
||||||
var startTime = Date.now();
|
|
||||||
|
|
||||||
|
|
||||||
//Need to wait before calling these methods for some reason...
|
|
||||||
Script.setTimeout(function() {
|
|
||||||
rightController.checkPointer();
|
|
||||||
leftController.checkPointer();
|
|
||||||
}, 100)
|
|
||||||
|
|
||||||
function controller(side, triggerAction, pullAction, hand) {
|
|
||||||
this.hand = hand;
|
this.hand = hand;
|
||||||
if (hand === "right") {
|
if (this.hand === RIGHT_HAND) {
|
||||||
this.getHandPosition = MyAvatar.getRightPalmPosition;
|
this.getHandPosition = MyAvatar.getRightPalmPosition;
|
||||||
this.getHandRotation = MyAvatar.getRightPalmRotation;
|
this.getHandRotation = MyAvatar.getRightPalmRotation;
|
||||||
} else {
|
} else {
|
||||||
|
@ -83,309 +82,345 @@ function controller(side, triggerAction, pullAction, hand) {
|
||||||
this.getHandRotation = MyAvatar.getLeftPalmRotation;
|
this.getHandRotation = MyAvatar.getLeftPalmRotation;
|
||||||
}
|
}
|
||||||
this.triggerAction = triggerAction;
|
this.triggerAction = triggerAction;
|
||||||
this.pullAction = pullAction;
|
this.palm = 2 * hand;
|
||||||
this.actionID = null;
|
// this.tip = 2 * hand + 1; // unused, but I'm leaving this here for fear it will be needed
|
||||||
this.distanceHolding = false;
|
|
||||||
this.closeGrabbing = false;
|
|
||||||
this.triggerValue = 0;
|
|
||||||
this.prevTriggerValue = 0;
|
|
||||||
this.palm = 2 * side;
|
|
||||||
this.tip = 2 * side + 1;
|
|
||||||
this.pointer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
this.actionID = null; // action this script created...
|
||||||
|
this.grabbedEntity = null; // on this entity.
|
||||||
|
this.grabbedVelocity = ZERO_VEC; // rolling average of held object's velocity
|
||||||
|
this.state = 0;
|
||||||
|
this.pointer = null; // entity-id of line object
|
||||||
|
this.triggerValue = 0; // rolling average of trigger value
|
||||||
|
|
||||||
controller.prototype.updateLine = function() {
|
this.update = function() {
|
||||||
if (this.pointer != null) {
|
switch(this.state) {
|
||||||
if (Entities.getEntityProperties(this.pointer).id != this.pointer) {
|
case STATE_SEARCHING:
|
||||||
this.pointer = null;
|
this.search();
|
||||||
|
break;
|
||||||
|
case STATE_DISTANCE_HOLDING:
|
||||||
|
this.distanceHolding();
|
||||||
|
break;
|
||||||
|
case STATE_CONTINUE_DISTANCE_HOLDING:
|
||||||
|
this.continueDistanceHolding();
|
||||||
|
break;
|
||||||
|
case STATE_NEAR_GRABBING:
|
||||||
|
this.nearGrabbing();
|
||||||
|
break;
|
||||||
|
case STATE_CONTINUE_NEAR_GRABBING:
|
||||||
|
this.continueNearGrabbing();
|
||||||
|
break;
|
||||||
|
case STATE_RELEASE:
|
||||||
|
this.release();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.lineOn = function(closePoint, farPoint, color) {
|
||||||
|
// draw a line
|
||||||
if (this.pointer == null) {
|
if (this.pointer == null) {
|
||||||
this.lineCreationTime = Date.now();
|
|
||||||
this.pointer = Entities.addEntity({
|
this.pointer = Entities.addEntity({
|
||||||
type: "Line",
|
type: "Line",
|
||||||
name: "pointer",
|
name: "pointer",
|
||||||
color: NO_INTERSECT_COLOR,
|
dimensions: LINE_ENTITY_DIMENSIONS,
|
||||||
dimensions: {
|
|
||||||
x: 1000,
|
|
||||||
y: 1000,
|
|
||||||
z: 1000
|
|
||||||
},
|
|
||||||
visible: true,
|
visible: true,
|
||||||
|
position: closePoint,
|
||||||
|
linePoints: [ ZERO_VEC, farPoint ],
|
||||||
|
color: color,
|
||||||
lifetime: LIFETIME
|
lifetime: LIFETIME
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
Entities.editEntity(this.pointer, {
|
||||||
|
position: closePoint,
|
||||||
|
linePoints: [ ZERO_VEC, farPoint ],
|
||||||
|
color: color,
|
||||||
|
lifetime: (Date.now() - startTime) / MSEC_PER_SEC + LIFETIME
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var handPosition = this.getHandPosition();
|
|
||||||
var direction = Quat.getUp(this.getHandRotation());
|
|
||||||
|
|
||||||
//only check if we havent already grabbed an object
|
this.lineOff = function() {
|
||||||
if (this.distanceHolding) {
|
if (this.pointer != null) {
|
||||||
Entities.editEntity(this.pointer, {
|
Entities.deleteEntity(this.pointer);
|
||||||
position: handPosition,
|
}
|
||||||
linePoints: [ ZERO_VEC, Vec3.subtract(Entities.getEntityProperties(this.grabbedEntity).position, handPosition) ],
|
this.pointer = null;
|
||||||
lifetime: (Date.now() - startTime) / 1000.0 + LIFETIME
|
}
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
this.triggerSmoothedSqueezed = function() {
|
||||||
|
var triggerValue = Controller.getActionValue(this.triggerAction);
|
||||||
|
// smooth out trigger value
|
||||||
|
this.triggerValue = (this.triggerValue * TRIGGER_SMOOTH_RATIO) +
|
||||||
|
(triggerValue * (1.0 - TRIGGER_SMOOTH_RATIO));
|
||||||
|
return this.triggerValue > TRIGGER_ON_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.triggerSqueezed = function() {
|
||||||
|
var triggerValue = Controller.getActionValue(this.triggerAction);
|
||||||
|
return triggerValue > TRIGGER_ON_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.search = function() {
|
||||||
|
if (!this.triggerSmoothedSqueezed()) {
|
||||||
|
this.state = STATE_RELEASE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entities.editEntity(this.pointer, {
|
// the trigger is being pressed, do a ray test
|
||||||
position: handPosition,
|
var handPosition = this.getHandPosition();
|
||||||
linePoints: [ ZERO_VEC, Vec3.multiply(direction, LINE_LENGTH) ],
|
var pickRay = {origin: handPosition, direction: Quat.getUp(this.getHandRotation())};
|
||||||
lifetime: (Date.now() - startTime) / 1000.0 + LIFETIME
|
|
||||||
});
|
|
||||||
|
|
||||||
if (this.checkForIntersections(handPosition, direction)) {
|
|
||||||
Entities.editEntity(this.pointer, {
|
|
||||||
color: INTERSECT_COLOR,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Entities.editEntity(this.pointer, {
|
|
||||||
color: NO_INTERSECT_COLOR,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
controller.prototype.checkPointer = function() {
|
|
||||||
var self = this;
|
|
||||||
Script.setTimeout(function() {
|
|
||||||
var props = Entities.getEntityProperties(self.pointer);
|
|
||||||
Entities.editEntity(self.pointer, {
|
|
||||||
lifetime: (Date.now() - startTime) / 1000.0 + LIFETIME
|
|
||||||
});
|
|
||||||
self.checkPointer();
|
|
||||||
}, POINTER_CHECK_TIME);
|
|
||||||
}
|
|
||||||
|
|
||||||
controller.prototype.checkForIntersections = function(origin, direction) {
|
|
||||||
var pickRay = {
|
|
||||||
origin: origin,
|
|
||||||
direction: direction
|
|
||||||
};
|
|
||||||
|
|
||||||
var intersection = Entities.findRayIntersection(pickRay, true);
|
var intersection = Entities.findRayIntersection(pickRay, true);
|
||||||
if (intersection.intersects && intersection.properties.collisionsWillMove === 1) {
|
if (intersection.intersects &&
|
||||||
var handPosition = Controller.getSpatialControlPosition(this.palm);
|
intersection.properties.collisionsWillMove === 1 &&
|
||||||
this.distanceToEntity = Vec3.distance(handPosition, intersection.properties.position);
|
intersection.properties.locked === 0) {
|
||||||
var intersectionDistance = Vec3.distance(handPosition, intersection.intersection);
|
// the ray is intersecting something we can move.
|
||||||
|
var handControllerPosition = Controller.getSpatialControlPosition(this.palm);
|
||||||
if (intersectionDistance < 0.6) {
|
var intersectionDistance = Vec3.distance(handControllerPosition, intersection.intersection);
|
||||||
//We are grabbing an entity, so let it know we've grabbed it
|
|
||||||
this.grabbedEntity = intersection.entityID;
|
this.grabbedEntity = intersection.entityID;
|
||||||
this.activateEntity(this.grabbedEntity);
|
if (intersectionDistance < NEAR_PICK_MAX_DISTANCE) {
|
||||||
this.hidePointer();
|
// the hand is very close to the intersected object. go into close-grabbing mode.
|
||||||
this.shouldDisplayLine = false;
|
this.state = STATE_NEAR_GRABBING;
|
||||||
this.grabEntity();
|
|
||||||
return true;
|
|
||||||
} else {
|
} else {
|
||||||
Entities.editEntity(this.pointer, {
|
// the hand is far from the intersected object. go into distance-holding mode
|
||||||
linePoints: [
|
this.state = STATE_DISTANCE_HOLDING;
|
||||||
ZERO_VEC,
|
this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR);
|
||||||
Vec3.multiply(direction, this.distanceToEntity)
|
}
|
||||||
]
|
} else {
|
||||||
});
|
// forward ray test failed, try sphere test.
|
||||||
this.grabbedEntity = intersection.entityID;
|
var nearbyEntities = Entities.findEntities(handPosition, GRAB_RADIUS);
|
||||||
return true;
|
var minDistance = GRAB_RADIUS;
|
||||||
|
var grabbedEntity = null;
|
||||||
|
for (var i = 0; i < nearbyEntities.length; i++) {
|
||||||
|
var props = Entities.getEntityProperties(nearbyEntities[i]);
|
||||||
|
var distance = Vec3.distance(props.position, handPosition);
|
||||||
|
if (distance < minDistance && props.name !== "pointer" &&
|
||||||
|
props.collisionsWillMove === 1 &&
|
||||||
|
props.locked === 0) {
|
||||||
|
this.grabbedEntity = nearbyEntities[i];
|
||||||
|
minDistance = distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.grabbedEntity === null) {
|
||||||
|
this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR);
|
||||||
|
} else {
|
||||||
|
this.state = STATE_NEAR_GRABBING;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
controller.prototype.attemptMove = function() {
|
this.distanceHolding = function() {
|
||||||
if (this.grabbedEntity || this.distanceHolding) {
|
var handControllerPosition = Controller.getSpatialControlPosition(this.palm);
|
||||||
var handPosition = Controller.getSpatialControlPosition(this.palm);
|
|
||||||
var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm));
|
var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm));
|
||||||
|
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position","rotation"]);
|
||||||
|
|
||||||
this.distanceHolding = true;
|
// add the action and initialize some variables
|
||||||
if (this.actionID === null) {
|
this.currentObjectPosition = grabbedProperties.position;
|
||||||
this.currentObjectPosition = Entities.getEntityProperties(this.grabbedEntity).position;
|
this.currentObjectRotation = grabbedProperties.rotation;
|
||||||
this.currentObjectRotation = Entities.getEntityProperties(this.grabbedEntity).rotation;
|
this.handPreviousPosition = handControllerPosition;
|
||||||
|
|
||||||
this.handPreviousPosition = handPosition;
|
|
||||||
this.handPreviousRotation = handRotation;
|
this.handPreviousRotation = handRotation;
|
||||||
|
|
||||||
this.actionID = Entities.addAction("spring", this.grabbedEntity, {
|
this.actionID = Entities.addAction("spring", this.grabbedEntity, {
|
||||||
targetPosition: this.currentObjectPosition,
|
targetPosition: this.currentObjectPosition,
|
||||||
linearTimeScale: .1,
|
linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME,
|
||||||
targetRotation: this.currentObjectRotation,
|
targetRotation: this.currentObjectRotation,
|
||||||
angularTimeScale: .1
|
angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME
|
||||||
});
|
});
|
||||||
} else {
|
if (this.actionID == NULL_ACTION_ID) {
|
||||||
var radius = Math.max(Vec3.distance(this.currentObjectPosition, handPosition) * RADIUS_FACTOR, 1.0);
|
this.actionID = null;
|
||||||
|
}
|
||||||
|
|
||||||
var handMoved = Vec3.subtract(handPosition, this.handPreviousPosition);
|
if (this.actionID != null) {
|
||||||
this.handPreviousPosition = handPosition;
|
this.state = STATE_CONTINUE_DISTANCE_HOLDING;
|
||||||
|
this.activateEntity(this.grabbedEntity);
|
||||||
|
Entities.callEntityMethod(this.grabbedEntity, "startDistantGrab");
|
||||||
|
|
||||||
|
if (this.hand === RIGHT_HAND) {
|
||||||
|
Entities.callEntityMethod(this.grabbedEntity, "setRightHand");
|
||||||
|
} else {
|
||||||
|
Entities.callEntityMethod(this.grabbedEntity, "setLeftHand");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.continueDistanceHolding = function() {
|
||||||
|
if (!this.triggerSmoothedSqueezed()) {
|
||||||
|
this.state = STATE_RELEASE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var handPosition = this.getHandPosition();
|
||||||
|
var handControllerPosition = Controller.getSpatialControlPosition(this.palm);
|
||||||
|
var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm));
|
||||||
|
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position","rotation"]);
|
||||||
|
|
||||||
|
this.lineOn(handPosition, Vec3.subtract(grabbedProperties.position, handPosition), INTERSECT_COLOR);
|
||||||
|
|
||||||
|
// the action was set up on a previous call. update the targets.
|
||||||
|
var radius = Math.max(Vec3.distance(this.currentObjectPosition,
|
||||||
|
handControllerPosition) * DISTANCE_HOLDING_RADIUS_FACTOR,
|
||||||
|
DISTANCE_HOLDING_RADIUS_FACTOR);
|
||||||
|
|
||||||
|
var handMoved = Vec3.subtract(handControllerPosition, this.handPreviousPosition);
|
||||||
|
this.handPreviousPosition = handControllerPosition;
|
||||||
var superHandMoved = Vec3.multiply(handMoved, radius);
|
var superHandMoved = Vec3.multiply(handMoved, radius);
|
||||||
this.currentObjectPosition = Vec3.sum(this.currentObjectPosition, superHandMoved);
|
this.currentObjectPosition = Vec3.sum(this.currentObjectPosition, superHandMoved);
|
||||||
|
|
||||||
// ---------------- this tracks hand rotation
|
// this doubles hand rotation
|
||||||
// var handChange = Quat.multiply(handRotation, Quat.inverse(this.handPreviousRotation));
|
var handChange = Quat.multiply(Quat.slerp(this.handPreviousRotation, handRotation,
|
||||||
// this.handPreviousRotation = handRotation;
|
DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR),
|
||||||
// this.currentObjectRotation = Quat.multiply(handChange, this.currentObjectRotation);
|
|
||||||
// ----------------
|
|
||||||
|
|
||||||
// ---------------- this doubles hand rotation
|
|
||||||
var handChange = Quat.multiply(Quat.slerp(this.handPreviousRotation, handRotation, 2.0),
|
|
||||||
Quat.inverse(this.handPreviousRotation));
|
Quat.inverse(this.handPreviousRotation));
|
||||||
this.handPreviousRotation = handRotation;
|
this.handPreviousRotation = handRotation;
|
||||||
this.currentObjectRotation = Quat.multiply(handChange, this.currentObjectRotation);
|
this.currentObjectRotation = Quat.multiply(handChange, this.currentObjectRotation);
|
||||||
// ----------------
|
|
||||||
|
|
||||||
|
Entities.callEntityMethod(this.grabbedEntity, "continueDistantGrab");
|
||||||
|
|
||||||
Entities.updateAction(this.grabbedEntity, this.actionID, {
|
Entities.updateAction(this.grabbedEntity, this.actionID, {
|
||||||
targetPosition: this.currentObjectPosition, linearTimeScale: .1,
|
targetPosition: this.currentObjectPosition, linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME,
|
||||||
targetRotation: this.currentObjectRotation, angularTimeScale: .1
|
targetRotation: this.currentObjectRotation, angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
controller.prototype.showPointer = function() {
|
|
||||||
Entities.editEntity(this.pointer, {
|
|
||||||
visible: true
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
controller.prototype.hidePointer = function() {
|
|
||||||
Entities.editEntity(this.pointer, {
|
|
||||||
visible: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
controller.prototype.letGo = function() {
|
this.nearGrabbing = function() {
|
||||||
if (this.grabbedEntity && this.actionID) {
|
if (!this.triggerSmoothedSqueezed()) {
|
||||||
this.deactivateEntity(this.grabbedEntity);
|
this.state = STATE_RELEASE;
|
||||||
Entities.deleteAction(this.grabbedEntity, this.actionID);
|
return;
|
||||||
}
|
|
||||||
this.grabbedEntity = null;
|
|
||||||
this.actionID = null;
|
|
||||||
this.distanceHolding = false;
|
|
||||||
this.closeGrabbing = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
controller.prototype.update = function() {
|
|
||||||
this.triggerValue = Controller.getActionValue(this.triggerAction);
|
|
||||||
if (this.triggerValue > SHOW_LINE_THRESHOLD && this.prevTriggerValue < SHOW_LINE_THRESHOLD) {
|
|
||||||
//First check if an object is within close range and then run the close grabbing logic
|
|
||||||
if (this.checkForInRangeObject()) {
|
|
||||||
this.grabEntity();
|
|
||||||
} else {
|
|
||||||
this.showPointer();
|
|
||||||
this.shouldDisplayLine = true;
|
|
||||||
}
|
|
||||||
} else if (this.triggerValue < SHOW_LINE_THRESHOLD && this.prevTriggerValue > SHOW_LINE_THRESHOLD) {
|
|
||||||
this.hidePointer();
|
|
||||||
this.letGo();
|
|
||||||
this.shouldDisplayLine = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.shouldDisplayLine) {
|
this.lineOff();
|
||||||
this.updateLine();
|
|
||||||
}
|
|
||||||
if (this.triggerValue > DISTANCE_HOLD_THRESHOLD && !this.closeGrabbing) {
|
|
||||||
this.attemptMove();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.prevTriggerValue = this.triggerValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
controller.prototype.grabEntity = function() {
|
|
||||||
var handRotation = this.getHandRotation();
|
|
||||||
var handPosition = this.getHandPosition();
|
|
||||||
this.closeGrabbing = true;
|
|
||||||
//check if our entity has instructions on how to be grabbed, otherwise, just use default relative position and rotation
|
|
||||||
var userData = getEntityUserData(this.grabbedEntity);
|
|
||||||
|
|
||||||
var objectRotation = Entities.getEntityProperties(this.grabbedEntity).rotation;
|
|
||||||
var offsetRotation = Quat.multiply(Quat.inverse(handRotation), objectRotation);
|
|
||||||
|
|
||||||
var objectPosition = Entities.getEntityProperties(this.grabbedEntity).position;
|
|
||||||
var offset = Vec3.subtract(objectPosition, handPosition);
|
|
||||||
var offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, offsetRotation)), offset);
|
|
||||||
|
|
||||||
var relativePosition = offsetPosition;
|
|
||||||
var relativeRotation = offsetRotation;
|
|
||||||
if (userData.grabFrame) {
|
|
||||||
if (userData.grabFrame.relativePosition) {
|
|
||||||
relativePosition = userData.grabFrame.relativePosition;
|
|
||||||
}
|
|
||||||
if (userData.grabFrame.relativeRotation) {
|
|
||||||
relativeRotation = userData.grabFrame.relativeRotation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.actionID = Entities.addAction("hold", this.grabbedEntity, {
|
|
||||||
hand: this.hand,
|
|
||||||
timeScale: 0.05,
|
|
||||||
relativePosition: relativePosition,
|
|
||||||
relativeRotation: relativeRotation
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
controller.prototype.checkForInRangeObject = function() {
|
|
||||||
var handPosition = Controller.getSpatialControlPosition(this.palm);
|
|
||||||
var entities = Entities.findEntities(handPosition, GRAB_RADIUS);
|
|
||||||
var minDistance = GRAB_RADIUS;
|
|
||||||
var grabbedEntity = null;
|
|
||||||
//Get nearby entities and assign nearest
|
|
||||||
for (var i = 0; i < entities.length; i++) {
|
|
||||||
var props = Entities.getEntityProperties(entities[i]);
|
|
||||||
var distance = Vec3.distance(props.position, handPosition);
|
|
||||||
if (distance < minDistance && props.name !== "pointer" && props.collisionsWillMove === 1) {
|
|
||||||
grabbedEntity = entities[i];
|
|
||||||
minDistance = distance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (grabbedEntity === null) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
//We are grabbing an entity, so let it know we've grabbed it
|
|
||||||
this.grabbedEntity = grabbedEntity;
|
|
||||||
this.activateEntity(this.grabbedEntity);
|
this.activateEntity(this.grabbedEntity);
|
||||||
|
|
||||||
return true;
|
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, "position");
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
controller.prototype.activateEntity = function(entity) {
|
var handRotation = this.getHandRotation();
|
||||||
|
var handPosition = this.getHandPosition();
|
||||||
|
|
||||||
|
var objectRotation = grabbedProperties.rotation;
|
||||||
|
var offsetRotation = Quat.multiply(Quat.inverse(handRotation), objectRotation);
|
||||||
|
|
||||||
|
currentObjectPosition = grabbedProperties.position;
|
||||||
|
var offset = Vec3.subtract(currentObjectPosition, handPosition);
|
||||||
|
var offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, offsetRotation)), offset);
|
||||||
|
|
||||||
|
this.actionID = Entities.addAction("hold", this.grabbedEntity, {
|
||||||
|
hand: this.hand == RIGHT_HAND ? "right" : "left",
|
||||||
|
timeScale: NEAR_GRABBING_ACTION_TIMEFRAME,
|
||||||
|
relativePosition: offsetPosition,
|
||||||
|
relativeRotation: offsetRotation
|
||||||
|
});
|
||||||
|
if (this.actionID == NULL_ACTION_ID) {
|
||||||
|
this.actionID = null;
|
||||||
|
} else {
|
||||||
|
this.state = STATE_CONTINUE_NEAR_GRABBING;
|
||||||
|
Entities.callEntityMethod(this.grabbedEntity, "startNearGrab");
|
||||||
|
if (this.hand === RIGHT_HAND) {
|
||||||
|
Entities.callEntityMethod(this.grabbedEntity, "setRightHand");
|
||||||
|
} else {
|
||||||
|
Entities.callEntityMethod(this.grabbedEntity, "setLeftHand");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.currentHandControllerPosition = Controller.getSpatialControlPosition(this.palm);
|
||||||
|
this.currentObjectTime = Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.continueNearGrabbing = function() {
|
||||||
|
if (!this.triggerSmoothedSqueezed()) {
|
||||||
|
this.state = STATE_RELEASE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// keep track of the measured velocity of the held object
|
||||||
|
var handControllerPosition = Controller.getSpatialControlPosition(this.palm);
|
||||||
|
var now = Date.now();
|
||||||
|
|
||||||
|
var deltaPosition = Vec3.subtract(handControllerPosition, this.currentHandControllerPosition); // meters
|
||||||
|
var deltaTime = (now - this.currentObjectTime) / MSEC_PER_SEC; // convert to seconds
|
||||||
|
|
||||||
|
if (deltaTime > 0.0 && !vec3equal(this.currentHandControllerPosition, handControllerPosition)) {
|
||||||
|
var grabbedVelocity = Vec3.multiply(deltaPosition, 1.0 / deltaTime);
|
||||||
|
// don't update grabbedVelocity if the trigger is off. the smoothing of the trigger
|
||||||
|
// value would otherwise give the held object time to slow down.
|
||||||
|
if (this.triggerSqueezed()) {
|
||||||
|
this.grabbedVelocity =
|
||||||
|
Vec3.sum(Vec3.multiply(this.grabbedVelocity,
|
||||||
|
(1.0 - NEAR_GRABBING_VELOCITY_SMOOTH_RATIO)),
|
||||||
|
Vec3.multiply(grabbedVelocity, NEAR_GRABBING_VELOCITY_SMOOTH_RATIO));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.currentHandControllerPosition = handControllerPosition;
|
||||||
|
this.currentObjectTime = now;
|
||||||
|
Entities.callEntityMethod(this.grabbedEntity, "continueNearGrab");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.release = function() {
|
||||||
|
this.lineOff();
|
||||||
|
|
||||||
|
if (this.grabbedEntity != null && this.actionID != null) {
|
||||||
|
Entities.deleteAction(this.grabbedEntity, this.actionID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// the action will tend to quickly bring an object's velocity to zero. now that
|
||||||
|
// the action is gone, set the objects velocity to something the holder might expect.
|
||||||
|
Entities.editEntity(this.grabbedEntity,
|
||||||
|
{velocity: Vec3.multiply(this.grabbedVelocity, RELEASE_VELOCITY_MULTIPLIER)}
|
||||||
|
);
|
||||||
|
Entities.callEntityMethod(this.grabbedEntity, "releaseGrab");
|
||||||
|
this.deactivateEntity(this.grabbedEntity);
|
||||||
|
|
||||||
|
this.grabbedVelocity = ZERO_VEC;
|
||||||
|
this.grabbedEntity = null;
|
||||||
|
this.actionID = null;
|
||||||
|
this.state = STATE_SEARCHING;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.cleanup = function() {
|
||||||
|
release();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.activateEntity = function(entity) {
|
||||||
var data = {
|
var data = {
|
||||||
activated: true,
|
activated: true,
|
||||||
avatarId: MyAvatar.sessionUUID
|
avatarId: MyAvatar.sessionUUID
|
||||||
};
|
};
|
||||||
setEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, data);
|
setEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
controller.prototype.deactivateEntity = function(entity) {
|
this.deactivateEntity = function(entity) {
|
||||||
var data = {
|
var data = {
|
||||||
activated: false,
|
activated: false,
|
||||||
avatarId: null
|
avatarId: null
|
||||||
};
|
};
|
||||||
setEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, data);
|
setEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, data);
|
||||||
}
|
|
||||||
|
|
||||||
controller.prototype.cleanup = function() {
|
|
||||||
Entities.deleteEntity(this.pointer);
|
|
||||||
if (this.grabbedEntity) {
|
|
||||||
Entities.deleteAction(this.grabbedEntity, this.actionID);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var rightController = new controller(RIGHT_HAND, Controller.findAction("RIGHT_HAND_CLICK"));
|
||||||
|
var leftController = new controller(LEFT_HAND, Controller.findAction("LEFT_HAND_CLICK"));
|
||||||
|
|
||||||
|
|
||||||
function update() {
|
function update() {
|
||||||
rightController.update();
|
rightController.update();
|
||||||
leftController.update();
|
leftController.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function cleanup() {
|
function cleanup() {
|
||||||
rightController.cleanup();
|
rightController.cleanup();
|
||||||
leftController.cleanup();
|
leftController.cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Script.scriptEnding.connect(cleanup);
|
Script.scriptEnding.connect(cleanup);
|
||||||
Script.update.connect(update)
|
Script.update.connect(update)
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
Script.include("../libraries/utils.js");
|
|
||||||
|
|
||||||
var _this;
|
var _this;
|
||||||
|
|
||||||
|
@ -24,39 +23,29 @@
|
||||||
|
|
||||||
DetectGrabbed.prototype = {
|
DetectGrabbed.prototype = {
|
||||||
|
|
||||||
// update() will be called regulary, because we've hooked the update signal in our preload() function
|
setRightHand: function () {
|
||||||
// we will check out userData for the grabData. In the case of the hydraGrab script, it will tell us
|
print("I am being held in a right hand... entity:" + this.entityID);
|
||||||
// if we're currently being grabbed and if the person grabbing us is the current interfaces avatar.
|
},
|
||||||
// we will watch this for state changes and print out if we're being grabbed or released when it changes.
|
setLeftHand: function () {
|
||||||
update: function() {
|
print("I am being held in a left hand... entity:" + this.entityID);
|
||||||
var GRAB_USER_DATA_KEY = "grabKey";
|
},
|
||||||
|
|
||||||
// because the update() signal doesn't have a valid this, we need to use our memorized _this to access our entityID
|
startDistantGrab: function () {
|
||||||
var entityID = _this.entityID;
|
print("I am being distance held... entity:" + this.entityID);
|
||||||
|
},
|
||||||
|
continueDistantGrab: function () {
|
||||||
|
print("I continue to be distance held... entity:" + this.entityID);
|
||||||
|
},
|
||||||
|
|
||||||
// we want to assume that if there is no grab data, then we are not being grabbed
|
startNearGrab: function () {
|
||||||
var defaultGrabData = { activated: false, avatarId: null };
|
print("I was just grabbed... entity:" + this.entityID);
|
||||||
|
},
|
||||||
|
continueNearGrab: function () {
|
||||||
|
print("I am still being grabbed... entity:" + this.entityID);
|
||||||
|
},
|
||||||
|
|
||||||
// this handy function getEntityCustomData() is available in utils.js and it will return just the specific section
|
release: function () {
|
||||||
// of user data we asked for. If it's not available it returns our default data.
|
print("I was released... entity:" + this.entityID);
|
||||||
var grabData = getEntityCustomData(GRAB_USER_DATA_KEY, entityID, defaultGrabData);
|
|
||||||
|
|
||||||
// if the grabData says we're being grabbed, and the owner ID is our session, then we are being grabbed by this interface
|
|
||||||
if (grabData.activated && grabData.avatarId == MyAvatar.sessionUUID) {
|
|
||||||
|
|
||||||
// remember we're being grabbed so we can detect being released
|
|
||||||
_this.beingGrabbed = true;
|
|
||||||
|
|
||||||
// print out that we're being grabbed
|
|
||||||
print("I'm being grabbed...");
|
|
||||||
|
|
||||||
} else if (_this.beingGrabbed) {
|
|
||||||
|
|
||||||
// if we are not being grabbed, and we previously were, then we were just released, remember that
|
|
||||||
// and print out a message
|
|
||||||
_this.beingGrabbed = false;
|
|
||||||
print("I'm was released...");
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// preload() will be called when the entity has become visible (or known) to the interface
|
// preload() will be called when the entity has become visible (or known) to the interface
|
||||||
|
@ -65,14 +54,6 @@
|
||||||
// * connecting to the update signal so we can check our grabbed state
|
// * connecting to the update signal so we can check our grabbed state
|
||||||
preload: function(entityID) {
|
preload: function(entityID) {
|
||||||
this.entityID = entityID;
|
this.entityID = entityID;
|
||||||
Script.update.connect(this.update);
|
|
||||||
},
|
|
||||||
|
|
||||||
// unload() will be called when our entity is no longer available. It may be because we were deleted,
|
|
||||||
// or because we've left the domain or quit the application. In all cases we want to unhook our connection
|
|
||||||
// to the update signal
|
|
||||||
unload: function(entityID) {
|
|
||||||
Script.update.disconnect(this.update);
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,14 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
vec3toStr = function (v, digits) {
|
vec3toStr = function(v, digits) {
|
||||||
if (!digits) { digits = 3; }
|
if (!digits) { digits = 3; }
|
||||||
return "{ " + v.x.toFixed(digits) + ", " + v.y.toFixed(digits) + ", " + v.z.toFixed(digits)+ " }";
|
return "{ " + v.x.toFixed(digits) + ", " + v.y.toFixed(digits) + ", " + v.z.toFixed(digits)+ " }";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec3equal = function(v0, v1) {
|
||||||
|
return (v0.x == v1.x) && (v0.y == v1.y) && (v0.z == v1.z);
|
||||||
|
}
|
||||||
|
|
||||||
colorMix = function(colorA, colorB, mix) {
|
colorMix = function(colorA, colorB, mix) {
|
||||||
var result = {};
|
var result = {};
|
||||||
|
@ -60,7 +63,7 @@ setEntityUserData = function(id, data) {
|
||||||
// FIXME do non-destructive modification of the existing user data
|
// FIXME do non-destructive modification of the existing user data
|
||||||
getEntityUserData = function(id) {
|
getEntityUserData = function(id) {
|
||||||
var results = null;
|
var results = null;
|
||||||
var properties = Entities.getEntityProperties(id);
|
var properties = Entities.getEntityProperties(id, "userData");
|
||||||
if (properties.userData) {
|
if (properties.userData) {
|
||||||
try {
|
try {
|
||||||
results = JSON.parse(properties.userData);
|
results = JSON.parse(properties.userData);
|
||||||
|
|
|
@ -1063,7 +1063,7 @@ void Application::paintGL() {
|
||||||
auto lodManager = DependencyManager::get<LODManager>();
|
auto lodManager = DependencyManager::get<LODManager>();
|
||||||
|
|
||||||
|
|
||||||
RenderArgs renderArgs(_gpuContext, nullptr, getViewFrustum(), lodManager->getOctreeSizeScale(),
|
RenderArgs renderArgs(_gpuContext, getEntities(), getViewFrustum(), lodManager->getOctreeSizeScale(),
|
||||||
lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE,
|
lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE,
|
||||||
RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE);
|
RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE);
|
||||||
|
|
||||||
|
@ -3562,7 +3562,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
(RenderArgs::DebugFlags) (renderDebugFlags | (int)RenderArgs::RENDER_DEBUG_SIMULATION_OWNERSHIP);
|
(RenderArgs::DebugFlags) (renderDebugFlags | (int)RenderArgs::RENDER_DEBUG_SIMULATION_OWNERSHIP);
|
||||||
}
|
}
|
||||||
renderArgs->_debugFlags = renderDebugFlags;
|
renderArgs->_debugFlags = renderDebugFlags;
|
||||||
_entities.render(renderArgs);
|
|
||||||
//ViveControllerManager::getInstance().updateRendering(renderArgs, _main3DScene, pendingChanges);
|
//ViveControllerManager::getInstance().updateRendering(renderArgs, _main3DScene, pendingChanges);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3648,14 +3647,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
sceneInterface->setEngineDrawnOverlay3DItems(engineRC->_numDrawnOverlay3DItems);
|
sceneInterface->setEngineDrawnOverlay3DItems(engineRC->_numDrawnOverlay3DItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!selfAvatarOnly) {
|
|
||||||
// give external parties a change to hook in
|
|
||||||
{
|
|
||||||
PerformanceTimer perfTimer("inWorldInterface");
|
|
||||||
emit renderingInWorldInterface();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
activeRenderingThread = nullptr;
|
activeRenderingThread = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -347,9 +347,6 @@ signals:
|
||||||
/// Fired when we're simulating; allows external parties to hook in.
|
/// Fired when we're simulating; allows external parties to hook in.
|
||||||
void simulating(float deltaTime);
|
void simulating(float deltaTime);
|
||||||
|
|
||||||
/// Fired when we're rendering in-world interface elements; allows external parties to hook in.
|
|
||||||
void renderingInWorldInterface();
|
|
||||||
|
|
||||||
/// Fired when the import window is closed
|
/// Fired when the import window is closed
|
||||||
void importDone();
|
void importDone();
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,10 @@ GlobalServicesScriptingInterface::GlobalServicesScriptingInterface() {
|
||||||
connect(&accountManager, &AccountManager::logoutComplete, this, &GlobalServicesScriptingInterface::loggedOut);
|
connect(&accountManager, &AccountManager::logoutComplete, this, &GlobalServicesScriptingInterface::loggedOut);
|
||||||
|
|
||||||
_downloading = false;
|
_downloading = false;
|
||||||
connect(Application::getInstance(), &Application::renderingInWorldInterface,
|
QTimer* checkDownloadTimer = new QTimer(this);
|
||||||
this, &GlobalServicesScriptingInterface::checkDownloadInfo);
|
connect(checkDownloadTimer, &QTimer::timeout, this, &GlobalServicesScriptingInterface::checkDownloadInfo);
|
||||||
|
const int CHECK_DOWNLOAD_INTERVAL = MSECS_PER_SECOND / 2;
|
||||||
|
checkDownloadTimer->start(CHECK_DOWNLOAD_INTERVAL);
|
||||||
|
|
||||||
auto discoverabilityManager = DependencyManager::get<DiscoverabilityManager>();
|
auto discoverabilityManager = DependencyManager::get<DiscoverabilityManager>();
|
||||||
connect(discoverabilityManager.data(), &DiscoverabilityManager::discoverabilityModeChanged,
|
connect(discoverabilityManager.data(), &DiscoverabilityManager::discoverabilityModeChanged,
|
||||||
|
|
|
@ -153,6 +153,11 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar
|
||||||
++constraintItr;
|
++constraintItr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// clear the accumulators before we start the IK solver
|
||||||
|
for (auto& accumulatorPair: _accumulators) {
|
||||||
|
accumulatorPair.second.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// compute absolute poses that correspond to relative target poses
|
// compute absolute poses that correspond to relative target poses
|
||||||
AnimPoseVec absolutePoses;
|
AnimPoseVec absolutePoses;
|
||||||
computeAbsolutePoses(absolutePoses);
|
computeAbsolutePoses(absolutePoses);
|
||||||
|
@ -165,8 +170,8 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar
|
||||||
quint64 expiry = usecTimestampNow() + MAX_IK_TIME;
|
quint64 expiry = usecTimestampNow() + MAX_IK_TIME;
|
||||||
do {
|
do {
|
||||||
largestError = 0.0f;
|
largestError = 0.0f;
|
||||||
|
int lowestMovedIndex = _relativePoses.size();
|
||||||
for (auto& target: targets) {
|
for (auto& target: targets) {
|
||||||
int lowestMovedIndex = _relativePoses.size() - 1;
|
|
||||||
int tipIndex = target.index;
|
int tipIndex = target.index;
|
||||||
AnimPose targetPose = target.pose;
|
AnimPose targetPose = target.pose;
|
||||||
int rootIndex = target.rootIndex;
|
int rootIndex = target.rootIndex;
|
||||||
|
@ -226,7 +231,8 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar
|
||||||
glm::inverse(absolutePoses[pivotIndex].rot);
|
glm::inverse(absolutePoses[pivotIndex].rot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_relativePoses[pivotIndex].rot = newRot;
|
// store the rotation change in the accumulator
|
||||||
|
_accumulators[pivotIndex].add(newRot);
|
||||||
}
|
}
|
||||||
// this joint has been changed so we check to see if it has the lowest index
|
// this joint has been changed so we check to see if it has the lowest index
|
||||||
if (pivotIndex < lowestMovedIndex) {
|
if (pivotIndex < lowestMovedIndex) {
|
||||||
|
@ -243,20 +249,33 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar
|
||||||
if (largestError < error) {
|
if (largestError < error) {
|
||||||
largestError = error;
|
largestError = error;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
++numLoops;
|
||||||
|
|
||||||
if (lowestMovedIndex <= _maxTargetIndex && lowestMovedIndex < tipIndex) {
|
// harvest accumulated rotations and apply the average
|
||||||
// only update the absolutePoses that matter: those between lowestMovedIndex and _maxTargetIndex
|
for (auto& accumulatorPair: _accumulators) {
|
||||||
|
RotationAccumulator& accumulator = accumulatorPair.second;
|
||||||
|
if (accumulator.size() > 0) {
|
||||||
|
_relativePoses[accumulatorPair.first].rot = accumulator.getAverage();
|
||||||
|
accumulator.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// only update the absolutePoses that need it: those between lowestMovedIndex and _maxTargetIndex
|
||||||
for (int i = lowestMovedIndex; i <= _maxTargetIndex; ++i) {
|
for (int i = lowestMovedIndex; i <= _maxTargetIndex; ++i) {
|
||||||
int parentIndex = _skeleton->getParentIndex(i);
|
int parentIndex = _skeleton->getParentIndex(i);
|
||||||
if (parentIndex != -1) {
|
if (parentIndex != -1) {
|
||||||
absolutePoses[i] = absolutePoses[parentIndex] * _relativePoses[i];
|
absolutePoses[i] = absolutePoses[parentIndex] * _relativePoses[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} while (largestError > ACCEPTABLE_RELATIVE_ERROR && numLoops < MAX_IK_LOOPS && usecTimestampNow() < expiry);
|
||||||
|
|
||||||
// finally set the relative rotation of the tip to agree with absolute target rotation
|
// finally set the relative rotation of each tip to agree with absolute target rotation
|
||||||
|
for (auto& target: targets) {
|
||||||
|
int tipIndex = target.index;
|
||||||
int parentIndex = _skeleton->getParentIndex(tipIndex);
|
int parentIndex = _skeleton->getParentIndex(tipIndex);
|
||||||
if (parentIndex != -1) {
|
if (parentIndex != -1) {
|
||||||
|
AnimPose targetPose = target.pose;
|
||||||
// compute tip's new parent-relative rotation
|
// compute tip's new parent-relative rotation
|
||||||
// Q = Qp * q --> q' = Qp^ * Q
|
// Q = Qp * q --> q' = Qp^ * Q
|
||||||
glm::quat newRelativeRotation = glm::inverse(absolutePoses[parentIndex].rot) * targetPose.rot;
|
glm::quat newRelativeRotation = glm::inverse(absolutePoses[parentIndex].rot) * targetPose.rot;
|
||||||
|
@ -271,8 +290,6 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar
|
||||||
absolutePoses[tipIndex].rot = targetPose.rot;
|
absolutePoses[tipIndex].rot = targetPose.rot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++numLoops;
|
|
||||||
} while (largestError > ACCEPTABLE_RELATIVE_ERROR && numLoops < MAX_IK_LOOPS && usecTimestampNow() < expiry);
|
|
||||||
}
|
}
|
||||||
return _relativePoses;
|
return _relativePoses;
|
||||||
}
|
}
|
||||||
|
@ -628,6 +645,7 @@ void AnimInverseKinematics::setSkeletonInternal(AnimSkeleton::ConstPointer skele
|
||||||
|
|
||||||
_maxTargetIndex = 0;
|
_maxTargetIndex = 0;
|
||||||
|
|
||||||
|
_accumulators.clear();
|
||||||
if (skeleton) {
|
if (skeleton) {
|
||||||
initConstraints();
|
initConstraints();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -12,8 +12,13 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "AnimNode.h"
|
#include "AnimNode.h"
|
||||||
|
|
||||||
|
#include "RotationAccumulator.h"
|
||||||
|
|
||||||
class RotationConstraint;
|
class RotationConstraint;
|
||||||
|
|
||||||
class AnimInverseKinematics : public AnimNode {
|
class AnimInverseKinematics : public AnimNode {
|
||||||
|
@ -24,7 +29,6 @@ public:
|
||||||
|
|
||||||
void loadDefaultPoses(const AnimPoseVec& poses);
|
void loadDefaultPoses(const AnimPoseVec& poses);
|
||||||
void loadPoses(const AnimPoseVec& poses);
|
void loadPoses(const AnimPoseVec& poses);
|
||||||
const AnimPoseVec& getRelativePoses() const { return _relativePoses; }
|
|
||||||
void computeAbsolutePoses(AnimPoseVec& absolutePoses) const;
|
void computeAbsolutePoses(AnimPoseVec& absolutePoses) const;
|
||||||
|
|
||||||
void setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar);
|
void setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar);
|
||||||
|
@ -60,6 +64,7 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
std::map<int, RotationConstraint*> _constraints;
|
std::map<int, RotationConstraint*> _constraints;
|
||||||
|
std::map<int, RotationAccumulator> _accumulators;
|
||||||
std::vector<IKTargetVar> _targetVarVec;
|
std::vector<IKTargetVar> _targetVarVec;
|
||||||
AnimPoseVec _defaultRelativePoses; // poses of the relaxed state
|
AnimPoseVec _defaultRelativePoses; // poses of the relaxed state
|
||||||
AnimPoseVec _relativePoses; // current relative poses
|
AnimPoseVec _relativePoses; // current relative poses
|
||||||
|
|
27
libraries/animation/src/RotationAccumulator.cpp
Normal file
27
libraries/animation/src/RotationAccumulator.cpp
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
//
|
||||||
|
// RotationAccumulator.h
|
||||||
|
//
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "RotationAccumulator.h"
|
||||||
|
|
||||||
|
#include <glm/gtx/quaternion.hpp>
|
||||||
|
|
||||||
|
void RotationAccumulator::add(glm::quat rotation) {
|
||||||
|
// make sure both quaternions are on the same hyper-hemisphere before we add them linearly (lerp)
|
||||||
|
_rotationSum += copysignf(1.0f, glm::dot(_rotationSum, rotation)) * rotation;
|
||||||
|
++_numRotations;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::quat RotationAccumulator::getAverage() {
|
||||||
|
return (_numRotations > 0) ? glm::normalize(_rotationSum) : glm::quat();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RotationAccumulator::clear() {
|
||||||
|
_rotationSum *= 0.0f;
|
||||||
|
_numRotations = 0;
|
||||||
|
}
|
32
libraries/animation/src/RotationAccumulator.h
Normal file
32
libraries/animation/src/RotationAccumulator.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
//
|
||||||
|
// RotationAccumulator.h
|
||||||
|
//
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_RotationAccumulator_h
|
||||||
|
#define hifi_RotationAccumulator_h
|
||||||
|
|
||||||
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
|
||||||
|
class RotationAccumulator {
|
||||||
|
public:
|
||||||
|
RotationAccumulator() : _rotationSum(0.0f, 0.0f, 0.0f, 0.0f), _numRotations(0) { }
|
||||||
|
|
||||||
|
int size() const { return _numRotations; }
|
||||||
|
|
||||||
|
void add(glm::quat rotation);
|
||||||
|
|
||||||
|
glm::quat getAverage();
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
private:
|
||||||
|
glm::quat _rotationSum;
|
||||||
|
int _numRotations;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_RotationAccumulator_h
|
|
@ -52,9 +52,7 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf
|
||||||
_lastMouseEventValid(false),
|
_lastMouseEventValid(false),
|
||||||
_viewState(viewState),
|
_viewState(viewState),
|
||||||
_scriptingServices(scriptingServices),
|
_scriptingServices(scriptingServices),
|
||||||
_displayElementChildProxies(false),
|
|
||||||
_displayModelBounds(false),
|
_displayModelBounds(false),
|
||||||
_displayModelElementProxy(false),
|
|
||||||
_dontDoPrecisionPicking(false)
|
_dontDoPrecisionPicking(false)
|
||||||
{
|
{
|
||||||
REGISTER_ENTITY_TYPE_WITH_FACTORY(Model, RenderableModelEntityItem::factory)
|
REGISTER_ENTITY_TYPE_WITH_FACTORY(Model, RenderableModelEntityItem::factory)
|
||||||
|
@ -112,6 +110,7 @@ void EntityTreeRenderer::init() {
|
||||||
_scriptingServices->getControllerScriptingInterface());
|
_scriptingServices->getControllerScriptingInterface());
|
||||||
_scriptingServices->registerScriptEngineWithApplicationServices(_entitiesScriptEngine);
|
_scriptingServices->registerScriptEngineWithApplicationServices(_entitiesScriptEngine);
|
||||||
_entitiesScriptEngine->runInThread();
|
_entitiesScriptEngine->runInThread();
|
||||||
|
DependencyManager::get<EntityScriptingInterface>()->setEntitiesScriptEngine(_entitiesScriptEngine);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure our "last avatar position" is something other than our current position, so that on our
|
// make sure our "last avatar position" is something other than our current position, so that on our
|
||||||
|
@ -151,6 +150,7 @@ void EntityTreeRenderer::update() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
deleteReleasedModels();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityTreeRenderer::checkEnterLeaveEntities() {
|
void EntityTreeRenderer::checkEnterLeaveEntities() {
|
||||||
|
@ -167,12 +167,41 @@ void EntityTreeRenderer::checkEnterLeaveEntities() {
|
||||||
_tree->withReadLock([&] {
|
_tree->withReadLock([&] {
|
||||||
std::static_pointer_cast<EntityTree>(_tree)->findEntities(avatarPosition, radius, foundEntities);
|
std::static_pointer_cast<EntityTree>(_tree)->findEntities(avatarPosition, radius, foundEntities);
|
||||||
|
|
||||||
|
// Whenever you're in an intersection between zones, we will always choose the smallest zone.
|
||||||
|
_bestZone = NULL; // NOTE: Is this what we want?
|
||||||
|
_bestZoneVolume = std::numeric_limits<float>::max();
|
||||||
|
|
||||||
// create a list of entities that actually contain the avatar's position
|
// create a list of entities that actually contain the avatar's position
|
||||||
foreach(EntityItemPointer entity, foundEntities) {
|
foreach(EntityItemPointer entity, foundEntities) {
|
||||||
if (entity->contains(avatarPosition)) {
|
if (entity->contains(avatarPosition)) {
|
||||||
entitiesContainingAvatar << entity->getEntityItemID();
|
entitiesContainingAvatar << entity->getEntityItemID();
|
||||||
|
|
||||||
|
// if this entity is a zone, use this time to determine the bestZone
|
||||||
|
if (entity->getType() == EntityTypes::Zone) {
|
||||||
|
float entityVolumeEstimate = entity->getVolumeEstimate();
|
||||||
|
if (entityVolumeEstimate < _bestZoneVolume) {
|
||||||
|
_bestZoneVolume = entityVolumeEstimate;
|
||||||
|
_bestZone = std::dynamic_pointer_cast<ZoneEntityItem>(entity);
|
||||||
|
} else if (entityVolumeEstimate == _bestZoneVolume) {
|
||||||
|
if (!_bestZone) {
|
||||||
|
_bestZoneVolume = entityVolumeEstimate;
|
||||||
|
_bestZone = std::dynamic_pointer_cast<ZoneEntityItem>(entity);
|
||||||
|
} else {
|
||||||
|
// in the case of the volume being equal, we will use the
|
||||||
|
// EntityItemID to deterministically pick one entity over the other
|
||||||
|
if (entity->getEntityItemID() < _bestZone->getEntityItemID()) {
|
||||||
|
_bestZoneVolume = entityVolumeEstimate;
|
||||||
|
_bestZone = std::dynamic_pointer_cast<ZoneEntityItem>(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
applyZonePropertiesToScene(_bestZone);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Note: at this point we don't need to worry about the tree being locked, because we only deal with
|
// Note: at this point we don't need to worry about the tree being locked, because we only deal with
|
||||||
|
@ -307,27 +336,6 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityTreeRenderer::render(RenderArgs* renderArgs) {
|
|
||||||
|
|
||||||
if (_tree && !_shuttingDown) {
|
|
||||||
renderArgs->_renderer = this;
|
|
||||||
_tree->withReadLock([&] {
|
|
||||||
// Whenever you're in an intersection between zones, we will always choose the smallest zone.
|
|
||||||
_bestZone = NULL; // NOTE: Is this what we want?
|
|
||||||
_bestZoneVolume = std::numeric_limits<float>::max();
|
|
||||||
|
|
||||||
// FIX ME: right now the renderOperation does the following:
|
|
||||||
// 1) determining the best zone (not really rendering)
|
|
||||||
// 2) render the debug cell details
|
|
||||||
// we should clean this up
|
|
||||||
_tree->recurseTreeWithOperation(renderOperation, renderArgs);
|
|
||||||
|
|
||||||
applyZonePropertiesToScene(_bestZone);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
deleteReleasedModels(); // seems like as good as any other place to do some memory cleanup
|
|
||||||
}
|
|
||||||
|
|
||||||
const FBXGeometry* EntityTreeRenderer::getGeometryForEntity(EntityItemPointer entityItem) {
|
const FBXGeometry* EntityTreeRenderer::getGeometryForEntity(EntityItemPointer entityItem) {
|
||||||
const FBXGeometry* result = NULL;
|
const FBXGeometry* result = NULL;
|
||||||
|
|
||||||
|
@ -372,121 +380,6 @@ const FBXGeometry* EntityTreeRenderer::getCollisionGeometryForEntity(EntityItemP
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityTreeRenderer::renderElementProxy(EntityTreeElementPointer entityTreeElement, RenderArgs* args) {
|
|
||||||
auto deferredLighting = DependencyManager::get<DeferredLightingEffect>();
|
|
||||||
Q_ASSERT(args->_batch);
|
|
||||||
gpu::Batch& batch = *args->_batch;
|
|
||||||
Transform transform;
|
|
||||||
|
|
||||||
glm::vec3 elementCenter = entityTreeElement->getAACube().calcCenter();
|
|
||||||
float elementSize = entityTreeElement->getScale();
|
|
||||||
|
|
||||||
auto drawWireCube = [&](glm::vec3 offset, float size, glm::vec4 color) {
|
|
||||||
transform.setTranslation(elementCenter + offset);
|
|
||||||
batch.setModelTransform(transform);
|
|
||||||
deferredLighting->renderWireCube(batch, size, color);
|
|
||||||
};
|
|
||||||
|
|
||||||
drawWireCube(glm::vec3(), elementSize, glm::vec4(1.0f, 0.0f, 0.0f, 1.0f));
|
|
||||||
|
|
||||||
if (_displayElementChildProxies) {
|
|
||||||
// draw the children
|
|
||||||
float halfSize = elementSize / 2.0f;
|
|
||||||
float quarterSize = elementSize / 4.0f;
|
|
||||||
|
|
||||||
drawWireCube(glm::vec3(-quarterSize, -quarterSize, -quarterSize), halfSize, glm::vec4(1.0f, 1.0f, 0.0f, 1.0f));
|
|
||||||
drawWireCube(glm::vec3(quarterSize, -quarterSize, -quarterSize), halfSize, glm::vec4(1.0f, 0.0f, 1.0f, 1.0f));
|
|
||||||
drawWireCube(glm::vec3(-quarterSize, quarterSize, -quarterSize), halfSize, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f));
|
|
||||||
drawWireCube(glm::vec3(-quarterSize, -quarterSize, quarterSize), halfSize, glm::vec4(0.0f, 0.0f, 1.0f, 1.0f));
|
|
||||||
drawWireCube(glm::vec3(quarterSize, quarterSize, quarterSize), halfSize, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));
|
|
||||||
drawWireCube(glm::vec3(-quarterSize, quarterSize, quarterSize), halfSize, glm::vec4(0.0f, 0.5f, 0.5f, 1.0f));
|
|
||||||
drawWireCube(glm::vec3(quarterSize, -quarterSize, quarterSize), halfSize, glm::vec4(0.5f, 0.0f, 0.0f, 1.0f));
|
|
||||||
drawWireCube(glm::vec3(quarterSize, quarterSize, -quarterSize), halfSize, glm::vec4(0.0f, 0.5f, 0.0f, 1.0f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EntityTreeRenderer::renderProxies(EntityItemPointer entity, RenderArgs* args) {
|
|
||||||
bool isShadowMode = args->_renderMode == RenderArgs::SHADOW_RENDER_MODE;
|
|
||||||
if (!isShadowMode && _displayModelBounds) {
|
|
||||||
PerformanceTimer perfTimer("renderProxies");
|
|
||||||
|
|
||||||
AACube maxCube = entity->getMaximumAACube();
|
|
||||||
AACube minCube = entity->getMinimumAACube();
|
|
||||||
AABox entityBox = entity->getAABox();
|
|
||||||
|
|
||||||
glm::vec3 maxCenter = maxCube.calcCenter();
|
|
||||||
glm::vec3 minCenter = minCube.calcCenter();
|
|
||||||
glm::vec3 entityBoxCenter = entityBox.calcCenter();
|
|
||||||
glm::vec3 entityBoxScale = entityBox.getScale();
|
|
||||||
|
|
||||||
auto deferredLighting = DependencyManager::get<DeferredLightingEffect>();
|
|
||||||
Q_ASSERT(args->_batch);
|
|
||||||
gpu::Batch& batch = *args->_batch;
|
|
||||||
Transform transform;
|
|
||||||
|
|
||||||
// draw the max bounding cube
|
|
||||||
transform.setTranslation(maxCenter);
|
|
||||||
batch.setModelTransform(transform);
|
|
||||||
deferredLighting->renderWireCube(batch, maxCube.getScale(), glm::vec4(1.0f, 1.0f, 0.0f, 1.0f));
|
|
||||||
|
|
||||||
// draw the min bounding cube
|
|
||||||
transform.setTranslation(minCenter);
|
|
||||||
batch.setModelTransform(transform);
|
|
||||||
deferredLighting->renderWireCube(batch, minCube.getScale(), glm::vec4(0.0f, 1.0f, 0.0f, 1.0f));
|
|
||||||
|
|
||||||
// draw the entityBox bounding box
|
|
||||||
transform.setTranslation(entityBoxCenter);
|
|
||||||
transform.setScale(entityBoxScale);
|
|
||||||
batch.setModelTransform(transform);
|
|
||||||
deferredLighting->renderWireCube(batch, 1.0f, glm::vec4(0.0f, 0.0f, 1.0f, 1.0f));
|
|
||||||
|
|
||||||
// Rotated bounding box
|
|
||||||
batch.setModelTransform(entity->getTransformToCenter());
|
|
||||||
deferredLighting->renderWireCube(batch, 1.0f, glm::vec4(1.0f, 0.0f, 1.0f, 1.0f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EntityTreeRenderer::renderElement(OctreeElementPointer element, RenderArgs* args) {
|
|
||||||
// actually render it here...
|
|
||||||
// we need to iterate the actual entityItems of the element
|
|
||||||
EntityTreeElementPointer entityTreeElement = std::static_pointer_cast<EntityTreeElement>(element);
|
|
||||||
|
|
||||||
|
|
||||||
bool isShadowMode = args->_renderMode == RenderArgs::SHADOW_RENDER_MODE;
|
|
||||||
|
|
||||||
if (!isShadowMode && _displayModelElementProxy && entityTreeElement->size() > 0) {
|
|
||||||
renderElementProxy(entityTreeElement, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
entityTreeElement->forEachEntity([&](EntityItemPointer entityItem) {
|
|
||||||
if (entityItem->isVisible()) {
|
|
||||||
// NOTE: Zone Entities are a special case we handle here...
|
|
||||||
if (entityItem->getType() == EntityTypes::Zone) {
|
|
||||||
if (entityItem->contains(_viewState->getAvatarPosition())) {
|
|
||||||
float entityVolumeEstimate = entityItem->getVolumeEstimate();
|
|
||||||
if (entityVolumeEstimate < _bestZoneVolume) {
|
|
||||||
_bestZoneVolume = entityVolumeEstimate;
|
|
||||||
_bestZone = std::dynamic_pointer_cast<ZoneEntityItem>(entityItem);
|
|
||||||
} else if (entityVolumeEstimate == _bestZoneVolume) {
|
|
||||||
if (!_bestZone) {
|
|
||||||
_bestZoneVolume = entityVolumeEstimate;
|
|
||||||
_bestZone = std::dynamic_pointer_cast<ZoneEntityItem>(entityItem);
|
|
||||||
} else {
|
|
||||||
// in the case of the volume being equal, we will use the
|
|
||||||
// EntityItemID to deterministically pick one entity over the other
|
|
||||||
if (entityItem->getEntityItemID() < _bestZone->getEntityItemID()) {
|
|
||||||
_bestZoneVolume = entityVolumeEstimate;
|
|
||||||
_bestZone = std::dynamic_pointer_cast<ZoneEntityItem>(entityItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
float EntityTreeRenderer::getSizeScale() const {
|
float EntityTreeRenderer::getSizeScale() const {
|
||||||
return _viewState->getSizeScale();
|
return _viewState->getSizeScale();
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,6 @@ public:
|
||||||
virtual char getMyNodeType() const { return NodeType::EntityServer; }
|
virtual char getMyNodeType() const { return NodeType::EntityServer; }
|
||||||
virtual PacketType getMyQueryMessageType() const { return PacketType::EntityQuery; }
|
virtual PacketType getMyQueryMessageType() const { return PacketType::EntityQuery; }
|
||||||
virtual PacketType getExpectedPacketType() const { return PacketType::EntityData; }
|
virtual PacketType getExpectedPacketType() const { return PacketType::EntityData; }
|
||||||
virtual void renderElement(OctreeElementPointer element, RenderArgs* args);
|
|
||||||
virtual float getSizeScale() const;
|
virtual float getSizeScale() const;
|
||||||
virtual int getBoundaryLevelAdjust() const;
|
virtual int getBoundaryLevelAdjust() const;
|
||||||
virtual void setTree(OctreePointer newTree);
|
virtual void setTree(OctreePointer newTree);
|
||||||
|
@ -53,7 +52,6 @@ public:
|
||||||
void processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode);
|
void processEraseMessage(NLPacket& packet, const SharedNodePointer& sourceNode);
|
||||||
|
|
||||||
virtual void init();
|
virtual void init();
|
||||||
virtual void render(RenderArgs* renderArgs) override;
|
|
||||||
|
|
||||||
virtual const FBXGeometry* getGeometryForEntity(EntityItemPointer entityItem);
|
virtual const FBXGeometry* getGeometryForEntity(EntityItemPointer entityItem);
|
||||||
virtual const Model* getModelForEntityItem(EntityItemPointer entityItem);
|
virtual const Model* getModelForEntityItem(EntityItemPointer entityItem);
|
||||||
|
@ -114,9 +112,7 @@ public slots:
|
||||||
void updateEntityRenderStatus(bool shouldRenderEntities);
|
void updateEntityRenderStatus(bool shouldRenderEntities);
|
||||||
|
|
||||||
// optional slots that can be wired to menu items
|
// optional slots that can be wired to menu items
|
||||||
void setDisplayElementChildProxies(bool value) { _displayElementChildProxies = value; }
|
|
||||||
void setDisplayModelBounds(bool value) { _displayModelBounds = value; }
|
void setDisplayModelBounds(bool value) { _displayModelBounds = value; }
|
||||||
void setDisplayModelElementProxy(bool value) { _displayModelElementProxy = value; }
|
|
||||||
void setDontDoPrecisionPicking(bool value) { _dontDoPrecisionPicking = value; }
|
void setDontDoPrecisionPicking(bool value) { _dontDoPrecisionPicking = value; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -130,11 +126,9 @@ private:
|
||||||
void addEntityToScene(EntityItemPointer entity);
|
void addEntityToScene(EntityItemPointer entity);
|
||||||
|
|
||||||
void applyZonePropertiesToScene(std::shared_ptr<ZoneEntityItem> zone);
|
void applyZonePropertiesToScene(std::shared_ptr<ZoneEntityItem> zone);
|
||||||
void renderElementProxy(EntityTreeElementPointer entityTreeElement, RenderArgs* args);
|
|
||||||
void checkAndCallPreload(const EntityItemID& entityID, const bool reload = false);
|
void checkAndCallPreload(const EntityItemID& entityID, const bool reload = false);
|
||||||
|
|
||||||
QList<Model*> _releasedModels;
|
QList<Model*> _releasedModels;
|
||||||
void renderProxies(EntityItemPointer entity, RenderArgs* args);
|
|
||||||
RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
|
RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
|
||||||
bool precisionPicking);
|
bool precisionPicking);
|
||||||
|
|
||||||
|
@ -157,9 +151,7 @@ private:
|
||||||
MouseEvent _lastMouseEvent;
|
MouseEvent _lastMouseEvent;
|
||||||
AbstractViewStateInterface* _viewState;
|
AbstractViewStateInterface* _viewState;
|
||||||
AbstractScriptingServicesInterface* _scriptingServices;
|
AbstractScriptingServicesInterface* _scriptingServices;
|
||||||
bool _displayElementChildProxies;
|
|
||||||
bool _displayModelBounds;
|
bool _displayModelBounds;
|
||||||
bool _displayModelElementProxy;
|
|
||||||
bool _dontDoPrecisionPicking;
|
bool _dontDoPrecisionPicking;
|
||||||
|
|
||||||
bool _shuttingDown = false;
|
bool _shuttingDown = false;
|
||||||
|
|
|
@ -358,8 +358,8 @@ bool RenderableModelEntityItem::needsToCallUpdate() const {
|
||||||
return _needsInitialSimulation || ModelEntityItem::needsToCallUpdate();
|
return _needsInitialSimulation || ModelEntityItem::needsToCallUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties RenderableModelEntityItem::getProperties() const {
|
EntityItemProperties RenderableModelEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
||||||
EntityItemProperties properties = ModelEntityItem::getProperties(); // get the properties from our base class
|
EntityItemProperties properties = ModelEntityItem::getProperties(desiredProperties); // get the properties from our base class
|
||||||
if (_originalTexturesRead) {
|
if (_originalTexturesRead) {
|
||||||
properties.setTextureNames(_originalTextures);
|
properties.setTextureNames(_originalTextures);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ public:
|
||||||
|
|
||||||
virtual ~RenderableModelEntityItem();
|
virtual ~RenderableModelEntityItem();
|
||||||
|
|
||||||
virtual EntityItemProperties getProperties() const;
|
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties);
|
virtual bool setProperties(const EntityItemProperties& properties);
|
||||||
virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||||
ReadBitstreamToTreeParams& args,
|
ReadBitstreamToTreeParams& args,
|
||||||
|
|
|
@ -32,14 +32,14 @@ AtmospherePropertyGroup::AtmospherePropertyGroup() {
|
||||||
_hasStars = true;
|
_hasStars = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtmospherePropertyGroup::copyToScriptValue(QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const {
|
void AtmospherePropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const {
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, atmosphere, Center, center);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ATMOSPHERE_CENTER, Atmosphere, atmosphere, Center, center);
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, atmosphere, InnerRadius, innerRadius);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ATMOSPHERE_INNER_RADIUS, Atmosphere, atmosphere, InnerRadius, innerRadius);
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, atmosphere, OuterRadius, outerRadius);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ATMOSPHERE_OUTER_RADIUS, Atmosphere, atmosphere, OuterRadius, outerRadius);
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, atmosphere, MieScattering, mieScattering);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ATMOSPHERE_MIE_SCATTERING, Atmosphere, atmosphere, MieScattering, mieScattering);
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, atmosphere, RayleighScattering, rayleighScattering);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ATMOSPHERE_RAYLEIGH_SCATTERING, Atmosphere, atmosphere, RayleighScattering, rayleighScattering);
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, atmosphere, ScatteringWavelengths, scatteringWavelengths);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ATMOSPHERE_SCATTERING_WAVELENGTHS, Atmosphere, atmosphere, ScatteringWavelengths, scatteringWavelengths);
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, atmosphere, HasStars, hasStars);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ATMOSPHERE_HAS_STARS, Atmosphere, atmosphere, HasStars, hasStars);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtmospherePropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) {
|
void AtmospherePropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) {
|
||||||
|
|
|
@ -53,7 +53,7 @@ public:
|
||||||
virtual ~AtmospherePropertyGroup() {}
|
virtual ~AtmospherePropertyGroup() {}
|
||||||
|
|
||||||
// EntityItemProperty related helpers
|
// EntityItemProperty related helpers
|
||||||
virtual void copyToScriptValue(QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const;
|
virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const;
|
||||||
virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings);
|
virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings);
|
||||||
virtual void debugDump() const;
|
virtual void debugDump() const;
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,8 @@ BoxEntityItem::BoxEntityItem(const EntityItemID& entityItemID, const EntityItemP
|
||||||
setProperties(properties);
|
setProperties(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties BoxEntityItem::getProperties() const {
|
EntityItemProperties BoxEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
||||||
EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
||||||
|
|
||||||
properties._color = getXColor();
|
properties._color = getXColor();
|
||||||
properties._colorChanged = false;
|
properties._colorChanged = false;
|
||||||
|
|
|
@ -23,7 +23,7 @@ public:
|
||||||
ALLOW_INSTANTIATION // This class can be instantiated
|
ALLOW_INSTANTIATION // This class can be instantiated
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties() const;
|
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties);
|
virtual bool setProperties(const EntityItemProperties& properties);
|
||||||
|
|
||||||
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
||||||
|
|
25
libraries/entities/src/EntitiesScriptEngineProvider.h
Normal file
25
libraries/entities/src/EntitiesScriptEngineProvider.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
//
|
||||||
|
// EntitiesScriptEngineProvider.h
|
||||||
|
// libraries/entities/src
|
||||||
|
//
|
||||||
|
// Created by Brad Hefta-Gaub on Sept. 18, 2015
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
// TODO: How will we handle collision callbacks with Entities
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_EntitiesScriptEngineProvider_h
|
||||||
|
#define hifi_EntitiesScriptEngineProvider_h
|
||||||
|
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include "EntityItemID.h"
|
||||||
|
|
||||||
|
class EntitiesScriptEngineProvider {
|
||||||
|
public:
|
||||||
|
virtual void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_EntitiesScriptEngineProvider_h
|
|
@ -1019,8 +1019,10 @@ quint64 EntityItem::getExpiry() const {
|
||||||
return _created + (quint64)(_lifetime * (float)USECS_PER_SECOND);
|
return _created + (quint64)(_lifetime * (float)USECS_PER_SECOND);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties EntityItem::getProperties() const {
|
EntityItemProperties EntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
||||||
EntityItemProperties properties;
|
EncodeBitstreamParams params; // unknown
|
||||||
|
EntityPropertyFlags propertyFlags = desiredProperties.isEmpty() ? getEntityProperties(params) : desiredProperties;
|
||||||
|
EntityItemProperties properties(propertyFlags);
|
||||||
properties._id = getID();
|
properties._id = getID();
|
||||||
properties._idSet = true;
|
properties._idSet = true;
|
||||||
properties._created = _created;
|
properties._created = _created;
|
||||||
|
|
|
@ -131,7 +131,7 @@ public:
|
||||||
EntityItemID getEntityItemID() const { return EntityItemID(_id); }
|
EntityItemID getEntityItemID() const { return EntityItemID(_id); }
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties() const;
|
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const;
|
||||||
|
|
||||||
/// returns true if something changed
|
/// returns true if something changed
|
||||||
virtual bool setProperties(const EntityItemProperties& properties);
|
virtual bool setProperties(const EntityItemProperties& properties);
|
||||||
|
|
|
@ -36,7 +36,7 @@ StagePropertyGroup EntityItemProperties::_staticStage;
|
||||||
|
|
||||||
EntityPropertyList PROP_LAST_ITEM = (EntityPropertyList)(PROP_AFTER_LAST_ITEM - 1);
|
EntityPropertyList PROP_LAST_ITEM = (EntityPropertyList)(PROP_AFTER_LAST_ITEM - 1);
|
||||||
|
|
||||||
EntityItemProperties::EntityItemProperties() :
|
EntityItemProperties::EntityItemProperties(EntityPropertyFlags desiredProperties) :
|
||||||
|
|
||||||
CONSTRUCT_PROPERTY(visible, ENTITY_ITEM_DEFAULT_VISIBLE),
|
CONSTRUCT_PROPERTY(visible, ENTITY_ITEM_DEFAULT_VISIBLE),
|
||||||
CONSTRUCT_PROPERTY(position, 0.0f),
|
CONSTRUCT_PROPERTY(position, 0.0f),
|
||||||
|
@ -147,7 +147,8 @@ _localRenderAlphaChanged(false),
|
||||||
|
|
||||||
_defaultSettings(true),
|
_defaultSettings(true),
|
||||||
_naturalDimensions(1.0f, 1.0f, 1.0f),
|
_naturalDimensions(1.0f, 1.0f, 1.0f),
|
||||||
_naturalPosition(0.0f, 0.0f, 0.0f)
|
_naturalPosition(0.0f, 0.0f, 0.0f),
|
||||||
|
_desiredProperties(desiredProperties)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,112 +438,164 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
EntityItemProperties defaultEntityProperties;
|
EntityItemProperties defaultEntityProperties;
|
||||||
|
|
||||||
if (_idSet) {
|
if (_idSet) {
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(id, _id.toString());
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_ALWAYS(id, _id.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(type, EntityTypes::getEntityTypeName(_type));
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_ALWAYS(type, EntityTypes::getEntityTypeName(_type));
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(position);
|
auto created = QDateTime::fromMSecsSinceEpoch(getCreated() / 1000.0f, Qt::UTC); // usec per msec
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(dimensions);
|
created.setTimeSpec(Qt::OffsetFromUTC);
|
||||||
if (!skipDefaults) {
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_ALWAYS(created, created.toString(Qt::ISODate));
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(naturalDimensions); // gettable, but not settable
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(naturalPosition);
|
|
||||||
}
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(rotation);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(velocity);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(gravity);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(acceleration);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(damping);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(restitution);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(friction);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(density);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(lifetime);
|
|
||||||
|
|
||||||
if (!skipDefaults || _lifetime != defaultEntityProperties._lifetime) {
|
if (!skipDefaults || _lifetime != defaultEntityProperties._lifetime) {
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(age, getAge()); // gettable, but not settable
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(age, getAge()); // gettable, but not settable
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(ageAsText, formatSecondsElapsed(getAge())); // gettable, but not settable
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(ageAsText, formatSecondsElapsed(getAge())); // gettable, but not settable
|
||||||
}
|
}
|
||||||
|
|
||||||
auto created = QDateTime::fromMSecsSinceEpoch(getCreated() / 1000.0f, Qt::UTC); // usec per msec
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_POSITION, position);
|
||||||
created.setTimeSpec(Qt::OffsetFromUTC);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DIMENSIONS, dimensions);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(created, created.toString(Qt::ISODate));
|
if (!skipDefaults) {
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DIMENSIONS, naturalDimensions); // gettable, but not settable
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_POSITION, naturalPosition);
|
||||||
|
}
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ROTATION, rotation);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VELOCITY, velocity);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAVITY, gravity);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ACCELERATION, acceleration);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DAMPING, damping);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_RESTITUTION, restitution);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FRICTION, friction);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DENSITY, density);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LIFETIME, lifetime);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SCRIPT, script);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SCRIPT_TIMESTAMP, scriptTimestamp);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_REGISTRATION_POINT, registrationPoint);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANGULAR_VELOCITY, angularVelocity);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANGULAR_DAMPING, angularDamping);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VISIBLE, visible);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_IGNORE_FOR_COLLISIONS, ignoreForCollisions);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLLISIONS_WILL_MOVE, collisionsWillMove);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_HREF, href);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DESCRIPTION, description);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FACE_CAMERA, faceCamera);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ACTION_DATA, actionData);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCKED, locked);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_USER_DATA, userData);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MARKETPLACE_ID, marketplaceID);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_NAME, name);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLLISION_SOUND_URL, collisionSoundURL);
|
||||||
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(script);
|
// Boxes, Spheres, Light, Line, Model(??), Particle, PolyLine
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(scriptTimestamp);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLOR, color);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(registrationPoint);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(angularVelocity);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(angularDamping);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(visible);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(color);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(colorSpread);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(colorStart);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(colorFinish);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(alpha);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(alphaSpread);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(alphaStart);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(alphaFinish);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(modelURL);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(compoundShapeURL);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(animationURL);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(animationIsPlaying);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(animationFPS);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(animationFrameIndex);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(animationSettings, getAnimationSettings());
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(glowLevel);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(localRenderAlpha);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(ignoreForCollisions);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(collisionsWillMove);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(isSpotlight);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(intensity);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(exponent);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(cutoff);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(locked);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(textures);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(userData);
|
|
||||||
//COPY_PROPERTY_TO_QSCRIPTVALUE(simulationOwner); // TODO: expose this for JSON saves?
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(text);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(lineHeight);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(textColor, getTextColor());
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(backgroundColor, getBackgroundColor());
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(shapeType, getShapeTypeAsString());
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(maxParticles);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(lifespan);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(emitRate);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(emitSpeed);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(speedSpread);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(emitOrientation);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(emitDimensions);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(emitRadiusStart);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(polarStart);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(polarFinish);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(azimuthStart);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(azimuthFinish);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(emitAcceleration);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(accelerationSpread);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(particleRadius);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(radiusSpread);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(radiusStart);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(radiusFinish);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(marketplaceID);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(name);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(collisionSoundURL);
|
|
||||||
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(keyLightColor);
|
// Particles only
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(keyLightIntensity);
|
if (_type == EntityTypes::ParticleEffect) {
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(keyLightAmbientIntensity);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MAX_PARTICLES, maxParticles);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(keyLightDirection);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LIFESPAN, lifespan);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(backgroundMode, getBackgroundModeAsString());
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EMIT_RATE, emitRate);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(sourceUrl);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EMIT_SPEED, emitSpeed);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(voxelVolumeSize);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SPEED_SPREAD, speedSpread);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(voxelData);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EMIT_ORIENTATION, emitOrientation);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(voxelSurfaceStyle);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EMIT_DIMENSIONS, emitDimensions);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(lineWidth);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EMIT_RADIUS_START, emitRadiusStart);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(linePoints);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_POLAR_START, polarStart);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(href);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_POLAR_FINISH, polarFinish);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(description);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_AZIMUTH_START, azimuthStart);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(faceCamera);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_AZIMUTH_FINISH, azimuthFinish);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(actionData);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EMIT_ACCELERATION, emitAcceleration);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(normals);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ACCELERATION_SPREAD, accelerationSpread);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(strokeWidths);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARTICLE_RADIUS, particleRadius);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_RADIUS_SPREAD, radiusSpread);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_RADIUS_START, radiusStart);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_RADIUS_FINISH, radiusFinish);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLOR_SPREAD, colorSpread);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLOR_START, colorStart);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLOR_FINISH, colorFinish);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA, alpha);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA_SPREAD, alphaSpread);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA_START, alphaStart);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA_FINISH, alphaFinish);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Models only
|
||||||
|
if (_type == EntityTypes::Model) {
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MODEL_URL, modelURL);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COMPOUND_SHAPE_URL, compoundShapeURL);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, animationURL);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (_type == EntityTypes::Model || _type == EntityTypes::Zone || _type == EntityTypes::ParticleEffect) {
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_SHAPE_TYPE, shapeType, getShapeTypeAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Models & Particles
|
||||||
|
if (_type == EntityTypes::Model || _type == EntityTypes::ParticleEffect) {
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_PLAYING, animationIsPlaying);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FPS, animationFPS);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, animationFrameIndex);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_SETTINGS, animationSettings, getAnimationSettings());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lights only
|
||||||
|
if (_type == EntityTypes::Light) {
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_IS_SPOTLIGHT, isSpotlight);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_INTENSITY, intensity);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EXPONENT, exponent);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CUTOFF, cutoff);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text only
|
||||||
|
if (_type == EntityTypes::Text) {
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXT, text);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_HEIGHT, lineHeight);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_TEXT_COLOR, textColor, getTextColor());
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_BACKGROUND_COLOR, backgroundColor, getBackgroundColor());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zones only
|
||||||
|
if (_type == EntityTypes::Zone) {
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_COLOR, keyLightColor);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_INTENSITY, keyLightIntensity);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_AMBIENT_INTENSITY, keyLightAmbientIntensity);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_DIRECTION, keyLightDirection);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_BACKGROUND_MODE, backgroundMode, getBackgroundModeAsString());
|
||||||
|
|
||||||
|
_stage.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
||||||
|
_atmosphere.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
||||||
|
_skybox.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Web only
|
||||||
|
if (_type == EntityTypes::Web) {
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SOURCE_URL, sourceUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PolyVoxel only
|
||||||
|
if (_type == EntityTypes::PolyVox) {
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VOXEL_VOLUME_SIZE, voxelVolumeSize);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VOXEL_DATA, voxelData);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VOXEL_SURFACE_STYLE, voxelSurfaceStyle);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_X_TEXTURE_URL, xTextureURL);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_Y_TEXTURE_URL, yTextureURL);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_Z_TEXTURE_URL, zTextureURL);
|
||||||
|
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_X_N_NEIGHBOR_ID, xNNeighborID);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_Y_N_NEIGHBOR_ID, yNNeighborID);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_Z_N_NEIGHBOR_ID, zNNeighborID);
|
||||||
|
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_X_P_NEIGHBOR_ID, xPNeighborID);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_Y_P_NEIGHBOR_ID, yPNeighborID);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_Z_P_NEIGHBOR_ID, zPNeighborID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lines & PolyLines
|
||||||
|
if (_type == EntityTypes::Line || _type == EntityTypes::PolyLine) {
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_WIDTH, lineWidth);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_POINTS, linePoints);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_NORMALS, normals);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STROKE_WIDTHS, strokeWidths);
|
||||||
|
}
|
||||||
|
|
||||||
// Sitting properties support
|
// Sitting properties support
|
||||||
if (!skipDefaults) {
|
if (!skipDefaults) {
|
||||||
|
@ -555,7 +608,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
sittingPoints.setProperty(i, sittingPoint);
|
sittingPoints.setProperty(i, sittingPoint);
|
||||||
}
|
}
|
||||||
sittingPoints.setProperty("length", _sittingPoints.size());
|
sittingPoints.setProperty("length", _sittingPoints.size());
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(sittingPoints, sittingPoints); // gettable, but not settable
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_ALWAYS(sittingPoints, sittingPoints); // gettable, but not settable
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!skipDefaults) {
|
if (!skipDefaults) {
|
||||||
|
@ -577,21 +630,9 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(originalTextures, textureNamesList); // gettable, but not settable
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(originalTextures, textureNamesList); // gettable, but not settable
|
||||||
}
|
}
|
||||||
|
|
||||||
_stage.copyToScriptValue(properties, engine, skipDefaults, defaultEntityProperties);
|
// FIXME - I don't think these properties are supported any more
|
||||||
_atmosphere.copyToScriptValue(properties, engine, skipDefaults, defaultEntityProperties);
|
//COPY_PROPERTY_TO_QSCRIPTVALUE(glowLevel);
|
||||||
_skybox.copyToScriptValue(properties, engine, skipDefaults, defaultEntityProperties);
|
//COPY_PROPERTY_TO_QSCRIPTVALUE(localRenderAlpha);
|
||||||
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(xTextureURL);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(yTextureURL);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(zTextureURL);
|
|
||||||
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(xNNeighborID);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(yNNeighborID);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(zNNeighborID);
|
|
||||||
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(xPNeighborID);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(yPNeighborID);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(zPNeighborID);
|
|
||||||
|
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
@ -737,6 +778,162 @@ void EntityItemPropertiesFromScriptValueHonorReadOnly(const QScriptValue &object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QScriptValue EntityPropertyFlagsToScriptValue(QScriptEngine* engine, const EntityPropertyFlags& flags) {
|
||||||
|
return EntityItemProperties::entityPropertyFlagsToScriptValue(engine, flags);
|
||||||
|
QScriptValue result = engine->newObject();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityPropertyFlagsFromScriptValue(const QScriptValue& object, EntityPropertyFlags& flags) {
|
||||||
|
EntityItemProperties::entityPropertyFlagsFromScriptValue(object, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QScriptValue EntityItemProperties::entityPropertyFlagsToScriptValue(QScriptEngine* engine, const EntityPropertyFlags& flags) {
|
||||||
|
QScriptValue result = engine->newObject();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QHash<QString, EntityPropertyList> _propertyStringsToEnums;
|
||||||
|
|
||||||
|
void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue& object, EntityPropertyFlags& flags) {
|
||||||
|
static std::once_flag initMap;
|
||||||
|
|
||||||
|
std::call_once(initMap, [](){
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_VISIBLE, Visible, visible, bool);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_POSITION, Position, position, glm::vec3);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_DIMENSIONS, Dimensions, dimensions, glm::vec3);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_ROTATION, Rotation, rotation, glm::quat);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_DENSITY, Density, density, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_VELOCITY, Velocity, velocity, glm::vec3);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_GRAVITY, Gravity, gravity, glm::vec3);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_ACCELERATION, Acceleration, acceleration, glm::vec3);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_DAMPING, Damping, damping, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_RESTITUTION, Restitution, restitution, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_FRICTION, Friction, friction, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_LIFETIME, Lifetime, lifetime, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_SCRIPT, Script, script, QString);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_SCRIPT_TIMESTAMP, ScriptTimestamp, scriptTimestamp, quint64);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_COLLISION_SOUND_URL, CollisionSoundURL, collisionSoundURL, QString);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_COLOR, Color, color, xColor);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_COLOR_SPREAD, ColorSpread, colorSpread, xColor);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_COLOR_START, ColorStart, colorStart, xColor);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_COLOR_FINISH, ColorFinish, colorFinish, xColor);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_ALPHA, Alpha, alpha, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_ALPHA_SPREAD, AlphaSpread, alphaSpread, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_ALPHA_START, AlphaStart, alphaStart, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_ALPHA_FINISH, AlphaFinish, alphaFinish, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_MODEL_URL, ModelURL, modelURL, QString);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_COMPOUND_SHAPE_URL, CompoundShapeURL, compoundShapeURL, QString);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_ANIMATION_URL, AnimationURL, animationURL, QString);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_ANIMATION_FPS, AnimationFPS, animationFPS, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_ANIMATION_FRAME_INDEX, AnimationFrameIndex, animationFrameIndex, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_ANIMATION_PLAYING, AnimationIsPlaying, animationIsPlaying, bool);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_REGISTRATION_POINT, RegistrationPoint, registrationPoint, glm::vec3);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_ANGULAR_VELOCITY, AngularVelocity, angularVelocity, glm::vec3);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_ANGULAR_DAMPING, AngularDamping, angularDamping, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_IGNORE_FOR_COLLISIONS, IgnoreForCollisions, ignoreForCollisions, bool);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_COLLISIONS_WILL_MOVE, CollisionsWillMove, collisionsWillMove, bool);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_IS_SPOTLIGHT, IsSpotlight, isSpotlight, bool);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_INTENSITY, Intensity, intensity, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_EXPONENT, Exponent, exponent, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_CUTOFF, Cutoff, cutoff, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_LOCKED, Locked, locked, bool);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_TEXTURES, Textures, textures, QString);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_ANIMATION_SETTINGS, AnimationSettings, animationSettings, QString);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_USER_DATA, UserData, userData, QString);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_SIMULATION_OWNER, SimulationOwner, simulationOwner, SimulationOwner);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_TEXT, Text, text, QString);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_LINE_HEIGHT, LineHeight, lineHeight, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_TEXT_COLOR, TextColor, textColor, xColor);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_BACKGROUND_COLOR, BackgroundColor, backgroundColor, xColor);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_SHAPE_TYPE, ShapeType, shapeType, ShapeType);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_MAX_PARTICLES, MaxParticles, maxParticles, quint32);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_LIFESPAN, Lifespan, lifespan, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_EMIT_RATE, EmitRate, emitRate, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_EMIT_SPEED, EmitSpeed, emitSpeed, glm::vec3);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_SPEED_SPREAD, SpeedSpread, speedSpread, glm::vec3);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_EMIT_ORIENTATION, EmitOrientation, emitOrientation, glm::quat);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_EMIT_DIMENSIONS, EmitDimensions, emitDimensions, glm::vec3);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_EMIT_RADIUS_START, EmitRadiusStart, emitRadiusStart, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_POLAR_START, EmitPolarStart, polarStart, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_POLAR_FINISH, EmitPolarFinish, polarFinish, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_AZIMUTH_START, EmitAzimuthStart, azimuthStart, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_AZIMUTH_FINISH, EmitAzimuthFinish, azimuthFinish, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_EMIT_ACCELERATION, EmitAcceleration, emitAcceleration, glm::vec3);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_ACCELERATION_SPREAD, AccelerationSpread, accelerationSpread, glm::vec3);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_PARTICLE_RADIUS, ParticleRadius, particleRadius, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_RADIUS_SPREAD, RadiusSpread, radiusSpread, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_RADIUS_START, RadiusStart, radiusStart, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_RADIUS_FINISH, RadiusFinish, radiusFinish, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_MARKETPLACE_ID, MarketplaceID, marketplaceID, QString);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_COLOR, KeyLightColor, keyLightColor, xColor);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_INTENSITY, KeyLightIntensity, keyLightIntensity, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_AMBIENT_INTENSITY, KeyLightAmbientIntensity, keyLightAmbientIntensity, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_DIRECTION, KeyLightDirection, keyLightDirection, glm::vec3);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_VOXEL_VOLUME_SIZE, VoxelVolumeSize, voxelVolumeSize, glm::vec3);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_VOXEL_DATA, VoxelData, voxelData, QByteArray);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_VOXEL_SURFACE_STYLE, VoxelSurfaceStyle, voxelSurfaceStyle, uint16_t);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_NAME, Name, name, QString);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_BACKGROUND_MODE, BackgroundMode, backgroundMode, BackgroundMode);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_SOURCE_URL, SourceUrl, sourceUrl, QString);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_LINE_WIDTH, LineWidth, lineWidth, float);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_LINE_POINTS, LinePoints, linePoints, QVector<glm::vec3>);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_HREF, Href, href, QString);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_DESCRIPTION, Description, description, QString);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_ACTION_DATA, ActionData, actionData, QByteArray);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_NORMALS, Normals, normals, QVector<glm::vec3>);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_STROKE_WIDTHS, StrokeWidths, strokeWidths, QVector<float>);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_Z_TEXTURE_URL, ZTextureURL, zTextureURL, QString);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_X_N_NEIGHBOR_ID, XNNeighborID, xNNeighborID, EntityItemID);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_Y_N_NEIGHBOR_ID, YNNeighborID, yNNeighborID, EntityItemID);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_Z_N_NEIGHBOR_ID, ZNNeighborID, zNNeighborID, EntityItemID);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_X_P_NEIGHBOR_ID, XPNeighborID, xPNeighborID, EntityItemID);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_Y_P_NEIGHBOR_ID, YPNeighborID, yPNeighborID, EntityItemID);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_Z_P_NEIGHBOR_ID, ZPNeighborID, zPNeighborID, EntityItemID);
|
||||||
|
|
||||||
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_SKYBOX_COLOR, Skybox, skybox, Color, color);
|
||||||
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_SKYBOX_URL, Skybox, skybox, URL, url);
|
||||||
|
|
||||||
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_ATMOSPHERE_CENTER, Atmosphere, atmosphere, Center, center);
|
||||||
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_ATMOSPHERE_INNER_RADIUS, Atmosphere, atmosphere, InnerRadius, innerRadius);
|
||||||
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_ATMOSPHERE_OUTER_RADIUS, Atmosphere, atmosphere, OuterRadius, outerRadius);
|
||||||
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_ATMOSPHERE_MIE_SCATTERING, Atmosphere, atmosphere, MieScattering, mieScattering);
|
||||||
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_ATMOSPHERE_RAYLEIGH_SCATTERING, Atmosphere, atmosphere, RayleighScattering, rayleighScattering);
|
||||||
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_ATMOSPHERE_SCATTERING_WAVELENGTHS, Atmosphere, atmosphere, ScatteringWavelengths, scatteringWavelengths);
|
||||||
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_ATMOSPHERE_HAS_STARS, Atmosphere, atmosphere, HasStars, hasStars);
|
||||||
|
|
||||||
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_STAGE_SUN_MODEL_ENABLED, Stage, stage, SunModelEnabled, sunModelEnabled);
|
||||||
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_STAGE_LATITUDE, Stage, stage, Latitude, latitude);
|
||||||
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_STAGE_LONGITUDE, Stage, stage, Longitude, longitude);
|
||||||
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_STAGE_ALTITUDE, Stage, stage, Altitude, altitude);
|
||||||
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_STAGE_DAY, Stage, stage, Day, day);
|
||||||
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_STAGE_HOUR, Stage, stage, Hour, hour);
|
||||||
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_STAGE_AUTOMATIC_HOURDAY, Stage, stage, AutomaticHourDay, automaticHourDay);
|
||||||
|
|
||||||
|
// FIXME - these are not yet handled
|
||||||
|
//ADD_PROPERTY_TO_MAP(PROP_CREATED, Created, created, quint64);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
if (object.isString()) {
|
||||||
|
if (_propertyStringsToEnums.contains(object.toString())) {
|
||||||
|
flags << _propertyStringsToEnums[object.toString()];
|
||||||
|
}
|
||||||
|
} else if (object.isArray()) {
|
||||||
|
quint32 length = object.property("length").toInt32();
|
||||||
|
for (quint32 i = 0; i < length; i++) {
|
||||||
|
QString propertyName = object.property(i).toString();
|
||||||
|
if (_propertyStringsToEnums.contains(propertyName)) {
|
||||||
|
flags << _propertyStringsToEnums[propertyName];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Implement support for edit packets that can span an MTU sized buffer. We need to implement a mechanism for the
|
// TODO: Implement support for edit packets that can span an MTU sized buffer. We need to implement a mechanism for the
|
||||||
// encodeEntityEditPacket() method to communicate the the caller which properties couldn't fit in the buffer. Similar
|
// encodeEntityEditPacket() method to communicate the the caller which properties couldn't fit in the buffer. Similar
|
||||||
// to how we handle this in the Octree streaming case.
|
// to how we handle this in the Octree streaming case.
|
||||||
|
|
|
@ -58,7 +58,7 @@ class EntityItemProperties {
|
||||||
friend class PolyVoxEntityItem; // TODO: consider removing this friend relationship and use public methods
|
friend class PolyVoxEntityItem; // TODO: consider removing this friend relationship and use public methods
|
||||||
friend class PolyLineEntityItem; // TODO: consider removing this friend relationship and use public methods
|
friend class PolyLineEntityItem; // TODO: consider removing this friend relationship and use public methods
|
||||||
public:
|
public:
|
||||||
EntityItemProperties();
|
EntityItemProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags());
|
||||||
virtual ~EntityItemProperties();
|
virtual ~EntityItemProperties();
|
||||||
|
|
||||||
EntityTypes::EntityType getType() const { return _type; }
|
EntityTypes::EntityType getType() const { return _type; }
|
||||||
|
@ -67,6 +67,9 @@ public:
|
||||||
virtual QScriptValue copyToScriptValue(QScriptEngine* engine, bool skipDefaults) const;
|
virtual QScriptValue copyToScriptValue(QScriptEngine* engine, bool skipDefaults) const;
|
||||||
virtual void copyFromScriptValue(const QScriptValue& object, bool honorReadOnly);
|
virtual void copyFromScriptValue(const QScriptValue& object, bool honorReadOnly);
|
||||||
|
|
||||||
|
static QScriptValue entityPropertyFlagsToScriptValue(QScriptEngine* engine, const EntityPropertyFlags& flags);
|
||||||
|
static void entityPropertyFlagsFromScriptValue(const QScriptValue& object, EntityPropertyFlags& flags);
|
||||||
|
|
||||||
// editing related features supported by all entities
|
// editing related features supported by all entities
|
||||||
quint64 getLastEdited() const { return _lastEdited; }
|
quint64 getLastEdited() const { return _lastEdited; }
|
||||||
float getEditedAgo() const /// Elapsed seconds since this entity was last edited
|
float getEditedAgo() const /// Elapsed seconds since this entity was last edited
|
||||||
|
@ -266,13 +269,19 @@ private:
|
||||||
QStringList _textureNames;
|
QStringList _textureNames;
|
||||||
glm::vec3 _naturalDimensions;
|
glm::vec3 _naturalDimensions;
|
||||||
glm::vec3 _naturalPosition;
|
glm::vec3 _naturalPosition;
|
||||||
|
|
||||||
|
EntityPropertyFlags _desiredProperties; // if set will narrow scopes of copy/to/from to just these properties
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(EntityItemProperties);
|
Q_DECLARE_METATYPE(EntityItemProperties);
|
||||||
QScriptValue EntityItemPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties);
|
QScriptValue EntityItemPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties);
|
||||||
QScriptValue EntityItemNonDefaultPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties);
|
QScriptValue EntityItemNonDefaultPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties);
|
||||||
void EntityItemPropertiesFromScriptValueIgnoreReadOnly(const QScriptValue &object, EntityItemProperties& properties);
|
void EntityItemPropertiesFromScriptValueIgnoreReadOnly(const QScriptValue& object, EntityItemProperties& properties);
|
||||||
void EntityItemPropertiesFromScriptValueHonorReadOnly(const QScriptValue &object, EntityItemProperties& properties);
|
void EntityItemPropertiesFromScriptValueHonorReadOnly(const QScriptValue& object, EntityItemProperties& properties);
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(EntityPropertyFlags);
|
||||||
|
QScriptValue EntityPropertyFlagsToScriptValue(QScriptEngine* engine, const EntityPropertyFlags& flags);
|
||||||
|
void EntityPropertyFlagsFromScriptValue(const QScriptValue& object, EntityPropertyFlags& flags);
|
||||||
|
|
||||||
|
|
||||||
// define these inline here so the macros work
|
// define these inline here so the macros work
|
||||||
|
|
|
@ -119,8 +119,9 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const QByteArray& v) {
|
||||||
inline QScriptValue convertScriptValue(QScriptEngine* e, const EntityItemID& v) { return QScriptValue(QUuid(v).toString()); }
|
inline QScriptValue convertScriptValue(QScriptEngine* e, const EntityItemID& v) { return QScriptValue(QUuid(v).toString()); }
|
||||||
|
|
||||||
|
|
||||||
#define COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(G,g,P,p) \
|
#define COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(X,G,g,P,p) \
|
||||||
if (!skipDefaults || defaultEntityProperties.get##G().get##P() != get##P()) { \
|
if ((desiredProperties.isEmpty() || desiredProperties.getHasProperty(X)) && \
|
||||||
|
(!skipDefaults || defaultEntityProperties.get##G().get##P() != get##P())) { \
|
||||||
QScriptValue groupProperties = properties.property(#g); \
|
QScriptValue groupProperties = properties.property(#g); \
|
||||||
if (!groupProperties.isValid()) { \
|
if (!groupProperties.isValid()) { \
|
||||||
groupProperties = engine->newObject(); \
|
groupProperties = engine->newObject(); \
|
||||||
|
@ -130,8 +131,9 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const EntityItemID& v)
|
||||||
properties.setProperty(#g, groupProperties); \
|
properties.setProperty(#g, groupProperties); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define COPY_PROPERTY_TO_QSCRIPTVALUE(P) \
|
#define COPY_PROPERTY_TO_QSCRIPTVALUE(p,P) \
|
||||||
if (!skipDefaults || defaultEntityProperties._##P != _##P) { \
|
if ((_desiredProperties.isEmpty() || _desiredProperties.getHasProperty(p)) && \
|
||||||
|
(!skipDefaults || defaultEntityProperties._##P != _##P)) { \
|
||||||
QScriptValue V = convertScriptValue(engine, _##P); \
|
QScriptValue V = convertScriptValue(engine, _##P); \
|
||||||
properties.setProperty(#P, V); \
|
properties.setProperty(#P, V); \
|
||||||
}
|
}
|
||||||
|
@ -139,7 +141,14 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const EntityItemID& v)
|
||||||
#define COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(P, G) \
|
#define COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(P, G) \
|
||||||
properties.setProperty(#P, G);
|
properties.setProperty(#P, G);
|
||||||
|
|
||||||
#define COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(P, G) \
|
#define COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(p, P, G) \
|
||||||
|
if ((_desiredProperties.isEmpty() || _desiredProperties.getHasProperty(p)) && \
|
||||||
|
(!skipDefaults || defaultEntityProperties._##P != _##P)) { \
|
||||||
|
QScriptValue V = convertScriptValue(engine, G); \
|
||||||
|
properties.setProperty(#P, V); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_ALWAYS(P, G) \
|
||||||
if (!skipDefaults || defaultEntityProperties._##P != _##P) { \
|
if (!skipDefaults || defaultEntityProperties._##P != _##P) { \
|
||||||
QScriptValue V = convertScriptValue(engine, G); \
|
QScriptValue V = convertScriptValue(engine, G); \
|
||||||
properties.setProperty(#P, V); \
|
properties.setProperty(#P, V); \
|
||||||
|
@ -304,6 +313,12 @@ inline xColor xColor_convertFromScriptValue(const QScriptValue& v, bool& isValid
|
||||||
T _##n; \
|
T _##n; \
|
||||||
static T _static##N;
|
static T _static##N;
|
||||||
|
|
||||||
|
#define ADD_PROPERTY_TO_MAP(P, N, n, T) \
|
||||||
|
_propertyStringsToEnums[#n] = P;
|
||||||
|
|
||||||
|
#define ADD_GROUP_PROPERTY_TO_MAP(P, G, g, N, n) \
|
||||||
|
_propertyStringsToEnums[#g "." #n] = P;
|
||||||
|
|
||||||
#define DEFINE_PROPERTY(P, N, n, T) \
|
#define DEFINE_PROPERTY(P, N, n, T) \
|
||||||
public: \
|
public: \
|
||||||
T get##N() const { return _##n; } \
|
T get##N() const { return _##n; } \
|
||||||
|
|
|
@ -12,33 +12,8 @@
|
||||||
#ifndef hifi_EntityPropertyFlags_h
|
#ifndef hifi_EntityPropertyFlags_h
|
||||||
#define hifi_EntityPropertyFlags_h
|
#define hifi_EntityPropertyFlags_h
|
||||||
|
|
||||||
/*
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <glm/gtx/extented_min_max.hpp>
|
|
||||||
|
|
||||||
#include <QtScript/QScriptEngine>
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QVector>
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
#include <AACube.h>
|
|
||||||
#include <FBXReader.h> // for SittingPoint
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <PropertyFlags.h>
|
#include <PropertyFlags.h>
|
||||||
|
|
||||||
/*
|
|
||||||
#include <OctreeConstants.h>
|
|
||||||
#include <ShapeInfo.h>
|
|
||||||
|
|
||||||
#include "AtmospherePropertyGroup.h"
|
|
||||||
#include "EntityItemID.h"
|
|
||||||
#include "EntityItemPropertiesMacros.h"
|
|
||||||
#include "EntityTypes.h"
|
|
||||||
*/
|
|
||||||
|
|
||||||
enum EntityPropertyList {
|
enum EntityPropertyList {
|
||||||
PROP_PAGED_PROPERTY,
|
PROP_PAGED_PROPERTY,
|
||||||
PROP_CUSTOM_PROPERTIES_INCLUDED,
|
PROP_CUSTOM_PROPERTIES_INCLUDED,
|
||||||
|
@ -197,6 +172,7 @@ enum EntityPropertyList {
|
||||||
PROP_STAGE_ALTITUDE = PROP_SPECULAR_COLOR_UNUSED,
|
PROP_STAGE_ALTITUDE = PROP_SPECULAR_COLOR_UNUSED,
|
||||||
PROP_STAGE_DAY = PROP_LINEAR_ATTENUATION_UNUSED,
|
PROP_STAGE_DAY = PROP_LINEAR_ATTENUATION_UNUSED,
|
||||||
PROP_STAGE_HOUR = PROP_QUADRATIC_ATTENUATION_UNUSED,
|
PROP_STAGE_HOUR = PROP_QUADRATIC_ATTENUATION_UNUSED,
|
||||||
|
PROP_STAGE_AUTOMATIC_HOURDAY = PROP_ANIMATION_FRAME_INDEX,
|
||||||
PROP_ATMOSPHERE_CENTER = PROP_MAX_PARTICLES,
|
PROP_ATMOSPHERE_CENTER = PROP_MAX_PARTICLES,
|
||||||
PROP_ATMOSPHERE_INNER_RADIUS = PROP_LIFESPAN,
|
PROP_ATMOSPHERE_INNER_RADIUS = PROP_LIFESPAN,
|
||||||
PROP_ATMOSPHERE_OUTER_RADIUS = PROP_EMIT_RATE,
|
PROP_ATMOSPHERE_OUTER_RADIUS = PROP_EMIT_RATE,
|
||||||
|
@ -207,7 +183,6 @@ enum EntityPropertyList {
|
||||||
PROP_BACKGROUND_MODE = PROP_MODEL_URL,
|
PROP_BACKGROUND_MODE = PROP_MODEL_URL,
|
||||||
PROP_SKYBOX_COLOR = PROP_ANIMATION_URL,
|
PROP_SKYBOX_COLOR = PROP_ANIMATION_URL,
|
||||||
PROP_SKYBOX_URL = PROP_ANIMATION_FPS,
|
PROP_SKYBOX_URL = PROP_ANIMATION_FPS,
|
||||||
PROP_STAGE_AUTOMATIC_HOURDAY = PROP_ANIMATION_FRAME_INDEX,
|
|
||||||
|
|
||||||
// Aliases/Piggyback properties for Web. These properties intentionally reuse the enum values for
|
// Aliases/Piggyback properties for Web. These properties intentionally reuse the enum values for
|
||||||
// other properties which will never overlap with each other.
|
// other properties which will never overlap with each other.
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include "EntityScriptingInterface.h"
|
#include "EntityScriptingInterface.h"
|
||||||
|
|
||||||
|
#include "EntityItemID.h"
|
||||||
#include <VariantMapToScriptValue.h>
|
#include <VariantMapToScriptValue.h>
|
||||||
|
|
||||||
#include "EntitiesLogging.h"
|
#include "EntitiesLogging.h"
|
||||||
|
@ -100,12 +101,17 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identity) {
|
EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identity) {
|
||||||
|
EntityPropertyFlags noSpecificProperties;
|
||||||
|
return getEntityProperties(identity, noSpecificProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identity, EntityPropertyFlags desiredProperties) {
|
||||||
EntityItemProperties results;
|
EntityItemProperties results;
|
||||||
if (_entityTree) {
|
if (_entityTree) {
|
||||||
_entityTree->withReadLock([&] {
|
_entityTree->withReadLock([&] {
|
||||||
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(identity));
|
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(identity));
|
||||||
if (entity) {
|
if (entity) {
|
||||||
results = entity->getProperties();
|
results = entity->getProperties(desiredProperties);
|
||||||
|
|
||||||
// TODO: improve sitting points and naturalDimensions in the future,
|
// TODO: improve sitting points and naturalDimensions in the future,
|
||||||
// for now we've included the old sitting points model behavior for entity types that are models
|
// for now we've included the old sitting points model behavior for entity types that are models
|
||||||
|
@ -211,6 +217,14 @@ void EntityScriptingInterface::deleteEntity(QUuid id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityScriptingInterface::callEntityMethod(QUuid id, const QString& method) {
|
||||||
|
if (_entitiesScriptEngine) {
|
||||||
|
EntityItemID entityID{ id };
|
||||||
|
_entitiesScriptEngine->callEntityScriptMethod(entityID, method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QUuid EntityScriptingInterface::findClosestEntity(const glm::vec3& center, float radius) const {
|
QUuid EntityScriptingInterface::findClosestEntity(const glm::vec3& center, float radius) const {
|
||||||
EntityItemID result;
|
EntityItemID result;
|
||||||
if (_entityTree) {
|
if (_entityTree) {
|
||||||
|
|
|
@ -20,18 +20,19 @@
|
||||||
#include <Octree.h>
|
#include <Octree.h>
|
||||||
#include <OctreeScriptingInterface.h>
|
#include <OctreeScriptingInterface.h>
|
||||||
#include <RegisteredMetaTypes.h>
|
#include <RegisteredMetaTypes.h>
|
||||||
|
|
||||||
#include "PolyVoxEntityItem.h"
|
#include "PolyVoxEntityItem.h"
|
||||||
#include "LineEntityItem.h"
|
#include "LineEntityItem.h"
|
||||||
#include "PolyLineEntityItem.h"
|
#include "PolyLineEntityItem.h"
|
||||||
#include "EntityTree.h"
|
#include "EntityTree.h"
|
||||||
|
|
||||||
#include "EntityEditPacketSender.h"
|
#include "EntityEditPacketSender.h"
|
||||||
|
#include "EntitiesScriptEngineProvider.h"
|
||||||
|
|
||||||
|
|
||||||
class EntityTree;
|
class EntityTree;
|
||||||
class MouseEvent;
|
class MouseEvent;
|
||||||
|
|
||||||
|
|
||||||
class RayToEntityIntersectionResult {
|
class RayToEntityIntersectionResult {
|
||||||
public:
|
public:
|
||||||
RayToEntityIntersectionResult();
|
RayToEntityIntersectionResult();
|
||||||
|
@ -63,6 +64,7 @@ public:
|
||||||
|
|
||||||
void setEntityTree(EntityTreePointer modelTree);
|
void setEntityTree(EntityTreePointer modelTree);
|
||||||
EntityTreePointer getEntityTree() { return _entityTree; }
|
EntityTreePointer getEntityTree() { return _entityTree; }
|
||||||
|
void setEntitiesScriptEngine(EntitiesScriptEngineProvider* engine) { _entitiesScriptEngine = engine; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
|
@ -78,6 +80,7 @@ public slots:
|
||||||
/// gets the current model properties for a specific model
|
/// gets the current model properties for a specific model
|
||||||
/// this function will not find return results in script engine contexts which don't have access to models
|
/// this function will not find return results in script engine contexts which don't have access to models
|
||||||
Q_INVOKABLE EntityItemProperties getEntityProperties(QUuid entityID);
|
Q_INVOKABLE EntityItemProperties getEntityProperties(QUuid entityID);
|
||||||
|
Q_INVOKABLE EntityItemProperties getEntityProperties(QUuid identity, EntityPropertyFlags desiredProperties);
|
||||||
|
|
||||||
/// edits a model updating only the included properties, will return the identified EntityItemID in case of
|
/// edits a model updating only the included properties, will return the identified EntityItemID in case of
|
||||||
/// successful edit, if the input entityID is for an unknown model this function will have no effect
|
/// successful edit, if the input entityID is for an unknown model this function will have no effect
|
||||||
|
@ -86,6 +89,11 @@ public slots:
|
||||||
/// deletes a model
|
/// deletes a model
|
||||||
Q_INVOKABLE void deleteEntity(QUuid entityID);
|
Q_INVOKABLE void deleteEntity(QUuid entityID);
|
||||||
|
|
||||||
|
/// Allows a script to call a method on an entity's script. The method will execute in the entity script
|
||||||
|
/// engine. If the entity does not have an entity script or the method does not exist, this call will have
|
||||||
|
/// no effect.
|
||||||
|
Q_INVOKABLE void callEntityMethod(QUuid entityID, const QString& method);
|
||||||
|
|
||||||
/// finds the closest model to the center point, within the radius
|
/// finds the closest model to the center point, within the radius
|
||||||
/// will return a EntityItemID.isKnownID = false if no models are in the radius
|
/// will return a EntityItemID.isKnownID = false if no models are in the radius
|
||||||
/// this function will not find any models in script engine contexts which don't have access to models
|
/// this function will not find any models in script engine contexts which don't have access to models
|
||||||
|
@ -180,6 +188,7 @@ private:
|
||||||
bool precisionPicking);
|
bool precisionPicking);
|
||||||
|
|
||||||
EntityTreePointer _entityTree;
|
EntityTreePointer _entityTree;
|
||||||
|
EntitiesScriptEngineProvider* _entitiesScriptEngine = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_EntityScriptingInterface_h
|
#endif // hifi_EntityScriptingInterface_h
|
||||||
|
|
|
@ -56,8 +56,8 @@ void LightEntityItem::setDimensions(const glm::vec3& value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EntityItemProperties LightEntityItem::getProperties() const {
|
EntityItemProperties LightEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
||||||
EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
||||||
|
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(isSpotlight, getIsSpotlight);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(isSpotlight, getIsSpotlight);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor);
|
||||||
|
|
|
@ -26,7 +26,7 @@ public:
|
||||||
virtual void setDimensions(const glm::vec3& value);
|
virtual void setDimensions(const glm::vec3& value);
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties() const;
|
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties);
|
virtual bool setProperties(const EntityItemProperties& properties);
|
||||||
|
|
||||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;
|
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;
|
||||||
|
|
|
@ -43,9 +43,9 @@ LineEntityItem::LineEntityItem(const EntityItemID& entityItemID, const EntityIte
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties LineEntityItem::getProperties() const {
|
EntityItemProperties LineEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
||||||
|
|
||||||
EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
||||||
|
|
||||||
|
|
||||||
properties._color = getXColor();
|
properties._color = getXColor();
|
||||||
|
|
|
@ -23,7 +23,7 @@ class LineEntityItem : public EntityItem {
|
||||||
ALLOW_INSTANTIATION // This class can be instantiated
|
ALLOW_INSTANTIATION // This class can be instantiated
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties() const;
|
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties);
|
virtual bool setProperties(const EntityItemProperties& properties);
|
||||||
|
|
||||||
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
||||||
|
|
|
@ -43,8 +43,8 @@ ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID, const EntityI
|
||||||
_color[0] = _color[1] = _color[2] = 0;
|
_color[0] = _color[1] = _color[2] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties ModelEntityItem::getProperties() const {
|
EntityItemProperties ModelEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
||||||
EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
||||||
|
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(modelURL, getModelURL);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(modelURL, getModelURL);
|
||||||
|
|
|
@ -25,7 +25,7 @@ public:
|
||||||
ALLOW_INSTANTIATION // This class can be instantiated
|
ALLOW_INSTANTIATION // This class can be instantiated
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties() const;
|
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties);
|
virtual bool setProperties(const EntityItemProperties& properties);
|
||||||
|
|
||||||
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
||||||
|
|
|
@ -163,8 +163,8 @@ void ParticleEffectEntityItem::computeAndUpdateDimensions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EntityItemProperties ParticleEffectEntityItem::getProperties() const {
|
EntityItemProperties ParticleEffectEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
||||||
EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
||||||
|
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha);
|
||||||
|
|
|
@ -25,7 +25,7 @@ public:
|
||||||
ALLOW_INSTANTIATION // This class can be instantiated
|
ALLOW_INSTANTIATION // This class can be instantiated
|
||||||
|
|
||||||
// methods for getting/setting all properties of this entity
|
// methods for getting/setting all properties of this entity
|
||||||
virtual EntityItemProperties getProperties() const;
|
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties);
|
virtual bool setProperties(const EntityItemProperties& properties);
|
||||||
|
|
||||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;
|
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;
|
||||||
|
|
|
@ -45,9 +45,9 @@ _strokeWidths(QVector<float>(0.0f))
|
||||||
setProperties(properties);
|
setProperties(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties PolyLineEntityItem::getProperties() const {
|
EntityItemProperties PolyLineEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
||||||
QWriteLocker lock(&_quadReadWriteLock);
|
QWriteLocker lock(&_quadReadWriteLock);
|
||||||
EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
||||||
|
|
||||||
|
|
||||||
properties._color = getXColor();
|
properties._color = getXColor();
|
||||||
|
|
|
@ -23,7 +23,7 @@ class PolyLineEntityItem : public EntityItem {
|
||||||
ALLOW_INSTANTIATION // This class can be instantiated
|
ALLOW_INSTANTIATION // This class can be instantiated
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties() const;
|
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties);
|
virtual bool setProperties(const EntityItemProperties& properties);
|
||||||
|
|
||||||
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
||||||
|
|
|
@ -104,8 +104,8 @@ const glm::vec3& PolyVoxEntityItem::getVoxelVolumeSize() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EntityItemProperties PolyVoxEntityItem::getProperties() const {
|
EntityItemProperties PolyVoxEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
||||||
EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(voxelVolumeSize, getVoxelVolumeSize);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(voxelVolumeSize, getVoxelVolumeSize);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(voxelData, getVoxelData);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(voxelData, getVoxelData);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(voxelSurfaceStyle, getVoxelSurfaceStyle);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(voxelSurfaceStyle, getVoxelSurfaceStyle);
|
||||||
|
|
|
@ -23,7 +23,7 @@ class PolyVoxEntityItem : public EntityItem {
|
||||||
ALLOW_INSTANTIATION // This class can be instantiated
|
ALLOW_INSTANTIATION // This class can be instantiated
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties() const;
|
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties);
|
virtual bool setProperties(const EntityItemProperties& properties);
|
||||||
|
|
||||||
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
||||||
|
|
|
@ -55,7 +55,7 @@ public:
|
||||||
virtual ~PropertyGroup() {}
|
virtual ~PropertyGroup() {}
|
||||||
|
|
||||||
// EntityItemProperty related helpers
|
// EntityItemProperty related helpers
|
||||||
virtual void copyToScriptValue(QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const = 0;
|
virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const = 0;
|
||||||
virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) = 0;
|
virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) = 0;
|
||||||
virtual void debugDump() const { }
|
virtual void debugDump() const { }
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,9 @@ SkyboxPropertyGroup::SkyboxPropertyGroup() {
|
||||||
_url = QString();
|
_url = QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkyboxPropertyGroup::copyToScriptValue(QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const {
|
void SkyboxPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const {
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Skybox, skybox, Color, color);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_SKYBOX_COLOR, Skybox, skybox, Color, color);
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Skybox, skybox, URL, url);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_SKYBOX_URL, Skybox, skybox, URL, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkyboxPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) {
|
void SkyboxPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) {
|
||||||
|
|
|
@ -33,7 +33,7 @@ public:
|
||||||
virtual ~SkyboxPropertyGroup() {}
|
virtual ~SkyboxPropertyGroup() {}
|
||||||
|
|
||||||
// EntityItemProperty related helpers
|
// EntityItemProperty related helpers
|
||||||
virtual void copyToScriptValue(QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const;
|
virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const;
|
||||||
virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings);
|
virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings);
|
||||||
virtual void debugDump() const;
|
virtual void debugDump() const;
|
||||||
|
|
||||||
|
|
|
@ -37,8 +37,8 @@ SphereEntityItem::SphereEntityItem(const EntityItemID& entityItemID, const Entit
|
||||||
_volumeMultiplier *= PI / 6.0f;
|
_volumeMultiplier *= PI / 6.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties SphereEntityItem::getProperties() const {
|
EntityItemProperties SphereEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
||||||
EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
||||||
properties.setColor(getXColor());
|
properties.setColor(getXColor());
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ public:
|
||||||
ALLOW_INSTANTIATION // This class can be instantiated
|
ALLOW_INSTANTIATION // This class can be instantiated
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties() const;
|
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties);
|
virtual bool setProperties(const EntityItemProperties& properties);
|
||||||
|
|
||||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;
|
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;
|
||||||
|
|
|
@ -36,14 +36,14 @@ StagePropertyGroup::StagePropertyGroup() {
|
||||||
_automaticHourDay = false;
|
_automaticHourDay = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StagePropertyGroup::copyToScriptValue(QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const {
|
void StagePropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const {
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Stage, stage, SunModelEnabled, sunModelEnabled);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_STAGE_SUN_MODEL_ENABLED, Stage, stage, SunModelEnabled, sunModelEnabled);
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Stage, stage, Latitude, latitude);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_STAGE_LATITUDE, Stage, stage, Latitude, latitude);
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Stage, stage, Longitude, longitude);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_STAGE_LONGITUDE, Stage, stage, Longitude, longitude);
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Stage, stage, Altitude, altitude);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_STAGE_ALTITUDE, Stage, stage, Altitude, altitude);
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Stage, stage, Day, day);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_STAGE_DAY, Stage, stage, Day, day);
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Stage, stage, Hour, hour);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_STAGE_HOUR, Stage, stage, Hour, hour);
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Stage, stage, AutomaticHourDay, automaticHourDay);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_STAGE_AUTOMATIC_HOURDAY, Stage, stage, AutomaticHourDay, automaticHourDay);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StagePropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) {
|
void StagePropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) {
|
||||||
|
|
|
@ -33,7 +33,7 @@ public:
|
||||||
virtual ~StagePropertyGroup() {}
|
virtual ~StagePropertyGroup() {}
|
||||||
|
|
||||||
// EntityItemProperty related helpers
|
// EntityItemProperty related helpers
|
||||||
virtual void copyToScriptValue(QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const;
|
virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const;
|
||||||
virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings);
|
virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings);
|
||||||
virtual void debugDump() const;
|
virtual void debugDump() const;
|
||||||
|
|
||||||
|
|
|
@ -47,8 +47,8 @@ void TextEntityItem::setDimensions(const glm::vec3& value) {
|
||||||
EntityItem::setDimensions(glm::vec3(value.x, value.y, TEXT_ENTITY_ITEM_FIXED_DEPTH));
|
EntityItem::setDimensions(glm::vec3(value.x, value.y, TEXT_ENTITY_ITEM_FIXED_DEPTH));
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties TextEntityItem::getProperties() const {
|
EntityItemProperties TextEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
||||||
EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
||||||
|
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(text, getText);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(text, getText);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineHeight, getLineHeight);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineHeight, getLineHeight);
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
virtual ShapeType getShapeType() const { return SHAPE_TYPE_BOX; }
|
virtual ShapeType getShapeType() const { return SHAPE_TYPE_BOX; }
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties() const;
|
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties);
|
virtual bool setProperties(const EntityItemProperties& properties);
|
||||||
|
|
||||||
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
||||||
|
|
|
@ -40,8 +40,8 @@ void WebEntityItem::setDimensions(const glm::vec3& value) {
|
||||||
EntityItem::setDimensions(glm::vec3(value.x, value.y, WEB_ENTITY_ITEM_FIXED_DEPTH));
|
EntityItem::setDimensions(glm::vec3(value.x, value.y, WEB_ENTITY_ITEM_FIXED_DEPTH));
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties WebEntityItem::getProperties() const {
|
EntityItemProperties WebEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
||||||
EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(sourceUrl, getSourceUrl);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(sourceUrl, getSourceUrl);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ public:
|
||||||
virtual ShapeType getShapeType() const { return SHAPE_TYPE_BOX; }
|
virtual ShapeType getShapeType() const { return SHAPE_TYPE_BOX; }
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties() const;
|
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties);
|
virtual bool setProperties(const EntityItemProperties& properties);
|
||||||
|
|
||||||
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
||||||
|
|
|
@ -73,8 +73,8 @@ EnvironmentData ZoneEntityItem::getEnvironmentData() const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties ZoneEntityItem::getProperties() const {
|
EntityItemProperties ZoneEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
||||||
EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class
|
EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class
|
||||||
|
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(keyLightColor, getKeyLightColor);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(keyLightColor, getKeyLightColor);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(keyLightIntensity, getKeyLightIntensity);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(keyLightIntensity, getKeyLightIntensity);
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
ALLOW_INSTANTIATION // This class can be instantiated
|
ALLOW_INSTANTIATION // This class can be instantiated
|
||||||
|
|
||||||
// methods for getting/setting all properties of an entity
|
// methods for getting/setting all properties of an entity
|
||||||
virtual EntityItemProperties getProperties() const;
|
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const;
|
||||||
virtual bool setProperties(const EntityItemProperties& properties);
|
virtual bool setProperties(const EntityItemProperties& properties);
|
||||||
|
|
||||||
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
||||||
|
|
|
@ -42,7 +42,7 @@ const unsigned int GRIP_BUTTON = 1U << 2;
|
||||||
const unsigned int TRACKPAD_BUTTON = 1U << 3;
|
const unsigned int TRACKPAD_BUTTON = 1U << 3;
|
||||||
const unsigned int TRIGGER_BUTTON = 1U << 4;
|
const unsigned int TRIGGER_BUTTON = 1U << 4;
|
||||||
|
|
||||||
const float CONTROLLER_LENGTH_OFFSET = 0.175f;
|
const float CONTROLLER_LENGTH_OFFSET = 0.0762f; // three inches
|
||||||
const QString CONTROLLER_MODEL_STRING = "vr_controller_05_wireless_b";
|
const QString CONTROLLER_MODEL_STRING = "vr_controller_05_wireless_b";
|
||||||
|
|
||||||
const QString ViveControllerManager::NAME = "OpenVR";
|
const QString ViveControllerManager::NAME = "OpenVR";
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
virtual char getMyNodeType() const = 0;
|
virtual char getMyNodeType() const = 0;
|
||||||
virtual PacketType getMyQueryMessageType() const = 0;
|
virtual PacketType getMyQueryMessageType() const = 0;
|
||||||
virtual PacketType getExpectedPacketType() const = 0;
|
virtual PacketType getExpectedPacketType() const = 0;
|
||||||
virtual void renderElement(OctreeElementPointer element, RenderArgs* args) = 0;
|
virtual void renderElement(OctreeElementPointer element, RenderArgs* args) { }
|
||||||
virtual float getSizeScale() const { return DEFAULT_OCTREE_SIZE_SCALE; }
|
virtual float getSizeScale() const { return DEFAULT_OCTREE_SIZE_SCALE; }
|
||||||
virtual int getBoundaryLevelAdjust() const { return 0; }
|
virtual int getBoundaryLevelAdjust() const { return 0; }
|
||||||
|
|
||||||
|
|
|
@ -280,6 +280,7 @@ void ScriptEngine::init() {
|
||||||
_controllerScriptingInterface->registerControllerTypes(this);
|
_controllerScriptingInterface->registerControllerTypes(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qScriptRegisterMetaType(this, EntityPropertyFlagsToScriptValue, EntityPropertyFlagsFromScriptValue);
|
||||||
qScriptRegisterMetaType(this, EntityItemPropertiesToScriptValue, EntityItemPropertiesFromScriptValueHonorReadOnly);
|
qScriptRegisterMetaType(this, EntityItemPropertiesToScriptValue, EntityItemPropertiesFromScriptValueHonorReadOnly);
|
||||||
qScriptRegisterMetaType(this, EntityItemIDtoScriptValue, EntityItemIDfromScriptValue);
|
qScriptRegisterMetaType(this, EntityItemIDtoScriptValue, EntityItemIDfromScriptValue);
|
||||||
qScriptRegisterMetaType(this, RayToEntityIntersectionResultToScriptValue, RayToEntityIntersectionResultFromScriptValue);
|
qScriptRegisterMetaType(this, RayToEntityIntersectionResultToScriptValue, RayToEntityIntersectionResultFromScriptValue);
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <AvatarHashMap.h>
|
#include <AvatarHashMap.h>
|
||||||
#include <LimitedNodeList.h>
|
#include <LimitedNodeList.h>
|
||||||
#include <EntityItemID.h>
|
#include <EntityItemID.h>
|
||||||
|
#include <EntitiesScriptEngineProvider.h>
|
||||||
|
|
||||||
#include "AbstractControllerScriptingInterface.h"
|
#include "AbstractControllerScriptingInterface.h"
|
||||||
#include "ArrayBufferClass.h"
|
#include "ArrayBufferClass.h"
|
||||||
|
@ -46,7 +47,7 @@ public:
|
||||||
QScriptValue scriptObject;
|
QScriptValue scriptObject;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ScriptEngine : public QScriptEngine, public ScriptUser {
|
class ScriptEngine : public QScriptEngine, public ScriptUser, public EntitiesScriptEngineProvider {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ScriptEngine(const QString& scriptContents = NO_SCRIPT,
|
ScriptEngine(const QString& scriptContents = NO_SCRIPT,
|
||||||
|
|
|
@ -45,6 +45,7 @@ public:
|
||||||
_maxFlag(INT_MIN), _minFlag(INT_MAX), _trailingFlipped(false), _encodedLength(0) { decode(fromEncoded); }
|
_maxFlag(INT_MIN), _minFlag(INT_MAX), _trailingFlipped(false), _encodedLength(0) { decode(fromEncoded); }
|
||||||
|
|
||||||
void clear() { _flags.clear(); _maxFlag = INT_MIN; _minFlag = INT_MAX; _trailingFlipped = false; _encodedLength = 0; }
|
void clear() { _flags.clear(); _maxFlag = INT_MIN; _minFlag = INT_MAX; _trailingFlipped = false; _encodedLength = 0; }
|
||||||
|
bool isEmpty() const { return _maxFlag == INT_MIN && _minFlag == INT_MAX && _trailingFlipped == false && _encodedLength == 0; }
|
||||||
|
|
||||||
Enum firstFlag() const { return (Enum)_minFlag; }
|
Enum firstFlag() const { return (Enum)_minFlag; }
|
||||||
Enum lastFlag() const { return (Enum)_maxFlag; }
|
Enum lastFlag() const { return (Enum)_maxFlag; }
|
||||||
|
|
Loading…
Reference in a new issue