mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 16:41:02 +02:00
recompute polyvox mesh when setVoxelSurfaceStyle is called. remove left-over color stuff from polyvox. don't require that a polyvox be rendered before computing its physics shape
This commit is contained in:
commit
fe59f8846f
11 changed files with 459 additions and 145 deletions
247
examples/example/brownianFun.js
Normal file
247
examples/example/brownianFun.js
Normal file
|
@ -0,0 +1,247 @@
|
||||||
|
var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
||||||
|
var SOUND_PATH = HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/";
|
||||||
|
var soundURLS = ["67LCollision01.wav", "67LCollision02.wav", "airhockey_hit1.wav"];
|
||||||
|
var FLOOR_SIZE = 10;
|
||||||
|
var center = Vec3.sum(MyAvatar.position, Vec3.multiply(FLOOR_SIZE * 1.5, Quat.getFront(Camera.getOrientation())));
|
||||||
|
var WALL_WIDTH = .1;
|
||||||
|
var FLOOR_HEIGHT_OFFSET = -2;
|
||||||
|
var WALL_HEIGHT = FLOOR_SIZE / 4;
|
||||||
|
var BALL_DROP_HEIGHT = center.y + WALL_HEIGHT;
|
||||||
|
var NUM_BALLS = 50;
|
||||||
|
var BALL_RADIUS = 1;
|
||||||
|
var BROWNIAN_INTERVAL_TIME = 16;
|
||||||
|
var BROWNIAN_FORCE_RANGE = 5;
|
||||||
|
var SPAWN_TIME = 50;
|
||||||
|
var spawnCount = 0;
|
||||||
|
|
||||||
|
var brownianMotionActivated = false;
|
||||||
|
var buttonOffColor = {
|
||||||
|
red: 250,
|
||||||
|
green: 10,
|
||||||
|
blue: 10
|
||||||
|
};
|
||||||
|
var buttonOnColor = {
|
||||||
|
red: 10,
|
||||||
|
green: 200,
|
||||||
|
blue: 100
|
||||||
|
};
|
||||||
|
|
||||||
|
var bounds = {
|
||||||
|
xMin: center.x - FLOOR_SIZE / 2,
|
||||||
|
xMax: center.x + FLOOR_SIZE / 2,
|
||||||
|
zMin: center.z - FLOOR_SIZE / 2,
|
||||||
|
zMax: center.z + FLOOR_SIZE / 2
|
||||||
|
};
|
||||||
|
var balls = [];
|
||||||
|
|
||||||
|
var screenSize = Controller.getViewportDimensions();
|
||||||
|
var BUTTON_SIZE = 32;
|
||||||
|
var PADDING = 3;
|
||||||
|
|
||||||
|
var brownianButton = Overlays.addOverlay("image", {
|
||||||
|
x: screenSize.x / 2 - BUTTON_SIZE,
|
||||||
|
y: screenSize.y - (BUTTON_SIZE + PADDING),
|
||||||
|
width: BUTTON_SIZE,
|
||||||
|
height: BUTTON_SIZE,
|
||||||
|
imageURL: HIFI_PUBLIC_BUCKET + "images/blocks.png",
|
||||||
|
color: buttonOffColor,
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
var floor = Entities.addEntity({
|
||||||
|
type: 'Box',
|
||||||
|
position: Vec3.sum(center, {
|
||||||
|
x: 0,
|
||||||
|
y: FLOOR_HEIGHT_OFFSET,
|
||||||
|
z: 0
|
||||||
|
}),
|
||||||
|
dimensions: {
|
||||||
|
x: FLOOR_SIZE,
|
||||||
|
y: WALL_WIDTH,
|
||||||
|
z: FLOOR_SIZE
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
red: 100,
|
||||||
|
green: 100,
|
||||||
|
blue: 100
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var rightWall = Entities.addEntity({
|
||||||
|
type: 'Box',
|
||||||
|
position: Vec3.sum(center, {
|
||||||
|
x: FLOOR_SIZE / 2,
|
||||||
|
y: FLOOR_HEIGHT_OFFSET / 2,
|
||||||
|
z: 0
|
||||||
|
}),
|
||||||
|
dimensions: {
|
||||||
|
x: WALL_WIDTH,
|
||||||
|
y: WALL_HEIGHT,
|
||||||
|
z: FLOOR_SIZE
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
red: 120,
|
||||||
|
green: 100,
|
||||||
|
blue: 120
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var leftWall = Entities.addEntity({
|
||||||
|
type: 'Box',
|
||||||
|
position: Vec3.sum(center, {
|
||||||
|
x: -FLOOR_SIZE / 2,
|
||||||
|
y: FLOOR_HEIGHT_OFFSET / 2,
|
||||||
|
z: 0
|
||||||
|
}),
|
||||||
|
dimensions: {
|
||||||
|
x: WALL_WIDTH,
|
||||||
|
y: WALL_HEIGHT,
|
||||||
|
z: FLOOR_SIZE
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
red: 120,
|
||||||
|
green: 100,
|
||||||
|
blue: 120
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var backWall = Entities.addEntity({
|
||||||
|
type: 'Box',
|
||||||
|
position: Vec3.sum(center, {
|
||||||
|
x: 0,
|
||||||
|
y: FLOOR_HEIGHT_OFFSET / 2,
|
||||||
|
z: -FLOOR_SIZE / 2,
|
||||||
|
}),
|
||||||
|
dimensions: {
|
||||||
|
x: FLOOR_SIZE,
|
||||||
|
y: WALL_HEIGHT,
|
||||||
|
z: WALL_WIDTH
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
red: 120,
|
||||||
|
green: 100,
|
||||||
|
blue: 120
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var frontWall = Entities.addEntity({
|
||||||
|
type: 'Box',
|
||||||
|
position: Vec3.sum(center, {
|
||||||
|
x: 0,
|
||||||
|
y: FLOOR_HEIGHT_OFFSET / 2,
|
||||||
|
z: FLOOR_SIZE / 2,
|
||||||
|
}),
|
||||||
|
dimensions: {
|
||||||
|
x: FLOOR_SIZE,
|
||||||
|
y: WALL_HEIGHT,
|
||||||
|
z: WALL_WIDTH
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
red: 120,
|
||||||
|
green: 100,
|
||||||
|
blue: 120
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var spawnInterval = Script.setInterval(spawnBalls, SPAWN_TIME);
|
||||||
|
|
||||||
|
function spawnBalls() {
|
||||||
|
balls.push(Entities.addEntity({
|
||||||
|
type: "Sphere",
|
||||||
|
shapeType: "sphere",
|
||||||
|
position: {
|
||||||
|
x: randFloat(bounds.xMin, bounds.xMax),
|
||||||
|
y: BALL_DROP_HEIGHT,
|
||||||
|
z: randFloat(bounds.zMin, bounds.zMax)
|
||||||
|
},
|
||||||
|
dimensions: {
|
||||||
|
x: BALL_RADIUS,
|
||||||
|
y: BALL_RADIUS,
|
||||||
|
z: BALL_RADIUS
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
red: randFloat(100, 150),
|
||||||
|
green: randFloat(20, 80),
|
||||||
|
blue: randFloat(10, 180)
|
||||||
|
},
|
||||||
|
ignoreCollisions: false,
|
||||||
|
collisionsWillMove: true,
|
||||||
|
gravity: {
|
||||||
|
x: 0,
|
||||||
|
y: -9.9,
|
||||||
|
z: 0
|
||||||
|
},
|
||||||
|
velocity: {
|
||||||
|
x: 0,
|
||||||
|
y: -.25,
|
||||||
|
z: 0
|
||||||
|
},
|
||||||
|
collisionSoundURL: SOUND_PATH + soundURLS[randInt(0, soundURLS.length - 1)]
|
||||||
|
}));
|
||||||
|
spawnCount++;
|
||||||
|
if (spawnCount === NUM_BALLS) {
|
||||||
|
Script.clearInterval(spawnInterval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mousePressEvent(event) {
|
||||||
|
var clickedOverlay = Overlays.getOverlayAtPoint({
|
||||||
|
x: event.x,
|
||||||
|
y: event.y
|
||||||
|
});
|
||||||
|
if (clickedOverlay == brownianButton) {
|
||||||
|
brownianMotionActivated = !brownianMotionActivated;
|
||||||
|
if (brownianMotionActivated) {
|
||||||
|
brownianInterval = Script.setInterval(bumpBalls, BROWNIAN_INTERVAL_TIME);
|
||||||
|
Overlays.editOverlay(brownianButton, {
|
||||||
|
color: buttonOnColor
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Script.clearInterval(brownianInterval);
|
||||||
|
Overlays.editOverlay(brownianButton, {
|
||||||
|
color: buttonOffColor
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function bumpBalls() {
|
||||||
|
balls.forEach(function(ball) {
|
||||||
|
var props = Entities.getEntityProperties(ball);
|
||||||
|
var newVelocity = Vec3.sum(props.velocity, {
|
||||||
|
x: (Math.random() - 0.5) * BROWNIAN_FORCE_RANGE,
|
||||||
|
y: 0,
|
||||||
|
z: (Math.random() - 0.5) * BROWNIAN_FORCE_RANGE
|
||||||
|
});
|
||||||
|
Entities.editEntity(ball, {
|
||||||
|
velocity: newVelocity
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanup() {
|
||||||
|
Entities.deleteEntity(floor);
|
||||||
|
Entities.deleteEntity(rightWall);
|
||||||
|
Entities.deleteEntity(leftWall);
|
||||||
|
Entities.deleteEntity(backWall);
|
||||||
|
Entities.deleteEntity(frontWall);
|
||||||
|
balls.forEach(function(ball) {
|
||||||
|
Entities.deleteEntity(ball);
|
||||||
|
});
|
||||||
|
Overlays.deleteOverlay(brownianButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
function randFloat(low, high) {
|
||||||
|
return Math.floor(low + Math.random() * (high - low));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function randInt(low, high) {
|
||||||
|
return Math.floor(randFloat(low, high));
|
||||||
|
}
|
||||||
|
|
||||||
|
Script.scriptEnding.connect(cleanup);
|
||||||
|
|
||||||
|
|
||||||
|
Script.scriptEnding.connect(cleanup);
|
||||||
|
Controller.mousePressEvent.connect(mousePressEvent);
|
|
@ -29,31 +29,38 @@ var tablePosition = {
|
||||||
z: 0
|
z: 0
|
||||||
}
|
}
|
||||||
var isGrabbing = false;
|
var isGrabbing = false;
|
||||||
|
var isGrabbingPaddle = false;
|
||||||
var grabbedEntity = null;
|
var grabbedEntity = null;
|
||||||
var prevMouse = {};
|
var prevMouse = {x: 0, y: 0};
|
||||||
var deltaMouse = {
|
var deltaMouse = {
|
||||||
z: 0
|
z: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var MAX_GRAB_DISTANCE = 100;
|
||||||
var TABLE_SEARCH_RANGE = 10;
|
var TABLE_SEARCH_RANGE = 10;
|
||||||
var entityProps;
|
var entityProps;
|
||||||
var moveUpDown = false;
|
var moveUpDown = false;
|
||||||
var CLOSE_ENOUGH = 0.001;
|
var CLOSE_ENOUGH = 0.001;
|
||||||
var FULL_STRENGTH = 1.0;
|
var FULL_STRENGTH = 1.0;
|
||||||
var SPRING_RATE = 1.5;
|
var SPRING_TIMESCALE = 0.05;
|
||||||
|
var ANGULAR_SPRING_TIMESCALE = 0.03;
|
||||||
var DAMPING_RATE = 0.80;
|
var DAMPING_RATE = 0.80;
|
||||||
var ANGULAR_DAMPING_RATE = 0.40;
|
var ANGULAR_DAMPING_RATE = 0.40;
|
||||||
var SCREEN_TO_METERS = 0.001;
|
var SCREEN_TO_METERS = 0.001;
|
||||||
var currentPosition, currentVelocity, cameraEntityDistance, currentRotation;
|
var currentPosition, currentVelocity, cameraEntityDistance, currentRotation;
|
||||||
var grabHeight;
|
var grabHeight;
|
||||||
|
var initialVerticalGrabPosition;
|
||||||
|
var MAX_VERTICAL_ANGLE = Math.PI / 3;
|
||||||
|
var MIN_VERTICAL_ANGLE = - MAX_VERTICAL_ANGLE;
|
||||||
var velocityTowardTarget, desiredVelocity, addedVelocity, newVelocity, dPosition, camYaw, distanceToTarget, targetPosition;
|
var velocityTowardTarget, desiredVelocity, addedVelocity, newVelocity, dPosition, camYaw, distanceToTarget, targetPosition;
|
||||||
|
var grabOffset;
|
||||||
var originalGravity = {
|
var originalGravity = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
z: 0
|
z: 0
|
||||||
};
|
};
|
||||||
var shouldRotate = false;
|
var shouldRotate = false;
|
||||||
var dQ, theta, axisAngle, dT;
|
var dQ, dT;
|
||||||
var angularVelocity = {
|
var angularVelocity = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
|
@ -94,6 +101,34 @@ function nearLinePoint(targetPosition) {
|
||||||
return Vec3.sum(handPosition, along);
|
return Vec3.sum(handPosition, along);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function xzPickRayIntersetion(pointOnPlane, mouseX, mouseY) {
|
||||||
|
var relativePoint = Vec3.subtract(pointOnPlane, Camera.getPosition());
|
||||||
|
var pickRay = Camera.computePickRay(mouseX, mouseY);
|
||||||
|
if (Math.abs(pickRay.direction.y) > 0.001) {
|
||||||
|
var distance = relativePoint.y / pickRay.direction.y;
|
||||||
|
if (distance < 0.001) {
|
||||||
|
return pointOnPlane;
|
||||||
|
}
|
||||||
|
var pickInersection = Vec3.multiply(pickRay.direction, distance);
|
||||||
|
pickInersection = Vec3.sum(Camera.getPosition(), pickInersection);
|
||||||
|
return pickInersection;
|
||||||
|
}
|
||||||
|
// point and line are more-or-less co-planar: compute closest approach of pickRay and pointOnPlane
|
||||||
|
var distance = Vec3.dot(relativePoint, pickRay.direction);
|
||||||
|
var pickInersection = Vec3.multiply(pickRay.direction, distance);
|
||||||
|
return pickInersection;
|
||||||
|
}
|
||||||
|
|
||||||
|
function forwardPickRayIntersection(pointOnPlane, mouseX, mouseY) {
|
||||||
|
var relativePoint = Vec3.subtract(pointOnPlane, Camera.getPosition());
|
||||||
|
var pickRay = Camera.computePickRay(mouseX, mouseY);
|
||||||
|
var planeNormal = Quat.getFront(Camera.getOrientation());
|
||||||
|
var distance = Vec3.dot(planeNormal, relativePoint);
|
||||||
|
var rayDistance = Vec3.dot(planeNormal, pickRay.direction);
|
||||||
|
var pickIntersection = Vec3.multiply(pickRay.direction, distance / rayDistance);
|
||||||
|
pickIntersection = Vec3.sum(pickIntersection, Camera.getPosition())
|
||||||
|
return pickIntersection;
|
||||||
|
}
|
||||||
|
|
||||||
function mousePressEvent(event) {
|
function mousePressEvent(event) {
|
||||||
if (!event.isLeftButton) {
|
if (!event.isLeftButton) {
|
||||||
|
@ -103,23 +138,35 @@ function mousePressEvent(event) {
|
||||||
prevMouse.y = event.y;
|
prevMouse.y = event.y;
|
||||||
|
|
||||||
var pickRay = Camera.computePickRay(event.x, event.y);
|
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||||
var intersection = Entities.findRayIntersection(pickRay, true); // accurate picking
|
var pickResults = Entities.findRayIntersection(pickRay, true); // accurate picking
|
||||||
if (!intersection.intersects) {
|
if (!pickResults.intersects) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (intersection.properties.collisionsWillMove) {
|
if (pickResults.properties.collisionsWillMove) {
|
||||||
grabbedEntity = intersection.entityID;
|
grabbedEntity = pickResults.entityID;
|
||||||
var props = Entities.getEntityProperties(grabbedEntity)
|
var props = Entities.getEntityProperties(grabbedEntity)
|
||||||
isGrabbing = true;
|
|
||||||
originalGravity = props.gravity;
|
originalGravity = props.gravity;
|
||||||
targetPosition = props.position;
|
var objectPosition = props.position;
|
||||||
currentPosition = props.position;
|
currentPosition = props.position;
|
||||||
|
if (Vec3.distance(currentPosition, Camera.getPosition()) > MAX_GRAB_DISTANCE) {
|
||||||
|
// don't allow grabs of things far away
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
isGrabbing = true;
|
||||||
|
isGrabbingPaddle = (props.name == "air-hockey-paddle-23j4h1jh82jsjfw91jf232n2k");
|
||||||
|
|
||||||
currentVelocity = props.velocity;
|
currentVelocity = props.velocity;
|
||||||
updateDropLine(targetPosition);
|
updateDropLine(objectPosition);
|
||||||
|
|
||||||
|
var pointOnPlane = xzPickRayIntersetion(objectPosition, event.x, event.y);
|
||||||
|
grabOffset = Vec3.subtract(pointOnPlane, objectPosition);
|
||||||
|
targetPosition = objectPosition;
|
||||||
|
|
||||||
// remember the height of the object when first grabbed
|
// remember the height of the object when first grabbed
|
||||||
// we'll try to maintain this height during the rest of this grab
|
// we'll try to maintain this height during the rest of this grab
|
||||||
grabHeight = currentPosition.y;
|
grabHeight = currentPosition.y;
|
||||||
|
initialVerticalGrabPosition = currentPosition;
|
||||||
|
|
||||||
Entities.editEntity(grabbedEntity, {
|
Entities.editEntity(grabbedEntity, {
|
||||||
gravity: {
|
gravity: {
|
||||||
|
@ -194,7 +241,6 @@ function mouseReleaseEvent() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// new mouseMoveEvent
|
|
||||||
function mouseMoveEvent(event) {
|
function mouseMoveEvent(event) {
|
||||||
if (isGrabbing) {
|
if (isGrabbing) {
|
||||||
// see if something added/restored gravity
|
// see if something added/restored gravity
|
||||||
|
@ -204,71 +250,78 @@ function mouseMoveEvent(event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldRotate) {
|
if (shouldRotate) {
|
||||||
|
targetPosition = currentPosition;
|
||||||
deltaMouse.x = event.x - prevMouse.x;
|
deltaMouse.x = event.x - prevMouse.x;
|
||||||
if (!moveUpDown) {
|
deltaMouse.z = event.y - prevMouse.y;
|
||||||
deltaMouse.z = event.y - prevMouse.y;
|
deltaMouse.y = 0;
|
||||||
deltaMouse.y = 0;
|
|
||||||
} else {
|
|
||||||
deltaMouse.y = (event.y - prevMouse.y) * -1;
|
|
||||||
deltaMouse.z = 0;
|
|
||||||
}
|
|
||||||
var transformedDeltaMouse = {
|
var transformedDeltaMouse = {
|
||||||
x: deltaMouse.z,
|
x: deltaMouse.z,
|
||||||
y: deltaMouse.x,
|
y: deltaMouse.x,
|
||||||
z: deltaMouse.y
|
z: deltaMouse.y
|
||||||
};
|
};
|
||||||
transformedDeltaMouse = Vec3.multiplyQbyV(Quat.fromPitchYawRollDegrees(0, camYaw, 0), transformedDeltaMouse);
|
|
||||||
dQ = Quat.fromVec3Degrees(transformedDeltaMouse);
|
dQ = Quat.fromVec3Degrees(transformedDeltaMouse);
|
||||||
theta = 2 * Math.acos(dQ.w);
|
var theta = 2 * Math.acos(dQ.w);
|
||||||
axisAngle = Quat.axis(dQ);
|
var axis = Quat.axis(dQ);
|
||||||
angularVelocity = Vec3.multiply((theta / dT), axisAngle);
|
angularVelocity = Vec3.multiply((theta / ANGULAR_SPRING_TIMESCALE), axis);
|
||||||
} else {
|
} else {
|
||||||
var relativePosition = Vec3.subtract(currentPosition, Camera.getPosition());
|
if (moveUpDown) {
|
||||||
if (relativePosition.y < 0) {
|
targetPosition = forwardPickRayIntersection(currentPosition, event.x, event.y);
|
||||||
// grabee is below camera, so movement is valid
|
grabHeight = targetPosition.y;
|
||||||
// compute intersectionPoint where mouse ray hits grabee's current x-z plane
|
} else {
|
||||||
var pickRay = Camera.computePickRay(event.x, event.y);
|
var pointOnPlane = xzPickRayIntersetion(currentPosition, event.x, event.y);
|
||||||
var mousePosition = pickRay.direction;
|
pointOnPlane = Vec3.subtract(pointOnPlane, grabOffset);
|
||||||
var length = relativePosition.y / mousePosition.y;
|
|
||||||
mousePosition = Vec3.multiply(mousePosition, length);
|
|
||||||
mousePosition = Vec3.sum(Camera.getPosition(), mousePosition);
|
|
||||||
|
|
||||||
// translate mousePosition into local-frame
|
if (isGrabbingPaddle) {
|
||||||
mousePosition = Vec3.subtract(mousePosition, tablePosition);
|
// translate pointOnPlane into local-frame
|
||||||
|
pointOnPlane = Vec3.subtract(pointOnPlane, tablePosition);
|
||||||
|
|
||||||
// clamp local mousePosition to table field
|
// clamp local pointOnPlane to table field
|
||||||
if (mousePosition.x > fieldMaxOffset.x) {
|
if (pointOnPlane.x > fieldMaxOffset.x) {
|
||||||
mousePosition.x = fieldMaxOffset.x;
|
pointOnPlane.x = fieldMaxOffset.x;
|
||||||
} else if (mousePosition.x < fieldMinOffset.x) {
|
} else if (pointOnPlane.x < fieldMinOffset.x) {
|
||||||
mousePosition.x = fieldMinOffset.x;
|
pointOnPlane.x = fieldMinOffset.x;
|
||||||
|
}
|
||||||
|
if (pointOnPlane.z > fieldMaxOffset.z) {
|
||||||
|
pointOnPlane.z = fieldMaxOffset.z;
|
||||||
|
} else if (pointOnPlane.z < fieldMinOffset.z) {
|
||||||
|
pointOnPlane.z = fieldMinOffset.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clamp to rotated square (for cut corners)
|
||||||
|
var rotation = Quat.angleAxis(45, { x:0, y:1, z:0 });
|
||||||
|
pointOnPlane = Vec3.multiplyQbyV(rotation, pointOnPlane);
|
||||||
|
if (pointOnPlane.x > halfCornerBoxWidth) {
|
||||||
|
pointOnPlane.x = halfCornerBoxWidth;
|
||||||
|
} else if (pointOnPlane.x < -halfCornerBoxWidth) {
|
||||||
|
pointOnPlane.x = -halfCornerBoxWidth;
|
||||||
|
}
|
||||||
|
if (pointOnPlane.z > halfCornerBoxWidth) {
|
||||||
|
pointOnPlane.z = halfCornerBoxWidth;
|
||||||
|
} else if (pointOnPlane.z < -halfCornerBoxWidth) {
|
||||||
|
pointOnPlane.z = -halfCornerBoxWidth;
|
||||||
|
}
|
||||||
|
// rotate back into local frame
|
||||||
|
rotation.y = -rotation.y;
|
||||||
|
pointOnPlane = Vec3.multiplyQbyV(rotation, pointOnPlane);
|
||||||
|
|
||||||
|
// translate into world-frame
|
||||||
|
pointOnPlane = Vec3.sum(tablePosition, pointOnPlane);
|
||||||
|
} else {
|
||||||
|
// we're grabbing a non-paddle object
|
||||||
|
|
||||||
|
// clamp distance
|
||||||
|
var relativePosition = Vec3.subtract(pointOnPlane, Camera.getPosition());
|
||||||
|
var length = Vec3.length(relativePosition);
|
||||||
|
if (length > MAX_GRAB_DISTANCE) {
|
||||||
|
relativePosition = Vec3.multiply(relativePosition, MAX_GRAB_DISTANCE / length);
|
||||||
|
pointOnPlane = Vec3.sum(relativePosition, Camera.getPosition());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (mousePosition.z > fieldMaxOffset.z) {
|
// clamp to grabHeight
|
||||||
mousePosition.z = fieldMaxOffset.z;
|
pointOnPlane.y = grabHeight;
|
||||||
} else if (mousePosition.z < fieldMinOffset.z) {
|
targetPosition = pointOnPlane;
|
||||||
mousePosition.z = fieldMinOffset.z;
|
initialVerticalGrabPosition = targetPosition;
|
||||||
}
|
|
||||||
|
|
||||||
// clamp to rotated square (for cut corners)
|
|
||||||
var rotation = Quat.angleAxis(45, { x:0, y:1, z:0 });
|
|
||||||
mousePosition = Vec3.multiplyQbyV(rotation, mousePosition);
|
|
||||||
if (mousePosition.x > halfCornerBoxWidth) {
|
|
||||||
mousePosition.x = halfCornerBoxWidth;
|
|
||||||
} else if (mousePosition.x < -halfCornerBoxWidth) {
|
|
||||||
mousePosition.x = -halfCornerBoxWidth;
|
|
||||||
}
|
|
||||||
if (mousePosition.z > halfCornerBoxWidth) {
|
|
||||||
mousePosition.z = halfCornerBoxWidth;
|
|
||||||
} else if (mousePosition.z < -halfCornerBoxWidth) {
|
|
||||||
mousePosition.z = -halfCornerBoxWidth;
|
|
||||||
}
|
|
||||||
// rotate back into local frame
|
|
||||||
rotation.y = -rotation.y;
|
|
||||||
mousePosition = Vec3.multiplyQbyV(rotation, mousePosition);
|
|
||||||
// translate into world-frame
|
|
||||||
mousePosition = Vec3.sum(tablePosition, mousePosition);
|
|
||||||
|
|
||||||
mousePosition.y = grabHeight;
|
|
||||||
targetPosition = mousePosition;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -297,57 +350,32 @@ function keyPressEvent(event) {
|
||||||
function update(deltaTime) {
|
function update(deltaTime) {
|
||||||
dT = deltaTime;
|
dT = deltaTime;
|
||||||
if (isGrabbing) {
|
if (isGrabbing) {
|
||||||
|
|
||||||
entityProps = Entities.getEntityProperties(grabbedEntity);
|
entityProps = Entities.getEntityProperties(grabbedEntity);
|
||||||
currentPosition = entityProps.position;
|
currentPosition = entityProps.position;
|
||||||
currentVelocity = entityProps.velocity;
|
|
||||||
currentRotation = entityProps.rotation;
|
|
||||||
|
|
||||||
var dPosition = Vec3.subtract(targetPosition, currentPosition);
|
|
||||||
|
|
||||||
distanceToTarget = Vec3.length(dPosition);
|
|
||||||
if (distanceToTarget > CLOSE_ENOUGH) {
|
|
||||||
// compute current velocity in the direction we want to move
|
|
||||||
velocityTowardTarget = Vec3.dot(currentVelocity, Vec3.normalize(dPosition));
|
|
||||||
velocityTowardTarget = Vec3.multiply(Vec3.normalize(dPosition), velocityTowardTarget);
|
|
||||||
// compute the speed we would like to be going toward the target position
|
|
||||||
|
|
||||||
desiredVelocity = Vec3.multiply(dPosition, (1.0 / deltaTime) * SPRING_RATE);
|
|
||||||
// compute how much we want to add to the existing velocity
|
|
||||||
addedVelocity = Vec3.subtract(desiredVelocity, velocityTowardTarget);
|
|
||||||
// If target is too far, roll off the force as inverse square of distance
|
|
||||||
if (distanceToTarget / cameraEntityDistance > FULL_STRENGTH) {
|
|
||||||
addedVelocity = Vec3.multiply(addedVelocity, Math.pow(FULL_STRENGTH / distanceToTarget, 2.0));
|
|
||||||
}
|
|
||||||
newVelocity = Vec3.sum(currentVelocity, addedVelocity);
|
|
||||||
// Add Damping
|
|
||||||
newVelocity = Vec3.subtract(newVelocity, Vec3.multiply(newVelocity, DAMPING_RATE));
|
|
||||||
// Update entity
|
|
||||||
} else {
|
|
||||||
newVelocity = {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
z: 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (shouldRotate) {
|
if (shouldRotate) {
|
||||||
angularVelocity = Vec3.subtract(angularVelocity, Vec3.multiply(angularVelocity, ANGULAR_DAMPING_RATE));
|
angularVelocity = Vec3.subtract(angularVelocity, Vec3.multiply(angularVelocity, ANGULAR_DAMPING_RATE));
|
||||||
|
Entities.editEntity(grabbedEntity, { angularVelocity: angularVelocity, });
|
||||||
} else {
|
} else {
|
||||||
angularVelocity = entityProps.angularVelocity;
|
var dPosition = Vec3.subtract(targetPosition, currentPosition);
|
||||||
|
var delta = Vec3.length(dPosition);
|
||||||
|
if (delta > CLOSE_ENOUGH) {
|
||||||
|
var MAX_POSITION_DELTA = 0.50;
|
||||||
|
if (delta > MAX_POSITION_DELTA) {
|
||||||
|
dPosition = Vec3.multiply(dPosition, MAX_POSITION_DELTA / delta);
|
||||||
|
}
|
||||||
|
// desired speed is proportional to displacement by the inverse of timescale
|
||||||
|
// (for critically damped motion)
|
||||||
|
newVelocity = Vec3.multiply(dPosition, 1.0 / SPRING_TIMESCALE);
|
||||||
|
} else {
|
||||||
|
newVelocity = {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Entities.editEntity(grabbedEntity, { velocity: newVelocity, });
|
||||||
}
|
}
|
||||||
|
|
||||||
// enforce that grabee's rotation is only about y-axis while being grabbed
|
|
||||||
currentRotation.x = 0;
|
|
||||||
currentRotation.z = 0;
|
|
||||||
currentRotation.y = Math.sqrt(1.0 - currentRotation.w * currentRotation.w);
|
|
||||||
// Hrm... slamming the currentRotation doesn't seem to work
|
|
||||||
|
|
||||||
Entities.editEntity(grabbedEntity, {
|
|
||||||
position: currentPosition,
|
|
||||||
rotation: currentRotation,
|
|
||||||
velocity: newVelocity,
|
|
||||||
angularVelocity: angularVelocity
|
|
||||||
});
|
|
||||||
updateDropLine(targetPosition);
|
updateDropLine(targetPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,8 +112,6 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
||||||
PerformanceTimer perfTimer("RMEIrender");
|
PerformanceTimer perfTimer("RMEIrender");
|
||||||
assert(getType() == EntityTypes::Model);
|
assert(getType() == EntityTypes::Model);
|
||||||
|
|
||||||
bool drawAsModel = hasModel();
|
|
||||||
|
|
||||||
glm::vec3 position = getPosition();
|
glm::vec3 position = getPosition();
|
||||||
glm::vec3 dimensions = getDimensions();
|
glm::vec3 dimensions = getDimensions();
|
||||||
|
|
||||||
|
@ -125,8 +123,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
||||||
highlightSimulationOwnership = (getSimulatorID() == myNodeID);
|
highlightSimulationOwnership = (getSimulatorID() == myNodeID);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool didDraw = false;
|
if (hasModel()) {
|
||||||
if (drawAsModel && !highlightSimulationOwnership) {
|
|
||||||
remapTextures();
|
remapTextures();
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
{
|
{
|
||||||
|
@ -179,19 +176,20 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
||||||
if (args && (args->_renderMode == RenderArgs::SHADOW_RENDER_MODE)) {
|
if (args && (args->_renderMode == RenderArgs::SHADOW_RENDER_MODE)) {
|
||||||
if (movingOrAnimating) {
|
if (movingOrAnimating) {
|
||||||
_model->renderInScene(alpha, args);
|
_model->renderInScene(alpha, args);
|
||||||
didDraw = true;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_model->renderInScene(alpha, args);
|
_model->renderInScene(alpha, args);
|
||||||
didDraw = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
|
||||||
|
|
||||||
if (!didDraw) {
|
if (highlightSimulationOwnership) {
|
||||||
|
glm::vec4 greenColor(0.0f, 1.0f, 0.0f, 1.0f);
|
||||||
|
RenderableDebugableEntityItem::renderBoundingBox(this, args, 0.0f, greenColor);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
glm::vec4 greenColor(0.0f, 1.0f, 0.0f, 1.0f);
|
glm::vec4 greenColor(0.0f, 1.0f, 0.0f, 1.0f);
|
||||||
RenderableDebugableEntityItem::renderBoundingBox(this, args, 0.0f, greenColor);
|
RenderableDebugableEntityItem::renderBoundingBox(this, args, 0.0f, greenColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,16 @@ void RenderablePolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize)
|
||||||
_voxelVolumeSize[2] - 1);
|
_voxelVolumeSize[2] - 1);
|
||||||
|
|
||||||
_volData = new PolyVox::SimpleVolume<uint8_t>(PolyVox::Region(lowCorner, highCorner));
|
_volData = new PolyVox::SimpleVolume<uint8_t>(PolyVox::Region(lowCorner, highCorner));
|
||||||
|
compressVolumeData();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RenderablePolyVoxEntityItem::setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle) {
|
||||||
|
if (voxelSurfaceStyle == _voxelSurfaceStyle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PolyVoxEntityItem::setVoxelSurfaceStyle(voxelSurfaceStyle);
|
||||||
|
_needsModelReload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -368,7 +378,7 @@ bool RenderablePolyVoxEntityItem::isReadyToComputeShape() {
|
||||||
qDebug() << "RenderablePolyVoxEntityItem::isReadyToComputeShape" << (!_needsModelReload);
|
qDebug() << "RenderablePolyVoxEntityItem::isReadyToComputeShape" << (!_needsModelReload);
|
||||||
|
|
||||||
if (_needsModelReload) {
|
if (_needsModelReload) {
|
||||||
return false;
|
getModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int z = 0; z < _volData->getDepth(); z++) {
|
for (int z = 0; z < _volData->getDepth(); z++) {
|
||||||
|
|
|
@ -40,6 +40,8 @@ public:
|
||||||
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
||||||
void** intersectedObject, bool precisionPicking) const;
|
void** intersectedObject, bool precisionPicking) const;
|
||||||
|
|
||||||
|
virtual void setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle);
|
||||||
|
|
||||||
void getModel();
|
void getModel();
|
||||||
|
|
||||||
virtual void setVoxelData(QByteArray voxelData);
|
virtual void setVoxelData(QByteArray voxelData);
|
||||||
|
|
|
@ -480,17 +480,21 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
||||||
bytesRead += encodedUpdateDelta.size();
|
bytesRead += encodedUpdateDelta.size();
|
||||||
|
|
||||||
// Newer bitstreams will have a last simulated and a last updated value
|
// Newer bitstreams will have a last simulated and a last updated value
|
||||||
|
quint64 lastSimulatedFromBufferAdjusted = now;
|
||||||
if (args.bitstreamVersion >= VERSION_ENTITIES_HAS_LAST_SIMULATED_TIME) {
|
if (args.bitstreamVersion >= VERSION_ENTITIES_HAS_LAST_SIMULATED_TIME) {
|
||||||
// last simulated is stored as ByteCountCoded delta from lastEdited
|
// last simulated is stored as ByteCountCoded delta from lastEdited
|
||||||
QByteArray encodedSimulatedDelta = originalDataBuffer.mid(bytesRead); // maximum possible size
|
QByteArray encodedSimulatedDelta = originalDataBuffer.mid(bytesRead); // maximum possible size
|
||||||
ByteCountCoded<quint64> simulatedDeltaCoder = encodedSimulatedDelta;
|
ByteCountCoded<quint64> simulatedDeltaCoder = encodedSimulatedDelta;
|
||||||
quint64 simulatedDelta = simulatedDeltaCoder;
|
quint64 simulatedDelta = simulatedDeltaCoder;
|
||||||
if (overwriteLocalData) {
|
if (overwriteLocalData) {
|
||||||
_lastSimulated = lastEditedFromBufferAdjusted + simulatedDelta; // don't adjust for clock skew since we already did that
|
lastSimulatedFromBufferAdjusted = lastEditedFromBufferAdjusted + simulatedDelta; // don't adjust for clock skew since we already did that
|
||||||
|
if (lastSimulatedFromBufferAdjusted > now) {
|
||||||
|
lastSimulatedFromBufferAdjusted = now;
|
||||||
|
}
|
||||||
#ifdef WANT_DEBUG
|
#ifdef WANT_DEBUG
|
||||||
qCDebug(entities) << " _lastSimulated:" << debugTime(_lastSimulated, now);
|
|
||||||
qCDebug(entities) << " _lastEdited:" << debugTime(_lastEdited, now);
|
qCDebug(entities) << " _lastEdited:" << debugTime(_lastEdited, now);
|
||||||
qCDebug(entities) << " lastEditedFromBufferAdjusted:" << debugTime(lastEditedFromBufferAdjusted, now);
|
qCDebug(entities) << " lastEditedFromBufferAdjusted:" << debugTime(lastEditedFromBufferAdjusted, now);
|
||||||
|
qCDebug(entities) << " lastSimulatedFromBufferAdjusted:" << debugTime(lastSimulatedFromBufferAdjusted, now);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
encodedSimulatedDelta = simulatedDeltaCoder; // determine true length
|
encodedSimulatedDelta = simulatedDeltaCoder; // determine true length
|
||||||
|
@ -606,8 +610,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
||||||
// use our simulation helper routine to get a best estimate of where the entity should be.
|
// use our simulation helper routine to get a best estimate of where the entity should be.
|
||||||
const float MIN_TIME_SKIP = 0.0f;
|
const float MIN_TIME_SKIP = 0.0f;
|
||||||
const float MAX_TIME_SKIP = 1.0f; // in seconds
|
const float MAX_TIME_SKIP = 1.0f; // in seconds
|
||||||
float skipTimeForward = glm::clamp((float)(now - _lastSimulated) / (float)(USECS_PER_SECOND),
|
float skipTimeForward = glm::clamp((float)(now - lastSimulatedFromBufferAdjusted) / (float)(USECS_PER_SECOND),
|
||||||
MIN_TIME_SKIP, MAX_TIME_SKIP);
|
MIN_TIME_SKIP, MAX_TIME_SKIP);
|
||||||
if (skipTimeForward > 0.0f) {
|
if (skipTimeForward > 0.0f) {
|
||||||
#ifdef WANT_DEBUG
|
#ifdef WANT_DEBUG
|
||||||
qCDebug(entities) << "skipTimeForward:" << skipTimeForward;
|
qCDebug(entities) << "skipTimeForward:" << skipTimeForward;
|
||||||
|
@ -617,19 +621,22 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
||||||
// we don't want the side effect of flag setting.
|
// we don't want the side effect of flag setting.
|
||||||
simulateKinematicMotion(skipTimeForward, false);
|
simulateKinematicMotion(skipTimeForward, false);
|
||||||
}
|
}
|
||||||
_lastSimulated = now;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
const QUuid& myNodeID = nodeList->getSessionUUID();
|
const QUuid& myNodeID = nodeList->getSessionUUID();
|
||||||
if (overwriteLocalData && _simulatorID == myNodeID && !_simulatorID.isNull()) {
|
if (overwriteLocalData) {
|
||||||
// we own the simulation, so we keep our transform+velocities and remove any related dirty flags
|
if (_simulatorID == myNodeID && !_simulatorID.isNull()) {
|
||||||
// rather than accept the values in the packet
|
// we own the simulation, so we keep our transform+velocities and remove any related dirty flags
|
||||||
_position = savePosition;
|
// rather than accept the values in the packet
|
||||||
_rotation = saveRotation;
|
_position = savePosition;
|
||||||
_velocity = saveVelocity;
|
_rotation = saveRotation;
|
||||||
_angularVelocity = saveAngularVelocity;
|
_velocity = saveVelocity;
|
||||||
_dirtyFlags &= ~(EntityItem::DIRTY_TRANSFORM | EntityItem::DIRTY_VELOCITIES);
|
_angularVelocity = saveAngularVelocity;
|
||||||
|
_dirtyFlags &= ~(EntityItem::DIRTY_TRANSFORM | EntityItem::DIRTY_VELOCITIES);
|
||||||
|
} else {
|
||||||
|
_lastSimulated = now;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
|
@ -919,6 +926,21 @@ EntityItemProperties EntityItem::getProperties() const {
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityItem::getAllTerseUpdateProperties(EntityItemProperties& properties) const {
|
||||||
|
// a TerseUpdate includes the transform and its derivatives
|
||||||
|
properties._position = _position;
|
||||||
|
properties._velocity = _velocity;
|
||||||
|
properties._rotation = _rotation;
|
||||||
|
properties._angularVelocity = _angularVelocity;
|
||||||
|
properties._acceleration = _acceleration;
|
||||||
|
|
||||||
|
properties._positionChanged = true;
|
||||||
|
properties._velocityChanged = true;
|
||||||
|
properties._rotationChanged = true;
|
||||||
|
properties._angularVelocityChanged = true;
|
||||||
|
properties._accelerationChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
bool EntityItem::setProperties(const EntityItemProperties& properties) {
|
bool EntityItem::setProperties(const EntityItemProperties& properties) {
|
||||||
bool somethingChanged = false;
|
bool somethingChanged = false;
|
||||||
|
|
||||||
|
|
|
@ -351,6 +351,8 @@ public:
|
||||||
|
|
||||||
quint64 getLastEditedFromRemote() { return _lastEditedFromRemote; }
|
quint64 getLastEditedFromRemote() { return _lastEditedFromRemote; }
|
||||||
|
|
||||||
|
void getAllTerseUpdateProperties(EntityItemProperties& properties) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
static bool _sendPhysicsUpdates;
|
static bool _sendPhysicsUpdates;
|
||||||
|
|
|
@ -1175,4 +1175,7 @@ AABox EntityItemProperties::getAABox() const {
|
||||||
return AABox(rotatedExtentsRelativeToRegistrationPoint);
|
return AABox(rotatedExtentsRelativeToRegistrationPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EntityItemProperties::hasTerseUpdateChanges() const {
|
||||||
|
// a TerseUpdate includes the transform and its derivatives
|
||||||
|
return _positionChanged || _velocityChanged || _rotationChanged || _angularVelocityChanged || _accelerationChanged;
|
||||||
|
}
|
||||||
|
|
|
@ -196,6 +196,8 @@ public:
|
||||||
|
|
||||||
void setCreated(QDateTime v);
|
void setCreated(QDateTime v);
|
||||||
|
|
||||||
|
bool hasTerseUpdateChanges() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QUuid _id;
|
QUuid _id;
|
||||||
bool _idSet;
|
bool _idSet;
|
||||||
|
@ -215,6 +217,7 @@ private:
|
||||||
QStringList _textureNames;
|
QStringList _textureNames;
|
||||||
glm::vec3 _naturalDimensions;
|
glm::vec3 _naturalDimensions;
|
||||||
};
|
};
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -146,7 +146,17 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties&
|
||||||
EntityItemProperties modifiedProperties = properties;
|
EntityItemProperties modifiedProperties = properties;
|
||||||
entity->setLastBroadcast(usecTimestampNow());
|
entity->setLastBroadcast(usecTimestampNow());
|
||||||
modifiedProperties.setType(entity->getType());
|
modifiedProperties.setType(entity->getType());
|
||||||
bidForSimulationOwnership(modifiedProperties);
|
if (modifiedProperties.hasTerseUpdateChanges()) {
|
||||||
|
// we make a bid for (or assert) our simulation ownership
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
const QUuid myNodeID = nodeList->getSessionUUID();
|
||||||
|
modifiedProperties.setSimulatorID(myNodeID);
|
||||||
|
|
||||||
|
if (entity->getSimulatorID() == myNodeID) {
|
||||||
|
// we think we already own simulation, so make sure we send ALL TerseUpdate properties
|
||||||
|
entity->getAllTerseUpdateProperties(modifiedProperties);
|
||||||
|
}
|
||||||
|
}
|
||||||
queueEntityMessage(PacketTypeEntityEdit, entityID, modifiedProperties);
|
queueEntityMessage(PacketTypeEntityEdit, entityID, modifiedProperties);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,16 +40,6 @@ class PolyVoxEntityItem : public EntityItem {
|
||||||
virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||||
ReadBitstreamToTreeParams& args,
|
ReadBitstreamToTreeParams& args,
|
||||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData);
|
EntityPropertyFlags& propertyFlags, bool overwriteLocalData);
|
||||||
|
|
||||||
const rgbColor& getColor() const { return _color; }
|
|
||||||
xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; }
|
|
||||||
|
|
||||||
void setColor(const rgbColor& value) { memcpy(_color, value, sizeof(_color)); }
|
|
||||||
void setXColor(const xColor& value) {
|
|
||||||
_color[RED_INDEX] = value.red;
|
|
||||||
_color[GREEN_INDEX] = value.green;
|
|
||||||
_color[BLUE_INDEX] = value.blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ShapeType getShapeType() const;
|
virtual ShapeType getShapeType() const;
|
||||||
|
|
||||||
|
@ -74,7 +64,7 @@ class PolyVoxEntityItem : public EntityItem {
|
||||||
|
|
||||||
virtual void setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle) { _voxelSurfaceStyle = voxelSurfaceStyle; }
|
virtual void setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle) { _voxelSurfaceStyle = voxelSurfaceStyle; }
|
||||||
virtual void setVoxelSurfaceStyle(uint16_t voxelSurfaceStyle) {
|
virtual void setVoxelSurfaceStyle(uint16_t voxelSurfaceStyle) {
|
||||||
_voxelSurfaceStyle = (PolyVoxSurfaceStyle) voxelSurfaceStyle;
|
setVoxelSurfaceStyle((PolyVoxSurfaceStyle) voxelSurfaceStyle);
|
||||||
}
|
}
|
||||||
virtual PolyVoxSurfaceStyle getVoxelSurfaceStyle() const { return _voxelSurfaceStyle; }
|
virtual PolyVoxSurfaceStyle getVoxelSurfaceStyle() const { return _voxelSurfaceStyle; }
|
||||||
|
|
||||||
|
@ -91,7 +81,6 @@ class PolyVoxEntityItem : public EntityItem {
|
||||||
virtual void setAll(uint8_t toValue) {}
|
virtual void setAll(uint8_t toValue) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
rgbColor _color;
|
|
||||||
glm::vec3 _voxelVolumeSize; // this is always 3 bytes
|
glm::vec3 _voxelVolumeSize; // this is always 3 bytes
|
||||||
QByteArray _voxelData;
|
QByteArray _voxelData;
|
||||||
PolyVoxSurfaceStyle _voxelSurfaceStyle;
|
PolyVoxSurfaceStyle _voxelSurfaceStyle;
|
||||||
|
|
Loading…
Reference in a new issue