mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 12:17:45 +02:00
Merge branch 'master' of https://github.com/worklist/hifi into 20367
This commit is contained in:
commit
484b014fa7
26 changed files with 651 additions and 214 deletions
|
@ -212,12 +212,8 @@
|
||||||
|
|
||||||
this.preload = function(entityID) {
|
this.preload = function(entityID) {
|
||||||
this.preOperation(entityID);
|
this.preOperation(entityID);
|
||||||
};
|
|
||||||
this.unload = function(){
|
|
||||||
Entities.deleteEntity(this.lightID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this.clickReleaseOnEntity = function(entityID, mouseEvent) {
|
this.clickReleaseOnEntity = function(entityID, mouseEvent) {
|
||||||
this.preOperation(entityID);
|
this.preOperation(entityID);
|
||||||
|
|
||||||
|
|
|
@ -330,6 +330,8 @@
|
||||||
elLightSections[i].style.display = 'block';
|
elLightSections[i].style.display = 'block';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
elLightSpotLight.checked = properties.isSpotlight;
|
||||||
|
|
||||||
elLightColorRed.value = properties.color.red;
|
elLightColorRed.value = properties.color.red;
|
||||||
elLightColorGreen.value = properties.color.green;
|
elLightColorGreen.value = properties.color.green;
|
||||||
elLightColorBlue.value = properties.color.blue;
|
elLightColorBlue.value = properties.color.blue;
|
||||||
|
|
|
@ -301,6 +301,8 @@ SelectionDisplay = (function () {
|
||||||
var grabberSolid = true;
|
var grabberSolid = true;
|
||||||
var grabberMoveUpPosition = { x: 0, y: 0, z: 0 };
|
var grabberMoveUpPosition = { x: 0, y: 0, z: 0 };
|
||||||
|
|
||||||
|
var lightOverlayColor = { red: 255, green: 153, blue: 0 };
|
||||||
|
|
||||||
var grabberPropertiesCorner = {
|
var grabberPropertiesCorner = {
|
||||||
position: { x:0, y: 0, z: 0},
|
position: { x:0, y: 0, z: 0},
|
||||||
size: grabberSizeCorner,
|
size: grabberSizeCorner,
|
||||||
|
@ -340,6 +342,11 @@ SelectionDisplay = (function () {
|
||||||
borderSize: 1.4,
|
borderSize: 1.4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var spotLightLineProperties = {
|
||||||
|
color: lightOverlayColor,
|
||||||
|
lineWidth: 1.5,
|
||||||
|
};
|
||||||
|
|
||||||
var highlightBox = Overlays.addOverlay("cube", {
|
var highlightBox = Overlays.addOverlay("cube", {
|
||||||
position: { x:0, y: 0, z: 0},
|
position: { x:0, y: 0, z: 0},
|
||||||
size: 1,
|
size: 1,
|
||||||
|
@ -434,6 +441,44 @@ SelectionDisplay = (function () {
|
||||||
var grabberEdgeFR = Overlays.addOverlay("cube", grabberPropertiesEdge);
|
var grabberEdgeFR = Overlays.addOverlay("cube", grabberPropertiesEdge);
|
||||||
var grabberEdgeFL = Overlays.addOverlay("cube", grabberPropertiesEdge);
|
var grabberEdgeFL = Overlays.addOverlay("cube", grabberPropertiesEdge);
|
||||||
|
|
||||||
|
var grabberSpotLightCircle = Overlays.addOverlay("circle3d", {
|
||||||
|
color: lightOverlayColor,
|
||||||
|
isSolid: false
|
||||||
|
});
|
||||||
|
var grabberSpotLightLineT = Overlays.addOverlay("line3d", spotLightLineProperties);
|
||||||
|
var grabberSpotLightLineB = Overlays.addOverlay("line3d", spotLightLineProperties);
|
||||||
|
var grabberSpotLightLineL = Overlays.addOverlay("line3d", spotLightLineProperties);
|
||||||
|
var grabberSpotLightLineR = Overlays.addOverlay("line3d", spotLightLineProperties);
|
||||||
|
|
||||||
|
var grabberSpotLightCenter = Overlays.addOverlay("cube", grabberPropertiesEdge);
|
||||||
|
var grabberSpotLightRadius = Overlays.addOverlay("cube", grabberPropertiesEdge);
|
||||||
|
var grabberSpotLightL = Overlays.addOverlay("cube", grabberPropertiesEdge);
|
||||||
|
var grabberSpotLightR = Overlays.addOverlay("cube", grabberPropertiesEdge);
|
||||||
|
var grabberSpotLightT = Overlays.addOverlay("cube", grabberPropertiesEdge);
|
||||||
|
var grabberSpotLightB = Overlays.addOverlay("cube", grabberPropertiesEdge);
|
||||||
|
|
||||||
|
var grabberPointLightCircleX = Overlays.addOverlay("circle3d", {
|
||||||
|
rotation: Quat.fromPitchYawRollDegrees(0, 90, 0),
|
||||||
|
color: lightOverlayColor,
|
||||||
|
isSolid: false
|
||||||
|
});
|
||||||
|
var grabberPointLightCircleY = Overlays.addOverlay("circle3d", {
|
||||||
|
rotation: Quat.fromPitchYawRollDegrees(90, 0, 0),
|
||||||
|
color: lightOverlayColor,
|
||||||
|
isSolid: false
|
||||||
|
});
|
||||||
|
var grabberPointLightCircleZ = Overlays.addOverlay("circle3d", {
|
||||||
|
rotation: Quat.fromPitchYawRollDegrees(0, 0, 0),
|
||||||
|
color: lightOverlayColor,
|
||||||
|
isSolid: false
|
||||||
|
});
|
||||||
|
var grabberPointLightT = Overlays.addOverlay("cube", grabberPropertiesEdge);
|
||||||
|
var grabberPointLightB = Overlays.addOverlay("cube", grabberPropertiesEdge);
|
||||||
|
var grabberPointLightL = Overlays.addOverlay("cube", grabberPropertiesEdge);
|
||||||
|
var grabberPointLightR = Overlays.addOverlay("cube", grabberPropertiesEdge);
|
||||||
|
var grabberPointLightF = Overlays.addOverlay("cube", grabberPropertiesEdge);
|
||||||
|
var grabberPointLightN = Overlays.addOverlay("cube", grabberPropertiesEdge);
|
||||||
|
|
||||||
var stretchHandles = [
|
var stretchHandles = [
|
||||||
grabberLBN,
|
grabberLBN,
|
||||||
grabberRBN,
|
grabberRBN,
|
||||||
|
@ -461,6 +506,25 @@ SelectionDisplay = (function () {
|
||||||
grabberEdgeNL,
|
grabberEdgeNL,
|
||||||
grabberEdgeFR,
|
grabberEdgeFR,
|
||||||
grabberEdgeFL,
|
grabberEdgeFL,
|
||||||
|
|
||||||
|
grabberSpotLightLineT,
|
||||||
|
grabberSpotLightLineB,
|
||||||
|
grabberSpotLightLineL,
|
||||||
|
grabberSpotLightLineR,
|
||||||
|
|
||||||
|
grabberSpotLightCenter,
|
||||||
|
grabberSpotLightRadius,
|
||||||
|
grabberSpotLightL,
|
||||||
|
grabberSpotLightR,
|
||||||
|
grabberSpotLightT,
|
||||||
|
grabberSpotLightB,
|
||||||
|
|
||||||
|
grabberPointLightT,
|
||||||
|
grabberPointLightB,
|
||||||
|
grabberPointLightL,
|
||||||
|
grabberPointLightR,
|
||||||
|
grabberPointLightF,
|
||||||
|
grabberPointLightN,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
@ -648,6 +712,10 @@ SelectionDisplay = (function () {
|
||||||
yRailOverlay,
|
yRailOverlay,
|
||||||
zRailOverlay,
|
zRailOverlay,
|
||||||
baseOfEntityProjectionOverlay,
|
baseOfEntityProjectionOverlay,
|
||||||
|
grabberSpotLightCircle,
|
||||||
|
grabberPointLightCircleX,
|
||||||
|
grabberPointLightCircleY,
|
||||||
|
grabberPointLightCircleZ,
|
||||||
].concat(stretchHandles);
|
].concat(stretchHandles);
|
||||||
|
|
||||||
overlayNames[highlightBox] = "highlightBox";
|
overlayNames[highlightBox] = "highlightBox";
|
||||||
|
@ -942,13 +1010,20 @@ SelectionDisplay = (function () {
|
||||||
var translateHandlesVisible = true;
|
var translateHandlesVisible = true;
|
||||||
var stretchHandlesVisible = true;
|
var stretchHandlesVisible = true;
|
||||||
var selectionBoxVisible = true;
|
var selectionBoxVisible = true;
|
||||||
|
var isPointLight = false;
|
||||||
|
|
||||||
|
if (selectionManager.selections.length == 1) {
|
||||||
|
var properties = Entities.getEntityProperties(selectionManager.selections[0]);
|
||||||
|
isPointLight = properties.type == "Light" && !properties.isSpotlight;
|
||||||
|
}
|
||||||
|
|
||||||
if (mode == "ROTATE_YAW" || mode == "ROTATE_PITCH" || mode == "ROTATE_ROLL" || mode == "TRANSLATE_X in case they Z") {
|
if (mode == "ROTATE_YAW" || mode == "ROTATE_PITCH" || mode == "ROTATE_ROLL" || mode == "TRANSLATE_X in case they Z") {
|
||||||
rotationOverlaysVisible = true;
|
rotationOverlaysVisible = true;
|
||||||
rotateHandlesVisible = false;
|
rotateHandlesVisible = false;
|
||||||
translateHandlesVisible = false;
|
translateHandlesVisible = false;
|
||||||
stretchHandlesVisible = false;
|
stretchHandlesVisible = false;
|
||||||
selectionBoxVisible = false;
|
selectionBoxVisible = false;
|
||||||
} else if (mode == "TRANSLATE_UP_DOWN") {
|
} else if (mode == "TRANSLATE_UP_DOWN" || isPointLight) {
|
||||||
rotateHandlesVisible = false;
|
rotateHandlesVisible = false;
|
||||||
stretchHandlesVisible = false;
|
stretchHandlesVisible = false;
|
||||||
} else if (mode != "UNKNOWN") {
|
} else if (mode != "UNKNOWN") {
|
||||||
|
@ -1122,6 +1197,171 @@ SelectionDisplay = (function () {
|
||||||
|
|
||||||
var stretchHandlesVisible = spaceMode == SPACE_LOCAL;
|
var stretchHandlesVisible = spaceMode == SPACE_LOCAL;
|
||||||
var extendedStretchHandlesVisible = stretchHandlesVisible && showExtendedStretchHandles;
|
var extendedStretchHandlesVisible = stretchHandlesVisible && showExtendedStretchHandles;
|
||||||
|
|
||||||
|
if (selectionManager.selections.length == 1 ) {
|
||||||
|
var properties = Entities.getEntityProperties(selectionManager.selections[0]);
|
||||||
|
if (properties.type == "Light" && properties.isSpotlight == true) {
|
||||||
|
var stretchHandlesVisible = false;
|
||||||
|
var extendedStretchHandlesVisible = false;
|
||||||
|
|
||||||
|
Overlays.editOverlay(grabberSpotLightCenter, {
|
||||||
|
position: position,
|
||||||
|
visible: false,
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(grabberSpotLightRadius, {
|
||||||
|
position: NEAR,
|
||||||
|
rotation: rotation,
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
var distance = (properties.dimensions.z / 2) * Math.tan(properties.cutoff * (Math.PI / 180));
|
||||||
|
|
||||||
|
Overlays.editOverlay(grabberSpotLightL, {
|
||||||
|
position: EdgeNL,
|
||||||
|
rotation: rotation,
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(grabberSpotLightR, {
|
||||||
|
position: EdgeNR,
|
||||||
|
rotation: rotation,
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(grabberSpotLightT, {
|
||||||
|
position: EdgeTN,
|
||||||
|
rotation: rotation,
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(grabberSpotLightB, {
|
||||||
|
position: EdgeBN,
|
||||||
|
rotation: rotation,
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(grabberSpotLightCircle, {
|
||||||
|
position: NEAR,
|
||||||
|
dimensions: { x: distance * 2, y: distance * 2, z: 1 },
|
||||||
|
lineWidth: 1.5,
|
||||||
|
rotation: rotation,
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
Overlays.editOverlay(grabberSpotLightLineT, {
|
||||||
|
start: position,
|
||||||
|
end: EdgeTN,
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(grabberSpotLightLineB, {
|
||||||
|
start: position,
|
||||||
|
end: EdgeBN,
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(grabberSpotLightLineR, {
|
||||||
|
start: position,
|
||||||
|
end: EdgeNR,
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(grabberSpotLightLineL, {
|
||||||
|
start: position,
|
||||||
|
end: EdgeNL,
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
Overlays.editOverlay(grabberPointLightCircleX, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberPointLightCircleY, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberPointLightCircleZ, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberPointLightT, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberPointLightB, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberPointLightL, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberPointLightR, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberPointLightF, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberPointLightN, { visible: false });
|
||||||
|
} else if (properties.type == "Light" && properties.isSpotlight == false) {
|
||||||
|
var stretchHandlesVisible = false;
|
||||||
|
var extendedStretchHandlesVisible = false;
|
||||||
|
Overlays.editOverlay(grabberPointLightT, {
|
||||||
|
position: TOP,
|
||||||
|
rotation: rotation,
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(grabberPointLightB, {
|
||||||
|
position: BOTTOM,
|
||||||
|
rotation: rotation,
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(grabberPointLightL, {
|
||||||
|
position: LEFT,
|
||||||
|
rotation: rotation,
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(grabberPointLightR, {
|
||||||
|
position: RIGHT,
|
||||||
|
rotation: rotation,
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(grabberPointLightF, {
|
||||||
|
position: FAR,
|
||||||
|
rotation: rotation,
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(grabberPointLightN, {
|
||||||
|
position: NEAR,
|
||||||
|
rotation: rotation,
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(grabberPointLightCircleX, {
|
||||||
|
position: position,
|
||||||
|
rotation: Quat.multiply(rotation, Quat.fromPitchYawRollDegrees(0, 90, 0)),
|
||||||
|
dimensions: { x: properties.dimensions.z, y: properties.dimensions.z, z: 1 },
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(grabberPointLightCircleY, {
|
||||||
|
position: position,
|
||||||
|
rotation: Quat.multiply(rotation, Quat.fromPitchYawRollDegrees(90, 0, 0)),
|
||||||
|
dimensions: { x: properties.dimensions.z, y: properties.dimensions.z, z: 1 },
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
Overlays.editOverlay(grabberPointLightCircleZ, {
|
||||||
|
position: position,
|
||||||
|
rotation: rotation,
|
||||||
|
dimensions: { x: properties.dimensions.z, y: properties.dimensions.z, z: 1 },
|
||||||
|
visible: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
Overlays.editOverlay(grabberSpotLightRadius, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberSpotLightL, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberSpotLightR, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberSpotLightT, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberSpotLightB, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberSpotLightCircle, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberSpotLightLineL, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberSpotLightLineR, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberSpotLightLineT, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberSpotLightLineB, { visible: false });
|
||||||
|
} else {
|
||||||
|
Overlays.editOverlay(grabberSpotLightCenter, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberSpotLightRadius, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberSpotLightL, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberSpotLightR, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberSpotLightT, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberSpotLightB, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberSpotLightCircle, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberSpotLightLineL, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberSpotLightLineR, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberSpotLightLineT, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberSpotLightLineB, { visible: false });
|
||||||
|
|
||||||
|
Overlays.editOverlay(grabberPointLightCircleX, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberPointLightCircleY, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberPointLightCircleZ, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberPointLightT, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberPointLightB, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberPointLightL, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberPointLightR, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberPointLightF, { visible: false });
|
||||||
|
Overlays.editOverlay(grabberPointLightN, { visible: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Overlays.editOverlay(grabberLBN, { visible: stretchHandlesVisible, rotation: rotation, position: LBN });
|
Overlays.editOverlay(grabberLBN, { visible: stretchHandlesVisible, rotation: rotation, position: LBN });
|
||||||
Overlays.editOverlay(grabberRBN, { visible: stretchHandlesVisible, rotation: rotation, position: RBN });
|
Overlays.editOverlay(grabberRBN, { visible: stretchHandlesVisible, rotation: rotation, position: RBN });
|
||||||
Overlays.editOverlay(grabberLBF, { visible: stretchHandlesVisible, rotation: rotation, position: LBF });
|
Overlays.editOverlay(grabberLBF, { visible: stretchHandlesVisible, rotation: rotation, position: LBF });
|
||||||
|
@ -1422,7 +1662,7 @@ SelectionDisplay = (function () {
|
||||||
// direction - direction to stretch in
|
// direction - direction to stretch in
|
||||||
// pivot - point to use as a pivot
|
// pivot - point to use as a pivot
|
||||||
// offset - the position of the overlay tool relative to the selections center position
|
// offset - the position of the overlay tool relative to the selections center position
|
||||||
var makeStretchTool = function(stretchMode, direction, pivot, offset) {
|
var makeStretchTool = function(stretchMode, direction, pivot, offset, customOnMove) {
|
||||||
var signs = {
|
var signs = {
|
||||||
x: direction.x < 0 ? -1 : (direction.x > 0 ? 1 : 0),
|
x: direction.x < 0 ? -1 : (direction.x > 0 ? 1 : 0),
|
||||||
y: direction.y < 0 ? -1 : (direction.y > 0 ? 1 : 0),
|
y: direction.y < 0 ? -1 : (direction.y > 0 ? 1 : 0),
|
||||||
|
@ -1554,7 +1794,7 @@ SelectionDisplay = (function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
var onMove = function(event) {
|
var onMove = function(event) {
|
||||||
var proportional = spaceMode == SPACE_WORLD || event.isShifted;
|
var proportional = spaceMode == SPACE_WORLD || event.isShifted || activeTool.mode == "STRETCH_RADIUS";
|
||||||
|
|
||||||
var position, dimensions, rotation;
|
var position, dimensions, rotation;
|
||||||
if (spaceMode == SPACE_LOCAL) {
|
if (spaceMode == SPACE_LOCAL) {
|
||||||
|
@ -1577,61 +1817,66 @@ SelectionDisplay = (function () {
|
||||||
|
|
||||||
vector = vec3Mult(mask, vector);
|
vector = vec3Mult(mask, vector);
|
||||||
|
|
||||||
vector = grid.snapToSpacing(vector);
|
if (customOnMove) {
|
||||||
|
var change = Vec3.multiply(-1, vec3Mult(signs, vector));
|
||||||
var changeInDimensions = Vec3.multiply(-1, vec3Mult(signs, vector));
|
customOnMove(vector, change);
|
||||||
var newDimensions;
|
|
||||||
if (proportional) {
|
|
||||||
var absX = Math.abs(changeInDimensions.x);
|
|
||||||
var absY = Math.abs(changeInDimensions.y);
|
|
||||||
var absZ = Math.abs(changeInDimensions.z);
|
|
||||||
var pctChange = 0;
|
|
||||||
if (absX > absY && absX > absZ) {
|
|
||||||
pctChange = changeInDimensions.x / initialProperties.dimensions.x;
|
|
||||||
pctChange = changeInDimensions.x / initialDimensions.x;
|
|
||||||
} else if (absY > absZ) {
|
|
||||||
pctChange = changeInDimensions.y / initialProperties.dimensions.y;
|
|
||||||
pctChange = changeInDimensions.y / initialDimensions.y;
|
|
||||||
} else {
|
|
||||||
pctChange = changeInDimensions.z / initialProperties.dimensions.z;
|
|
||||||
pctChange = changeInDimensions.z / initialDimensions.z;
|
|
||||||
}
|
|
||||||
pctChange += 1.0;
|
|
||||||
newDimensions = Vec3.multiply(pctChange, initialDimensions);
|
|
||||||
} else {
|
} else {
|
||||||
newDimensions = Vec3.sum(initialDimensions, changeInDimensions);
|
vector = grid.snapToSpacing(vector);
|
||||||
}
|
|
||||||
|
|
||||||
newDimensions.x = Math.max(newDimensions.x, MINIMUM_DIMENSION);
|
|
||||||
newDimensions.y = Math.max(newDimensions.y, MINIMUM_DIMENSION);
|
|
||||||
newDimensions.z = Math.max(newDimensions.z, MINIMUM_DIMENSION);
|
|
||||||
|
|
||||||
var changeInPosition = Vec3.multiplyQbyV(rotation, vec3Mult(deltaPivot, changeInDimensions));
|
|
||||||
var newPosition = Vec3.sum(initialPosition, changeInPosition);
|
|
||||||
|
|
||||||
for (var i = 0; i < SelectionManager.selections.length; i++) {
|
|
||||||
Entities.editEntity(SelectionManager.selections[i], {
|
|
||||||
position: newPosition,
|
|
||||||
dimensions: newDimensions,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var wantDebug = false;
|
var changeInDimensions = Vec3.multiply(-1, vec3Mult(signs, vector));
|
||||||
if (wantDebug) {
|
var newDimensions;
|
||||||
print(stretchMode);
|
if (proportional) {
|
||||||
Vec3.print(" newIntersection:", newIntersection);
|
var absX = Math.abs(changeInDimensions.x);
|
||||||
Vec3.print(" vector:", vector);
|
var absY = Math.abs(changeInDimensions.y);
|
||||||
Vec3.print(" oldPOS:", oldPOS);
|
var absZ = Math.abs(changeInDimensions.z);
|
||||||
Vec3.print(" newPOS:", newPOS);
|
var pctChange = 0;
|
||||||
Vec3.print(" changeInDimensions:", changeInDimensions);
|
if (absX > absY && absX > absZ) {
|
||||||
Vec3.print(" newDimensions:", newDimensions);
|
pctChange = changeInDimensions.x / initialProperties.dimensions.x;
|
||||||
|
pctChange = changeInDimensions.x / initialDimensions.x;
|
||||||
|
} else if (absY > absZ) {
|
||||||
|
pctChange = changeInDimensions.y / initialProperties.dimensions.y;
|
||||||
|
pctChange = changeInDimensions.y / initialDimensions.y;
|
||||||
|
} else {
|
||||||
|
pctChange = changeInDimensions.z / initialProperties.dimensions.z;
|
||||||
|
pctChange = changeInDimensions.z / initialDimensions.z;
|
||||||
|
}
|
||||||
|
pctChange += 1.0;
|
||||||
|
newDimensions = Vec3.multiply(pctChange, initialDimensions);
|
||||||
|
} else {
|
||||||
|
newDimensions = Vec3.sum(initialDimensions, changeInDimensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
newDimensions.x = Math.max(newDimensions.x, MINIMUM_DIMENSION);
|
||||||
|
newDimensions.y = Math.max(newDimensions.y, MINIMUM_DIMENSION);
|
||||||
|
newDimensions.z = Math.max(newDimensions.z, MINIMUM_DIMENSION);
|
||||||
|
|
||||||
|
var changeInPosition = Vec3.multiplyQbyV(rotation, vec3Mult(deltaPivot, changeInDimensions));
|
||||||
|
var newPosition = Vec3.sum(initialPosition, changeInPosition);
|
||||||
|
|
||||||
|
for (var i = 0; i < SelectionManager.selections.length; i++) {
|
||||||
|
Entities.editEntity(SelectionManager.selections[i], {
|
||||||
|
position: newPosition,
|
||||||
|
dimensions: newDimensions,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Vec3.print(" changeInPosition:", changeInPosition);
|
var wantDebug = false;
|
||||||
Vec3.print(" newPosition:", newPosition);
|
if (wantDebug) {
|
||||||
|
print(stretchMode);
|
||||||
|
Vec3.print(" newIntersection:", newIntersection);
|
||||||
|
Vec3.print(" vector:", vector);
|
||||||
|
Vec3.print(" oldPOS:", oldPOS);
|
||||||
|
Vec3.print(" newPOS:", newPOS);
|
||||||
|
Vec3.print(" changeInDimensions:", changeInDimensions);
|
||||||
|
Vec3.print(" newDimensions:", newDimensions);
|
||||||
|
|
||||||
|
Vec3.print(" changeInPosition:", changeInPosition);
|
||||||
|
Vec3.print(" newPosition:", newPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectionManager._update();
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectionManager._update();
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -1642,15 +1887,57 @@ SelectionDisplay = (function () {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
function addStretchTool(overlay, mode, pivot, direction, offset) {
|
function addStretchTool(overlay, mode, pivot, direction, offset, handleMove) {
|
||||||
if (!pivot) {
|
if (!pivot) {
|
||||||
pivot = direction;
|
pivot = direction;
|
||||||
}
|
}
|
||||||
var tool = makeStretchTool(mode, direction, pivot, offset);
|
var tool = makeStretchTool(mode, direction, pivot, offset, handleMove);
|
||||||
|
|
||||||
addGrabberTool(overlay, tool);
|
addGrabberTool(overlay, tool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cutoffStretchFunc(vector, change) {
|
||||||
|
vector = change;
|
||||||
|
Vec3.print("Radius stretch: ", vector);
|
||||||
|
var length = vector.x + vector.y + vector.z;
|
||||||
|
var props = selectionManager.savedProperties[selectionManager.selections[0].id];
|
||||||
|
|
||||||
|
var radius = props.dimensions.z / 2;
|
||||||
|
var originalCutoff = props.cutoff;
|
||||||
|
|
||||||
|
var originalSize = radius * Math.tan(originalCutoff * (Math.PI / 180));
|
||||||
|
var newSize = originalSize + length;
|
||||||
|
var cutoff = Math.atan2(newSize, radius) * 180 / Math.PI;
|
||||||
|
|
||||||
|
Entities.editEntity(selectionManager.selections[0], {
|
||||||
|
cutoff: cutoff,
|
||||||
|
});
|
||||||
|
|
||||||
|
SelectionManager._update();
|
||||||
|
};
|
||||||
|
|
||||||
|
function radiusStretchFunc(vector, change) {
|
||||||
|
var props = selectionManager.savedProperties[selectionManager.selections[0].id];
|
||||||
|
|
||||||
|
// Find the axis being adjusted
|
||||||
|
var size;
|
||||||
|
if (Math.abs(change.x) > 0) {
|
||||||
|
size = props.dimensions.x + change.x;
|
||||||
|
} else if (Math.abs(change.y) > 0) {
|
||||||
|
size = props.dimensions.y + change.y;
|
||||||
|
} else if (Math.abs(change.z) > 0) {
|
||||||
|
size = props.dimensions.z + change.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
var newDimensions = { x: size, y: size, z: size };
|
||||||
|
|
||||||
|
Entities.editEntity(selectionManager.selections[0], {
|
||||||
|
dimensions: newDimensions,
|
||||||
|
});
|
||||||
|
|
||||||
|
SelectionManager._update();
|
||||||
|
}
|
||||||
|
|
||||||
addStretchTool(grabberNEAR, "STRETCH_NEAR", { x: 0, y: 0, z: 1 }, { x: 0, y: 0, z: 1 }, { x: 0, y: 0, z: -1 });
|
addStretchTool(grabberNEAR, "STRETCH_NEAR", { x: 0, y: 0, z: 1 }, { x: 0, y: 0, z: 1 }, { x: 0, y: 0, z: -1 });
|
||||||
addStretchTool(grabberFAR, "STRETCH_FAR", { x: 0, y: 0, z: -1 }, { x: 0, y: 0, z: -1 }, { x: 0, y: 0, z: 1 });
|
addStretchTool(grabberFAR, "STRETCH_FAR", { x: 0, y: 0, z: -1 }, { x: 0, y: 0, z: -1 }, { x: 0, y: 0, z: 1 });
|
||||||
addStretchTool(grabberTOP, "STRETCH_TOP", { x: 0, y: -1, z: 0 }, { x: 0, y: -1, z: 0 }, { x: 0, y: 1, z: 0 });
|
addStretchTool(grabberTOP, "STRETCH_TOP", { x: 0, y: -1, z: 0 }, { x: 0, y: -1, z: 0 }, { x: 0, y: 1, z: 0 });
|
||||||
|
@ -1658,6 +1945,19 @@ SelectionDisplay = (function () {
|
||||||
addStretchTool(grabberRIGHT, "STRETCH_RIGHT", { x: -1, y: 0, z: 0 }, { x: -1, y: 0, z: 0 }, { x: 1, y: 0, z: 0 });
|
addStretchTool(grabberRIGHT, "STRETCH_RIGHT", { x: -1, y: 0, z: 0 }, { x: -1, y: 0, z: 0 }, { x: 1, y: 0, z: 0 });
|
||||||
addStretchTool(grabberLEFT, "STRETCH_LEFT", { x: 1, y: 0, z: 0 }, { x: 1, y: 0, z: 0 }, { x: -1, y: 0, z: 0 });
|
addStretchTool(grabberLEFT, "STRETCH_LEFT", { x: 1, y: 0, z: 0 }, { x: 1, y: 0, z: 0 }, { x: -1, y: 0, z: 0 });
|
||||||
|
|
||||||
|
addStretchTool(grabberSpotLightRadius, "STRETCH_RADIUS", { x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: 1 }, { x: 0, y: 0, z: -1 });
|
||||||
|
addStretchTool(grabberSpotLightT, "STRETCH_CUTOFF_T", { x: 0, y: 0, z: 0 }, { x: 0, y: -1, z: 0 }, { x: 0, y: 1, z: 0 }, cutoffStretchFunc);
|
||||||
|
addStretchTool(grabberSpotLightB, "STRETCH_CUTOFF_B", { x: 0, y: 0, z: 0 }, { x: 0, y: 1, z: 0 }, { x: 0, y: -1, z: 0 }, cutoffStretchFunc);
|
||||||
|
addStretchTool(grabberSpotLightL, "STRETCH_CUTOFF_L", { x: 0, y: 0, z: 0 }, { x: 1, y: 0, z: 0 }, { x: -1, y: 0, z: 0 }, cutoffStretchFunc);
|
||||||
|
addStretchTool(grabberSpotLightR, "STRETCH_CUTOFF_R", { x: 0, y: 0, z: 0 }, { x: -1, y: 0, z: 0 }, { x: 1, y: 0, z: 0 }, cutoffStretchFunc);
|
||||||
|
|
||||||
|
addStretchTool(grabberPointLightT, "STRETCH_RADIUS_T", { x: 0, y: 0, z: 0 }, { x: 0, y: -1, z: 0 }, { x: 0, y: 0, z: 1 }, radiusStretchFunc);
|
||||||
|
addStretchTool(grabberPointLightB, "STRETCH_RADIUS_B", { x: 0, y: 0, z: 0 }, { x: 0, y: 1, z: 0 }, { x: 0, y: 0, z: 1 }, radiusStretchFunc);
|
||||||
|
addStretchTool(grabberPointLightL, "STRETCH_RADIUS_L", { x: 0, y: 0, z: 0 }, { x: 1, y: 0, z: 0 }, { x: 0, y: 0, z: 1 }, radiusStretchFunc);
|
||||||
|
addStretchTool(grabberPointLightR, "STRETCH_RADIUS_R", { x: 0, y: 0, z: 0 }, { x: -1, y: 0, z: 0 }, { x: 0, y: 0, z: 1 }, radiusStretchFunc);
|
||||||
|
addStretchTool(grabberPointLightF, "STRETCH_RADIUS_F", { x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: -1 }, { x: 0, y: 0, z: 1 }, radiusStretchFunc);
|
||||||
|
addStretchTool(grabberPointLightN, "STRETCH_RADIUS_N", { x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: 1 }, { x: 0, y: 0, z: -1 }, radiusStretchFunc);
|
||||||
|
|
||||||
addStretchTool(grabberLBN, "STRETCH_LBN", null, {x: 1, y: 0, z: 1}, { x: -1, y: -1, z: -1 });
|
addStretchTool(grabberLBN, "STRETCH_LBN", null, {x: 1, y: 0, z: 1}, { x: -1, y: -1, z: -1 });
|
||||||
addStretchTool(grabberRBN, "STRETCH_RBN", null, {x: -1, y: 0, z: 1}, { x: 1, y: -1, z: -1 });
|
addStretchTool(grabberRBN, "STRETCH_RBN", null, {x: -1, y: 0, z: 1}, { x: 1, y: -1, z: -1 });
|
||||||
addStretchTool(grabberLBF, "STRETCH_LBF", null, {x: 1, y: 0, z: -1}, { x: -1, y: -1, z: 1 });
|
addStretchTool(grabberLBF, "STRETCH_LBF", null, {x: 1, y: 0, z: -1}, { x: -1, y: -1, z: 1 });
|
||||||
|
@ -2399,6 +2699,17 @@ SelectionDisplay = (function () {
|
||||||
case grabberEdgeNL:
|
case grabberEdgeNL:
|
||||||
case grabberEdgeFR:
|
case grabberEdgeFR:
|
||||||
case grabberEdgeFL:
|
case grabberEdgeFL:
|
||||||
|
case grabberSpotLightRadius:
|
||||||
|
case grabberSpotLightT:
|
||||||
|
case grabberSpotLightB:
|
||||||
|
case grabberSpotLightL:
|
||||||
|
case grabberSpotLightR:
|
||||||
|
case grabberPointLightT:
|
||||||
|
case grabberPointLightB:
|
||||||
|
case grabberPointLightR:
|
||||||
|
case grabberPointLightL:
|
||||||
|
case grabberPointLightN:
|
||||||
|
case grabberPointLightF:
|
||||||
pickedColor = grabberColorEdge;
|
pickedColor = grabberColorEdge;
|
||||||
pickedAlpha = grabberAlpha;
|
pickedAlpha = grabberAlpha;
|
||||||
highlightNeeded = true;
|
highlightNeeded = true;
|
||||||
|
|
|
@ -269,6 +269,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
_dependencyManagerIsSetup(setupEssentials(argc, argv)),
|
_dependencyManagerIsSetup(setupEssentials(argc, argv)),
|
||||||
_window(new MainWindow(desktop())),
|
_window(new MainWindow(desktop())),
|
||||||
_toolWindow(NULL),
|
_toolWindow(NULL),
|
||||||
|
_friendsWindow(NULL),
|
||||||
_datagramProcessor(),
|
_datagramProcessor(),
|
||||||
_undoStack(),
|
_undoStack(),
|
||||||
_undoStackScriptingInterface(&_undoStack),
|
_undoStackScriptingInterface(&_undoStack),
|
||||||
|
@ -310,8 +311,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
_isVSyncOn(true),
|
_isVSyncOn(true),
|
||||||
_aboutToQuit(false),
|
_aboutToQuit(false),
|
||||||
_notifiedPacketVersionMismatchThisDomain(false),
|
_notifiedPacketVersionMismatchThisDomain(false),
|
||||||
_domainConnectionRefusals(QList<QString>()),
|
_domainConnectionRefusals(QList<QString>())
|
||||||
_friendsWindow(NULL)
|
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
installNativeEventFilter(&MyNativeEventFilter::getInstance());
|
installNativeEventFilter(&MyNativeEventFilter::getInstance());
|
||||||
|
@ -977,6 +977,11 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
_myAvatar->setDriveKeys(UP, 1.0f);
|
_myAvatar->setDriveKeys(UP, 1.0f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Qt::Key_F: {
|
||||||
|
_physicsEngine.dumpNextStats();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Qt::Key_Asterisk:
|
case Qt::Key_Asterisk:
|
||||||
Menu::getInstance()->triggerOption(MenuOption::Stars);
|
Menu::getInstance()->triggerOption(MenuOption::Stars);
|
||||||
break;
|
break;
|
||||||
|
@ -1184,6 +1189,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
|
|
||||||
case Qt::Key_Comma: {
|
case Qt::Key_Comma: {
|
||||||
renderCollisionHulls = !renderCollisionHulls;
|
renderCollisionHulls = !renderCollisionHulls;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -2617,7 +2623,12 @@ glm::vec3 Application::getSunDirection() {
|
||||||
return skyStage->getSunLight()->getDirection();
|
return skyStage->getSunLight()->getDirection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME, preprocessor guard this check to occur only in DEBUG builds
|
||||||
|
static QThread * activeRenderingThread = nullptr;
|
||||||
|
|
||||||
void Application::updateShadowMap() {
|
void Application::updateShadowMap() {
|
||||||
|
activeRenderingThread = QThread::currentThread();
|
||||||
|
|
||||||
PerformanceTimer perfTimer("shadowMap");
|
PerformanceTimer perfTimer("shadowMap");
|
||||||
QOpenGLFramebufferObject* fbo = DependencyManager::get<TextureCache>()->getShadowFramebufferObject();
|
QOpenGLFramebufferObject* fbo = DependencyManager::get<TextureCache>()->getShadowFramebufferObject();
|
||||||
fbo->bind();
|
fbo->bind();
|
||||||
|
@ -2712,6 +2723,10 @@ void Application::updateShadowMap() {
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
glOrtho(minima.x, maxima.x, minima.y, maxima.y, -maxima.z, -minima.z);
|
glOrtho(minima.x, maxima.x, minima.y, maxima.y, -maxima.z, -minima.z);
|
||||||
|
|
||||||
|
glm::mat4 projAgain;
|
||||||
|
glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat*)&projAgain);
|
||||||
|
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
@ -2767,6 +2782,7 @@ void Application::updateShadowMap() {
|
||||||
fbo->release();
|
fbo->release();
|
||||||
|
|
||||||
glViewport(0, 0, _glWidget->getDeviceWidth(), _glWidget->getDeviceHeight());
|
glViewport(0, 0, _glWidget->getDeviceWidth(), _glWidget->getDeviceHeight());
|
||||||
|
activeRenderingThread = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GLfloat WORLD_AMBIENT_COLOR[] = { 0.525f, 0.525f, 0.6f };
|
const GLfloat WORLD_AMBIENT_COLOR[] = { 0.525f, 0.525f, 0.6f };
|
||||||
|
@ -2827,9 +2843,6 @@ QImage Application::renderAvatarBillboard() {
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME, preprocessor guard this check to occur only in DEBUG builds
|
|
||||||
static QThread * activeRenderingThread = nullptr;
|
|
||||||
|
|
||||||
ViewFrustum* Application::getViewFrustum() {
|
ViewFrustum* Application::getViewFrustum() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (QThread::currentThread() == activeRenderingThread) {
|
if (QThread::currentThread() == activeRenderingThread) {
|
||||||
|
|
|
@ -337,8 +337,13 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool
|
||||||
|
|
||||||
// simple frustum check
|
// simple frustum check
|
||||||
float boundingRadius = getBillboardSize();
|
float boundingRadius = getBillboardSize();
|
||||||
ViewFrustum* frustum = (renderMode == Avatar::SHADOW_RENDER_MODE) ?
|
|
||||||
Application::getInstance()->getShadowViewFrustum() : Application::getInstance()->getDisplayViewFrustum();
|
ViewFrustum* frustum = nullptr;
|
||||||
|
if (renderMode == Avatar::SHADOW_RENDER_MODE) {
|
||||||
|
frustum = Application::getInstance()->getShadowViewFrustum();
|
||||||
|
} else {
|
||||||
|
frustum = Application::getInstance()->getDisplayViewFrustum();
|
||||||
|
}
|
||||||
if (frustum->sphereInFrustum(getPosition(), boundingRadius) == ViewFrustum::OUTSIDE) {
|
if (frustum->sphereInFrustum(getPosition(), boundingRadius) == ViewFrustum::OUTSIDE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1005,22 +1005,25 @@ void MyAvatar::renderBody(ViewFrustum* renderFrustum, RenderMode renderMode, boo
|
||||||
Camera *camera = Application::getInstance()->getCamera();
|
Camera *camera = Application::getInstance()->getCamera();
|
||||||
const glm::vec3 cameraPos = camera->getPosition();
|
const glm::vec3 cameraPos = camera->getPosition();
|
||||||
|
|
||||||
// Set near clip distance according to skeleton model dimensions if first person and there is no separate head model.
|
// Only tweak the frustum near far if it's not shadow
|
||||||
if (shouldRenderHead(cameraPos, renderMode) || !getHead()->getFaceModel().getURL().isEmpty()) {
|
if (renderMode != SHADOW_RENDER_MODE) {
|
||||||
renderFrustum->setNearClip(DEFAULT_NEAR_CLIP);
|
// Set near clip distance according to skeleton model dimensions if first person and there is no separate head model.
|
||||||
} else {
|
if (shouldRenderHead(cameraPos, renderMode) || !getHead()->getFaceModel().getURL().isEmpty()) {
|
||||||
float clipDistance = _skeletonModel.getHeadClipDistance();
|
renderFrustum->setNearClip(DEFAULT_NEAR_CLIP);
|
||||||
if (OculusManager::isConnected()) {
|
} else {
|
||||||
// If avatar is horizontally in front of camera, increase clip distance by the amount it is in front.
|
float clipDistance = _skeletonModel.getHeadClipDistance();
|
||||||
glm::vec3 cameraToAvatar = _position - cameraPos;
|
if (OculusManager::isConnected()) {
|
||||||
cameraToAvatar.y = 0.0f;
|
// If avatar is horizontally in front of camera, increase clip distance by the amount it is in front.
|
||||||
glm::vec3 cameraLookAt = camera->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f);
|
glm::vec3 cameraToAvatar = _position - cameraPos;
|
||||||
float headOffset = glm::dot(cameraLookAt, cameraToAvatar);
|
cameraToAvatar.y = 0.0f;
|
||||||
if (headOffset > 0) {
|
glm::vec3 cameraLookAt = camera->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f);
|
||||||
clipDistance += headOffset;
|
float headOffset = glm::dot(cameraLookAt, cameraToAvatar);
|
||||||
|
if (headOffset > 0) {
|
||||||
|
clipDistance += headOffset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
renderFrustum->setNearClip(clipDistance);
|
||||||
}
|
}
|
||||||
renderFrustum->setNearClip(clipDistance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the body's voxels and head
|
// Render the body's voxels and head
|
||||||
|
|
|
@ -443,7 +443,6 @@ void OculusManager::configureCamera(Camera& camera, int screenWidth, int screenH
|
||||||
camera.setFieldOfView(atan(_eyeFov[0].UpTan) * DEGREES_PER_RADIAN * 2.0f);
|
camera.setFieldOfView(atan(_eyeFov[0].UpTan) * DEGREES_PER_RADIAN * 2.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool timerActive = false;
|
|
||||||
//Displays everything for the oculus, frame timing must be active
|
//Displays everything for the oculus, frame timing must be active
|
||||||
void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &position, Camera& whichCamera) {
|
void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &position, Camera& whichCamera) {
|
||||||
auto glCanvas = Application::getInstance()->getGLWidget();
|
auto glCanvas = Application::getInstance()->getGLWidget();
|
||||||
|
@ -463,6 +462,7 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p
|
||||||
// (does not seem to work on OSX with SDK based distortion)
|
// (does not seem to work on OSX with SDK based distortion)
|
||||||
// FIXME can't use a static object here, because it will cause a crash when the
|
// FIXME can't use a static object here, because it will cause a crash when the
|
||||||
// query attempts deconstruct after the GL context is gone.
|
// query attempts deconstruct after the GL context is gone.
|
||||||
|
static bool timerActive = false;
|
||||||
static QOpenGLTimerQuery timerQuery;
|
static QOpenGLTimerQuery timerQuery;
|
||||||
if (!timerQuery.isCreated()) {
|
if (!timerQuery.isCreated()) {
|
||||||
timerQuery.create();
|
timerQuery.create();
|
||||||
|
@ -671,7 +671,6 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// No DK2, no message.
|
// No DK2, no message.
|
||||||
char latency2Text[128] = "";
|
|
||||||
{
|
{
|
||||||
float latencies[5] = {};
|
float latencies[5] = {};
|
||||||
if (debugFrame && ovrHmd_GetFloatArray(_ovrHmd, "DK2Latency", latencies, 5) == 5)
|
if (debugFrame && ovrHmd_GetFloatArray(_ovrHmd, "DK2Latency", latencies, 5) == 5)
|
||||||
|
|
|
@ -31,6 +31,10 @@ class Text3DOverlay;
|
||||||
#define OVR_CLIENT_DISTORTION 1
|
#define OVR_CLIENT_DISTORTION 1
|
||||||
|
|
||||||
|
|
||||||
|
// Direct HMD mode is currently only supported on windows and some linux systems will
|
||||||
|
// misbehave if we try to enable the Oculus SDK at all, so isolate support for Direct
|
||||||
|
// mode only to windows for now
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
// On Win32 platforms, enabling Direct HMD requires that the SDK be
|
// On Win32 platforms, enabling Direct HMD requires that the SDK be
|
||||||
// initialized before the GL context is set up, but this breaks v-sync
|
// initialized before the GL context is set up, but this breaks v-sync
|
||||||
// for any application that has a Direct mode enable Rift connected
|
// for any application that has a Direct mode enable Rift connected
|
||||||
|
@ -40,6 +44,7 @@ class Text3DOverlay;
|
||||||
// caveat that it will break v-sync in NON-VR mode if you have an Oculus
|
// caveat that it will break v-sync in NON-VR mode if you have an Oculus
|
||||||
// Rift connect and in Direct mode
|
// Rift connect and in Direct mode
|
||||||
#define OVR_DIRECT_MODE 1
|
#define OVR_DIRECT_MODE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/// Handles interaction with the Oculus Rift.
|
/// Handles interaction with the Oculus Rift.
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "FlowLayout.h"
|
#include "FlowLayout.h"
|
||||||
#include "JSConsole.h"
|
#include "JSConsole.h"
|
||||||
|
#include "PathUtils.h"
|
||||||
|
|
||||||
ScriptEditorWindow::ScriptEditorWindow(QWidget* parent) :
|
ScriptEditorWindow::ScriptEditorWindow(QWidget* parent) :
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
|
@ -40,6 +41,7 @@ ScriptEditorWindow::ScriptEditorWindow(QWidget* parent) :
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
_ScriptEditorWindowUI->setupUi(this);
|
_ScriptEditorWindowUI->setupUi(this);
|
||||||
|
|
||||||
this->setWindowFlags(Qt::Tool);
|
this->setWindowFlags(Qt::Tool);
|
||||||
addScriptEditorWidget("New script");
|
addScriptEditorWidget("New script");
|
||||||
connect(_loadMenu, &QMenu::aboutToShow, this, &ScriptEditorWindow::loadMenuAboutToShow);
|
connect(_loadMenu, &QMenu::aboutToShow, this, &ScriptEditorWindow::loadMenuAboutToShow);
|
||||||
|
@ -54,6 +56,11 @@ ScriptEditorWindow::ScriptEditorWindow(QWidget* parent) :
|
||||||
connect(new QShortcut(QKeySequence("Ctrl+O"), this), &QShortcut::activated, this, &ScriptEditorWindow::loadScriptClicked);
|
connect(new QShortcut(QKeySequence("Ctrl+O"), this), &QShortcut::activated, this, &ScriptEditorWindow::loadScriptClicked);
|
||||||
connect(new QShortcut(QKeySequence("F5"), this), &QShortcut::activated, this, &ScriptEditorWindow::toggleRunScriptClicked);
|
connect(new QShortcut(QKeySequence("F5"), this), &QShortcut::activated, this, &ScriptEditorWindow::toggleRunScriptClicked);
|
||||||
|
|
||||||
|
_ScriptEditorWindowUI->loadButton->setIcon(QIcon(QPixmap(PathUtils::resourcesPath() + "icons/load-script.svg")));
|
||||||
|
_ScriptEditorWindowUI->newButton->setIcon(QIcon(QPixmap(PathUtils::resourcesPath() + "icons/new-script.svg")));
|
||||||
|
_ScriptEditorWindowUI->saveButton->setIcon(QIcon(QPixmap(PathUtils::resourcesPath() + "icons/save-script.svg")));
|
||||||
|
_ScriptEditorWindowUI->toggleRunButton->setIcon(QIcon(QPixmap(PathUtils::resourcesPath() + "icons/start-script.svg")));
|
||||||
|
|
||||||
QWidget* console = new JSConsole(this);
|
QWidget* console = new JSConsole(this);
|
||||||
console->setFixedHeight(CONSOLE_HEIGHT);
|
console->setFixedHeight(CONSOLE_HEIGHT);
|
||||||
this->layout()->addWidget(console);
|
this->layout()->addWidget(console);
|
||||||
|
|
|
@ -98,6 +98,9 @@ void Circle3DOverlay::render(RenderArgs* args) {
|
||||||
const float MAX_COLOR = 255.0f;
|
const float MAX_COLOR = 255.0f;
|
||||||
glm::vec4 color(colorX.red / MAX_COLOR, colorX.green / MAX_COLOR, colorX.blue / MAX_COLOR, alpha);
|
glm::vec4 color(colorX.red / MAX_COLOR, colorX.green / MAX_COLOR, colorX.blue / MAX_COLOR, alpha);
|
||||||
|
|
||||||
|
bool colorChanged = colorX.red != _lastColor.red || colorX.green != _lastColor.green || colorX.blue != _lastColor.blue;
|
||||||
|
_lastColor = colorX;
|
||||||
|
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
|
|
||||||
glm::vec3 position = getPosition();
|
glm::vec3 position = getPosition();
|
||||||
|
@ -131,7 +134,7 @@ void Circle3DOverlay::render(RenderArgs* args) {
|
||||||
_quadVerticesID = geometryCache->allocateID();
|
_quadVerticesID = geometryCache->allocateID();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (geometryChanged) {
|
if (geometryChanged || colorChanged) {
|
||||||
|
|
||||||
QVector<glm::vec2> points;
|
QVector<glm::vec2> points;
|
||||||
|
|
||||||
|
@ -170,7 +173,7 @@ void Circle3DOverlay::render(RenderArgs* args) {
|
||||||
_lineVerticesID = geometryCache->allocateID();
|
_lineVerticesID = geometryCache->allocateID();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (geometryChanged) {
|
if (geometryChanged || colorChanged) {
|
||||||
QVector<glm::vec2> points;
|
QVector<glm::vec2> points;
|
||||||
|
|
||||||
float angle = startAt;
|
float angle = startAt;
|
||||||
|
|
|
@ -70,6 +70,7 @@ protected:
|
||||||
int _majorTicksVerticesID;
|
int _majorTicksVerticesID;
|
||||||
int _minorTicksVerticesID;
|
int _minorTicksVerticesID;
|
||||||
|
|
||||||
|
xColor _lastColor;
|
||||||
float _lastStartAt;
|
float _lastStartAt;
|
||||||
float _lastEndAt;
|
float _lastEndAt;
|
||||||
float _lastOuterRadius;
|
float _lastOuterRadius;
|
||||||
|
|
|
@ -29,7 +29,16 @@
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="margin">
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
|
@ -54,11 +63,6 @@
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>New</string>
|
<string>New</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>../resources/icons/new-script.svg</normaloff>
|
|
||||||
<normalon>../resources/icons/new-script.svg</normalon>../resources/icons/new-script.svg</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>32</width>
|
<width>32</width>
|
||||||
|
@ -87,10 +91,6 @@
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Load</string>
|
<string>Load</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>../resources/icons/load-script.svg</normaloff>../resources/icons/load-script.svg</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>32</width>
|
<width>32</width>
|
||||||
|
@ -134,10 +134,6 @@
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Save</string>
|
<string>Save</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>../resources/icons/save-script.svg</normaloff>../resources/icons/save-script.svg</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>32</width>
|
<width>32</width>
|
||||||
|
@ -160,10 +156,6 @@
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Run/Stop</string>
|
<string>Run/Stop</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>../resources/icons/start-script.svg</normaloff>../resources/icons/start-script.svg</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>32</width>
|
<width>32</width>
|
||||||
|
|
|
@ -1281,6 +1281,9 @@ qint64 AudioClient::AudioOutputIODevice::readData(char * data, qint64 maxSize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioClient::checkDevices() {
|
void AudioClient::checkDevices() {
|
||||||
|
# ifdef Q_OS_LINUX
|
||||||
|
// on linux, this makes the audio stream hiccup
|
||||||
|
# else
|
||||||
QVector<QString> inputDevices = getDeviceNames(QAudio::AudioInput);
|
QVector<QString> inputDevices = getDeviceNames(QAudio::AudioInput);
|
||||||
QVector<QString> outputDevices = getDeviceNames(QAudio::AudioOutput);
|
QVector<QString> outputDevices = getDeviceNames(QAudio::AudioOutput);
|
||||||
|
|
||||||
|
@ -1290,6 +1293,7 @@ void AudioClient::checkDevices() {
|
||||||
|
|
||||||
emit deviceChanged();
|
emit deviceChanged();
|
||||||
}
|
}
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioClient::loadSettings() {
|
void AudioClient::loadSettings() {
|
||||||
|
|
|
@ -524,9 +524,9 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (useMeters) {
|
if (useMeters) {
|
||||||
READ_ENTITY_PROPERTY_SETTER(PROP_DIMENSIONS, glm::vec3, setDimensions);
|
READ_ENTITY_PROPERTY_SETTER(PROP_DIMENSIONS, glm::vec3, updateDimensions);
|
||||||
} else {
|
} else {
|
||||||
READ_ENTITY_PROPERTY_SETTER(PROP_DIMENSIONS, glm::vec3, setDimensionsInDomainUnits);
|
READ_ENTITY_PROPERTY_SETTER(PROP_DIMENSIONS, glm::vec3, updateDimensionsInDomainUnits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -920,6 +920,11 @@ int EntityTree::processEraseMessage(const QByteArray& dataByteArray, const Share
|
||||||
|
|
||||||
EntityItemID entityItemID(entityID);
|
EntityItemID entityItemID(entityID);
|
||||||
entityItemIDsToDelete << entityItemID;
|
entityItemIDsToDelete << entityItemID;
|
||||||
|
|
||||||
|
if (wantEditLogging()) {
|
||||||
|
qDebug() << "User [" << sourceNode->getUUID() << "] deleting entity. ID:" << entityItemID;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
deleteEntities(entityItemIDsToDelete, true, true);
|
deleteEntities(entityItemIDsToDelete, true, true);
|
||||||
}
|
}
|
||||||
|
@ -959,6 +964,11 @@ int EntityTree::processEraseMessageDetails(const QByteArray& dataByteArray, cons
|
||||||
|
|
||||||
EntityItemID entityItemID(entityID);
|
EntityItemID entityItemID(entityID);
|
||||||
entityItemIDsToDelete << entityItemID;
|
entityItemIDsToDelete << entityItemID;
|
||||||
|
|
||||||
|
if (wantEditLogging()) {
|
||||||
|
qDebug() << "User [" << sourceNode->getUUID() << "] deleting entity. ID:" << entityItemID;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
deleteEntities(entityItemIDsToDelete, true, true);
|
deleteEntities(entityItemIDsToDelete, true, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,8 +41,16 @@ LightEntityItem::LightEntityItem(const EntityItemID& entityItemID, const EntityI
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightEntityItem::setDimensions(const glm::vec3& value) {
|
void LightEntityItem::setDimensions(const glm::vec3& value) {
|
||||||
float maxDimension = glm::max(value.x, value.y, value.z);
|
if (_isSpotlight) {
|
||||||
_dimensions = glm::vec3(maxDimension, maxDimension, maxDimension);
|
// If we are a spotlight, treat the z value as our radius or length, and
|
||||||
|
// recalculate the x/y dimensions to properly encapsulate the spotlight.
|
||||||
|
const float length = value.z;
|
||||||
|
const float width = length * glm::tan(glm::radians(_cutoff));
|
||||||
|
_dimensions = glm::vec3(width, width, length);
|
||||||
|
} else {
|
||||||
|
float maxDimension = glm::max(value.x, value.y, value.z);
|
||||||
|
_dimensions = glm::vec3(maxDimension, maxDimension, maxDimension);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,6 +66,33 @@ EntityItemProperties LightEntityItem::getProperties() const {
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LightEntityItem::setIsSpotlight(bool value) {
|
||||||
|
if (value != _isSpotlight) {
|
||||||
|
_isSpotlight = value;
|
||||||
|
|
||||||
|
if (_isSpotlight) {
|
||||||
|
const float length = _dimensions.z;
|
||||||
|
const float width = length * glm::tan(glm::radians(_cutoff));
|
||||||
|
_dimensions = glm::vec3(width, width, length);
|
||||||
|
} else {
|
||||||
|
float maxDimension = glm::max(_dimensions.x, _dimensions.y, _dimensions.z);
|
||||||
|
_dimensions = glm::vec3(maxDimension, maxDimension, maxDimension);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LightEntityItem::setCutoff(float value) {
|
||||||
|
_cutoff = glm::clamp(value, 0.0f, 90.0f);
|
||||||
|
|
||||||
|
if (_isSpotlight) {
|
||||||
|
// If we are a spotlight, adjusting the cutoff will affect the area we encapsulate,
|
||||||
|
// so update the dimensions to reflect this.
|
||||||
|
const float length = _dimensions.z;
|
||||||
|
const float width = length * glm::tan(glm::radians(_cutoff));
|
||||||
|
_dimensions = glm::vec3(width, width, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool LightEntityItem::setProperties(const EntityItemProperties& properties) {
|
bool LightEntityItem::setProperties(const EntityItemProperties& properties) {
|
||||||
bool somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
|
bool somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getIsSpotlight() const { return _isSpotlight; }
|
bool getIsSpotlight() const { return _isSpotlight; }
|
||||||
void setIsSpotlight(bool value) { _isSpotlight = value; }
|
void setIsSpotlight(bool value);
|
||||||
|
|
||||||
float getIntensity() const { return _intensity; }
|
float getIntensity() const { return _intensity; }
|
||||||
void setIntensity(float value) { _intensity = value; }
|
void setIntensity(float value) { _intensity = value; }
|
||||||
|
@ -65,7 +65,7 @@ public:
|
||||||
void setExponent(float value) { _exponent = value; }
|
void setExponent(float value) { _exponent = value; }
|
||||||
|
|
||||||
float getCutoff() const { return _cutoff; }
|
float getCutoff() const { return _cutoff; }
|
||||||
void setCutoff(float value) { _cutoff = value; }
|
void setCutoff(float value);
|
||||||
|
|
||||||
static bool getLightsArePickable() { return _lightsArePickable; }
|
static bool getLightsArePickable() { return _lightsArePickable; }
|
||||||
static void setLightsArePickable(bool value) { _lightsArePickable = value; }
|
static void setLightsArePickable(bool value) { _lightsArePickable = value; }
|
||||||
|
|
|
@ -104,7 +104,7 @@ void makeBindings(GLBackend::GLShader* shader) {
|
||||||
loc = glGetUniformBlockIndex(glprogram, "transformCameraBuffer");
|
loc = glGetUniformBlockIndex(glprogram, "transformCameraBuffer");
|
||||||
if (loc >= 0) {
|
if (loc >= 0) {
|
||||||
glUniformBlockBinding(glprogram, loc, gpu::TRANSFORM_CAMERA_SLOT);
|
glUniformBlockBinding(glprogram, loc, gpu::TRANSFORM_CAMERA_SLOT);
|
||||||
shader->_transformCameraSlot = gpu::TRANSFORM_OBJECT_SLOT;
|
shader->_transformCameraSlot = gpu::TRANSFORM_CAMERA_SLOT;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
#include "DataServerAccountInfo.h"
|
#include "DataServerAccountInfo.h"
|
||||||
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
|
||||||
DataServerAccountInfo::DataServerAccountInfo() :
|
DataServerAccountInfo::DataServerAccountInfo() :
|
||||||
_accessToken(),
|
_accessToken(),
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
|
|
||||||
#include "RSAKeypairGenerator.h"
|
#include "RSAKeypairGenerator.h"
|
||||||
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
|
||||||
RSAKeypairGenerator::RSAKeypairGenerator(QObject* parent) :
|
RSAKeypairGenerator::RSAKeypairGenerator(QObject* parent) :
|
||||||
QObject(parent)
|
QObject(parent)
|
||||||
|
|
|
@ -257,6 +257,7 @@ btPairCachingGhostObject* CharacterController::getGhostObject() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorld) {
|
bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorld) {
|
||||||
|
BT_PROFILE("recoverFromPenetration");
|
||||||
// Here we must refresh the overlapping paircache as the penetrating movement itself or the
|
// Here we must refresh the overlapping paircache as the penetrating movement itself or the
|
||||||
// previous recovery iteration might have used setWorldTransform and pushed us into an object
|
// previous recovery iteration might have used setWorldTransform and pushed us into an object
|
||||||
// that is not in the previous cache contents from the last timestep, as will happen if we
|
// that is not in the previous cache contents from the last timestep, as will happen if we
|
||||||
|
@ -355,6 +356,7 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl
|
||||||
|
|
||||||
|
|
||||||
void CharacterController::scanDown(btCollisionWorld* world) {
|
void CharacterController::scanDown(btCollisionWorld* world) {
|
||||||
|
BT_PROFILE("scanDown");
|
||||||
// we test with downward raycast and if we don't find floor close enough then turn on "hover"
|
// we test with downward raycast and if we don't find floor close enough then turn on "hover"
|
||||||
btKinematicClosestNotMeRayResultCallback callback(_ghostObject);
|
btKinematicClosestNotMeRayResultCallback callback(_ghostObject);
|
||||||
callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
|
callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
|
||||||
|
@ -374,6 +376,7 @@ void CharacterController::scanDown(btCollisionWorld* world) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterController::stepUp(btCollisionWorld* world) {
|
void CharacterController::stepUp(btCollisionWorld* world) {
|
||||||
|
BT_PROFILE("stepUp");
|
||||||
// phase 1: up
|
// phase 1: up
|
||||||
|
|
||||||
// compute start and end
|
// compute start and end
|
||||||
|
@ -440,6 +443,7 @@ void CharacterController::updateTargetPositionBasedOnCollision(const btVector3&
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterController::stepForward(btCollisionWorld* collisionWorld, const btVector3& movement) {
|
void CharacterController::stepForward(btCollisionWorld* collisionWorld, const btVector3& movement) {
|
||||||
|
BT_PROFILE("stepForward");
|
||||||
// phase 2: forward
|
// phase 2: forward
|
||||||
_targetPosition = _currentPosition + movement;
|
_targetPosition = _currentPosition + movement;
|
||||||
|
|
||||||
|
@ -496,6 +500,7 @@ void CharacterController::stepForward(btCollisionWorld* collisionWorld, const bt
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt) {
|
void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt) {
|
||||||
|
BT_PROFILE("stepDown");
|
||||||
// phase 3: down
|
// phase 3: down
|
||||||
//
|
//
|
||||||
// The "stepDown" phase first makes a normal sweep down that cancels the lift from the "stepUp" phase.
|
// The "stepDown" phase first makes a normal sweep down that cancels the lift from the "stepUp" phase.
|
||||||
|
@ -607,6 +612,7 @@ void CharacterController::warp(const btVector3& origin) {
|
||||||
|
|
||||||
|
|
||||||
void CharacterController::preStep(btCollisionWorld* collisionWorld) {
|
void CharacterController::preStep(btCollisionWorld* collisionWorld) {
|
||||||
|
BT_PROFILE("preStep");
|
||||||
if (!_enabled) {
|
if (!_enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -627,6 +633,7 @@ void CharacterController::preStep(btCollisionWorld* collisionWorld) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar dt) {
|
void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar dt) {
|
||||||
|
BT_PROFILE("playerStep");
|
||||||
if (!_enabled) {
|
if (!_enabled) {
|
||||||
return; // no motion
|
return; // no motion
|
||||||
}
|
}
|
||||||
|
@ -875,6 +882,7 @@ void CharacterController::updateShapeIfNecessary() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterController::preSimulation(btScalar timeStep) {
|
void CharacterController::preSimulation(btScalar timeStep) {
|
||||||
|
BT_PROFILE("preSimulation");
|
||||||
if (_enabled && _dynamicsWorld) {
|
if (_enabled && _dynamicsWorld) {
|
||||||
glm::quat rotation = _avatarData->getOrientation();
|
glm::quat rotation = _avatarData->getOrientation();
|
||||||
_currentUp = quatRotate(glmToBullet(rotation), LOCAL_UP_AXIS);
|
_currentUp = quatRotate(glmToBullet(rotation), LOCAL_UP_AXIS);
|
||||||
|
@ -897,6 +905,7 @@ void CharacterController::preSimulation(btScalar timeStep) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterController::postSimulation() {
|
void CharacterController::postSimulation() {
|
||||||
|
BT_PROFILE("postSimulation");
|
||||||
if (_enabled && _ghostObject) {
|
if (_enabled && _ghostObject) {
|
||||||
const btTransform& avatarTransform = _ghostObject->getWorldTransform();
|
const btTransform& avatarTransform = _ghostObject->getWorldTransform();
|
||||||
glm::quat rotation = bulletToGLM(avatarTransform.getRotation());
|
glm::quat rotation = bulletToGLM(avatarTransform.getRotation());
|
||||||
|
|
|
@ -155,6 +155,7 @@ void PhysicsEngine::clearEntitiesInternal() {
|
||||||
// end EntitySimulation overrides
|
// end EntitySimulation overrides
|
||||||
|
|
||||||
void PhysicsEngine::relayIncomingChangesToSimulation() {
|
void PhysicsEngine::relayIncomingChangesToSimulation() {
|
||||||
|
BT_PROFILE("incomingChanges");
|
||||||
// process incoming changes
|
// process incoming changes
|
||||||
QSet<ObjectMotionState*>::iterator stateItr = _incomingChanges.begin();
|
QSet<ObjectMotionState*>::iterator stateItr = _incomingChanges.begin();
|
||||||
while (stateItr != _incomingChanges.end()) {
|
while (stateItr != _incomingChanges.end()) {
|
||||||
|
@ -287,66 +288,76 @@ void PhysicsEngine::init(EntityEditPacketSender* packetSender) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsEngine::stepSimulation() {
|
void PhysicsEngine::stepSimulation() {
|
||||||
lock();
|
{
|
||||||
// NOTE: the grand order of operations is:
|
|
||||||
// (1) pull incoming changes
|
|
||||||
// (2) step simulation
|
|
||||||
// (3) synchronize outgoing motion states
|
|
||||||
// (4) send outgoing packets
|
|
||||||
|
|
||||||
// This is step (1) pull incoming changes
|
|
||||||
relayIncomingChangesToSimulation();
|
|
||||||
|
|
||||||
const int MAX_NUM_SUBSTEPS = 4;
|
|
||||||
const float MAX_TIMESTEP = (float)MAX_NUM_SUBSTEPS * PHYSICS_ENGINE_FIXED_SUBSTEP;
|
|
||||||
float dt = 1.0e-6f * (float)(_clock.getTimeMicroseconds());
|
|
||||||
_clock.reset();
|
|
||||||
float timeStep = btMin(dt, MAX_TIMESTEP);
|
|
||||||
|
|
||||||
// TODO: move character->preSimulation() into relayIncomingChanges
|
|
||||||
if (_characterController) {
|
|
||||||
if (_characterController->needsRemoval()) {
|
|
||||||
_characterController->setDynamicsWorld(NULL);
|
|
||||||
}
|
|
||||||
_characterController->updateShapeIfNecessary();
|
|
||||||
if (_characterController->needsAddition()) {
|
|
||||||
_characterController->setDynamicsWorld(_dynamicsWorld);
|
|
||||||
}
|
|
||||||
_characterController->preSimulation(timeStep);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is step (2) step simulation
|
|
||||||
int numSubsteps = _dynamicsWorld->stepSimulation(timeStep, MAX_NUM_SUBSTEPS, PHYSICS_ENGINE_FIXED_SUBSTEP);
|
|
||||||
_numSubsteps += (uint32_t)numSubsteps;
|
|
||||||
stepNonPhysicalKinematics(usecTimestampNow());
|
|
||||||
unlock();
|
|
||||||
|
|
||||||
// TODO: make all of this harvest stuff into one function: relayOutgoingChanges()
|
|
||||||
if (numSubsteps > 0) {
|
|
||||||
// This is step (3) which is done outside of stepSimulation() so we can lock _entityTree.
|
|
||||||
//
|
|
||||||
// Unfortunately we have to unlock the simulation (above) before we try to lock the _entityTree
|
|
||||||
// to avoid deadlock -- the _entityTree may try to lock its EntitySimulation (from which this
|
|
||||||
// PhysicsEngine derives) when updating/adding/deleting entities so we need to wait for our own
|
|
||||||
// lock on the tree before we re-lock ourselves.
|
|
||||||
//
|
|
||||||
// TODO: untangle these lock sequences.
|
|
||||||
_entityTree->lockForWrite();
|
|
||||||
lock();
|
lock();
|
||||||
_dynamicsWorld->synchronizeMotionStates();
|
CProfileManager::Reset();
|
||||||
|
BT_PROFILE("stepSimulation");
|
||||||
|
// NOTE: the grand order of operations is:
|
||||||
|
// (1) pull incoming changes
|
||||||
|
// (2) step simulation
|
||||||
|
// (3) synchronize outgoing motion states
|
||||||
|
// (4) send outgoing packets
|
||||||
|
|
||||||
if (_characterController) {
|
// This is step (1) pull incoming changes
|
||||||
_characterController->postSimulation();
|
relayIncomingChangesToSimulation();
|
||||||
}
|
|
||||||
|
|
||||||
unlock();
|
|
||||||
_entityTree->unlock();
|
|
||||||
|
|
||||||
computeCollisionEvents();
|
const int MAX_NUM_SUBSTEPS = 4;
|
||||||
|
const float MAX_TIMESTEP = (float)MAX_NUM_SUBSTEPS * PHYSICS_ENGINE_FIXED_SUBSTEP;
|
||||||
|
float dt = 1.0e-6f * (float)(_clock.getTimeMicroseconds());
|
||||||
|
_clock.reset();
|
||||||
|
float timeStep = btMin(dt, MAX_TIMESTEP);
|
||||||
|
|
||||||
|
// TODO: move character->preSimulation() into relayIncomingChanges
|
||||||
|
if (_characterController) {
|
||||||
|
if (_characterController->needsRemoval()) {
|
||||||
|
_characterController->setDynamicsWorld(NULL);
|
||||||
|
}
|
||||||
|
_characterController->updateShapeIfNecessary();
|
||||||
|
if (_characterController->needsAddition()) {
|
||||||
|
_characterController->setDynamicsWorld(_dynamicsWorld);
|
||||||
|
}
|
||||||
|
_characterController->preSimulation(timeStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is step (2) step simulation
|
||||||
|
int numSubsteps = _dynamicsWorld->stepSimulation(timeStep, MAX_NUM_SUBSTEPS, PHYSICS_ENGINE_FIXED_SUBSTEP);
|
||||||
|
_numSubsteps += (uint32_t)numSubsteps;
|
||||||
|
stepNonPhysicalKinematics(usecTimestampNow());
|
||||||
|
unlock();
|
||||||
|
|
||||||
|
// TODO: make all of this harvest stuff into one function: relayOutgoingChanges()
|
||||||
|
if (numSubsteps > 0) {
|
||||||
|
BT_PROFILE("postSimulation");
|
||||||
|
// This is step (3) which is done outside of stepSimulation() so we can lock _entityTree.
|
||||||
|
//
|
||||||
|
// Unfortunately we have to unlock the simulation (above) before we try to lock the _entityTree
|
||||||
|
// to avoid deadlock -- the _entityTree may try to lock its EntitySimulation (from which this
|
||||||
|
// PhysicsEngine derives) when updating/adding/deleting entities so we need to wait for our own
|
||||||
|
// lock on the tree before we re-lock ourselves.
|
||||||
|
//
|
||||||
|
// TODO: untangle these lock sequences.
|
||||||
|
_entityTree->lockForWrite();
|
||||||
|
lock();
|
||||||
|
_dynamicsWorld->synchronizeMotionStates();
|
||||||
|
|
||||||
|
if (_characterController) {
|
||||||
|
_characterController->postSimulation();
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock();
|
||||||
|
_entityTree->unlock();
|
||||||
|
|
||||||
|
computeCollisionEvents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_dumpNextStats) {
|
||||||
|
_dumpNextStats = false;
|
||||||
|
CProfileManager::dumpAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsEngine::stepNonPhysicalKinematics(const quint64& now) {
|
void PhysicsEngine::stepNonPhysicalKinematics(const quint64& now) {
|
||||||
|
BT_PROFILE("nonPhysicalKinematics");
|
||||||
QSet<ObjectMotionState*>::iterator stateItr = _nonPhysicalKinematicObjects.begin();
|
QSet<ObjectMotionState*>::iterator stateItr = _nonPhysicalKinematicObjects.begin();
|
||||||
while (stateItr != _nonPhysicalKinematicObjects.end()) {
|
while (stateItr != _nonPhysicalKinematicObjects.end()) {
|
||||||
ObjectMotionState* motionState = *stateItr;
|
ObjectMotionState* motionState = *stateItr;
|
||||||
|
@ -358,6 +369,7 @@ void PhysicsEngine::stepNonPhysicalKinematics(const quint64& now) {
|
||||||
// TODO?: need to occasionally scan for stopped non-physical kinematics objects
|
// TODO?: need to occasionally scan for stopped non-physical kinematics objects
|
||||||
|
|
||||||
void PhysicsEngine::computeCollisionEvents() {
|
void PhysicsEngine::computeCollisionEvents() {
|
||||||
|
BT_PROFILE("computeCollisionEvents");
|
||||||
// update all contacts every frame
|
// update all contacts every frame
|
||||||
int numManifolds = _collisionDispatcher->getNumManifolds();
|
int numManifolds = _collisionDispatcher->getNumManifolds();
|
||||||
for (int i = 0; i < numManifolds; ++i) {
|
for (int i = 0; i < numManifolds; ++i) {
|
||||||
|
|
|
@ -86,6 +86,8 @@ public:
|
||||||
|
|
||||||
void setCharacterController(CharacterController* character);
|
void setCharacterController(CharacterController* character);
|
||||||
|
|
||||||
|
void dumpNextStats() { _dumpNextStats = true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// \param motionState pointer to Object's MotionState
|
/// \param motionState pointer to Object's MotionState
|
||||||
void removeObjectFromBullet(ObjectMotionState* motionState);
|
void removeObjectFromBullet(ObjectMotionState* motionState);
|
||||||
|
@ -121,6 +123,8 @@ private:
|
||||||
|
|
||||||
/// character collisions
|
/// character collisions
|
||||||
CharacterController* _characterController = NULL;
|
CharacterController* _characterController = NULL;
|
||||||
|
|
||||||
|
bool _dumpNextStats = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_PhysicsEngine_h
|
#endif // hifi_PhysicsEngine_h
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
* Copied and modified from btDiscreteDynamicsWorld.cpp by AndrewMeadows on 2014.11.12.
|
* Copied and modified from btDiscreteDynamicsWorld.cpp by AndrewMeadows on 2014.11.12.
|
||||||
* */
|
* */
|
||||||
|
|
||||||
|
#include <LinearMath/btQuickprof.h>
|
||||||
|
|
||||||
#include "ThreadSafeDynamicsWorld.h"
|
#include "ThreadSafeDynamicsWorld.h"
|
||||||
|
|
||||||
ThreadSafeDynamicsWorld::ThreadSafeDynamicsWorld(
|
ThreadSafeDynamicsWorld::ThreadSafeDynamicsWorld(
|
||||||
|
@ -25,50 +27,51 @@ ThreadSafeDynamicsWorld::ThreadSafeDynamicsWorld(
|
||||||
: btDiscreteDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration) {
|
: btDiscreteDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int ThreadSafeDynamicsWorld::stepSimulation( btScalar timeStep, int maxSubSteps, btScalar fixedTimeStep) {
|
int ThreadSafeDynamicsWorld::stepSimulation( btScalar timeStep, int maxSubSteps, btScalar fixedTimeStep) {
|
||||||
int subSteps = 0;
|
BT_PROFILE("stepSimulation");
|
||||||
if (maxSubSteps) {
|
int subSteps = 0;
|
||||||
//fixed timestep with interpolation
|
if (maxSubSteps) {
|
||||||
m_fixedTimeStep = fixedTimeStep;
|
//fixed timestep with interpolation
|
||||||
m_localTime += timeStep;
|
m_fixedTimeStep = fixedTimeStep;
|
||||||
if (m_localTime >= fixedTimeStep)
|
m_localTime += timeStep;
|
||||||
{
|
if (m_localTime >= fixedTimeStep)
|
||||||
subSteps = int( m_localTime / fixedTimeStep);
|
{
|
||||||
m_localTime -= subSteps * fixedTimeStep;
|
subSteps = int( m_localTime / fixedTimeStep);
|
||||||
}
|
m_localTime -= subSteps * fixedTimeStep;
|
||||||
} else {
|
}
|
||||||
//variable timestep
|
} else {
|
||||||
fixedTimeStep = timeStep;
|
//variable timestep
|
||||||
m_localTime = m_latencyMotionStateInterpolation ? 0 : timeStep;
|
fixedTimeStep = timeStep;
|
||||||
m_fixedTimeStep = 0;
|
m_localTime = m_latencyMotionStateInterpolation ? 0 : timeStep;
|
||||||
if (btFuzzyZero(timeStep))
|
m_fixedTimeStep = 0;
|
||||||
{
|
if (btFuzzyZero(timeStep))
|
||||||
subSteps = 0;
|
{
|
||||||
maxSubSteps = 0;
|
subSteps = 0;
|
||||||
} else
|
maxSubSteps = 0;
|
||||||
{
|
} else
|
||||||
subSteps = 1;
|
{
|
||||||
maxSubSteps = 1;
|
subSteps = 1;
|
||||||
}
|
maxSubSteps = 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*//process some debugging flags
|
/*//process some debugging flags
|
||||||
if (getDebugDrawer()) {
|
if (getDebugDrawer()) {
|
||||||
btIDebugDraw* debugDrawer = getDebugDrawer ();
|
btIDebugDraw* debugDrawer = getDebugDrawer ();
|
||||||
gDisableDeactivation = (debugDrawer->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0;
|
gDisableDeactivation = (debugDrawer->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0;
|
||||||
}*/
|
}*/
|
||||||
if (subSteps) {
|
if (subSteps) {
|
||||||
//clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
|
//clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
|
||||||
int clampedSimulationSteps = (subSteps > maxSubSteps)? maxSubSteps : subSteps;
|
int clampedSimulationSteps = (subSteps > maxSubSteps)? maxSubSteps : subSteps;
|
||||||
|
|
||||||
saveKinematicState(fixedTimeStep*clampedSimulationSteps);
|
saveKinematicState(fixedTimeStep*clampedSimulationSteps);
|
||||||
|
|
||||||
applyGravity();
|
applyGravity();
|
||||||
|
|
||||||
for (int i=0;i<clampedSimulationSteps;i++) {
|
for (int i=0;i<clampedSimulationSteps;i++) {
|
||||||
internalSingleStepSimulation(fixedTimeStep);
|
internalSingleStepSimulation(fixedTimeStep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: We do NOT call synchronizeMotionState() after each substep (to avoid multiple locks on the
|
// NOTE: We do NOT call synchronizeMotionState() after each substep (to avoid multiple locks on the
|
||||||
// object data outside of the physics engine). A consequence of this is that the transforms of the
|
// object data outside of the physics engine). A consequence of this is that the transforms of the
|
||||||
|
@ -77,7 +80,7 @@ int ThreadSafeDynamicsWorld::stepSimulation( btScalar timeStep, int maxSubSteps,
|
||||||
// NOTE: We do NOT call synchronizeMotionStates() here. Instead it is called by an external class
|
// NOTE: We do NOT call synchronizeMotionStates() here. Instead it is called by an external class
|
||||||
// that knows how to lock threads correctly.
|
// that knows how to lock threads correctly.
|
||||||
|
|
||||||
clearForces();
|
clearForces();
|
||||||
|
|
||||||
return subSteps;
|
return subSteps;
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,18 +121,20 @@ Model::Locations Model::_normalMapLocations;
|
||||||
Model::Locations Model::_specularMapLocations;
|
Model::Locations Model::_specularMapLocations;
|
||||||
Model::Locations Model::_normalSpecularMapLocations;
|
Model::Locations Model::_normalSpecularMapLocations;
|
||||||
Model::Locations Model::_translucentLocations;
|
Model::Locations Model::_translucentLocations;
|
||||||
|
Model::Locations Model::_shadowLocations;
|
||||||
|
|
||||||
Model::Locations Model::_lightmapLocations;
|
Model::Locations Model::_lightmapLocations;
|
||||||
Model::Locations Model::_lightmapNormalMapLocations;
|
Model::Locations Model::_lightmapNormalMapLocations;
|
||||||
Model::Locations Model::_lightmapSpecularMapLocations;
|
Model::Locations Model::_lightmapSpecularMapLocations;
|
||||||
Model::Locations Model::_lightmapNormalSpecularMapLocations;
|
Model::Locations Model::_lightmapNormalSpecularMapLocations;
|
||||||
|
|
||||||
|
|
||||||
Model::SkinLocations Model::_skinLocations;
|
Model::SkinLocations Model::_skinLocations;
|
||||||
Model::SkinLocations Model::_skinNormalMapLocations;
|
Model::SkinLocations Model::_skinNormalMapLocations;
|
||||||
Model::SkinLocations Model::_skinSpecularMapLocations;
|
Model::SkinLocations Model::_skinSpecularMapLocations;
|
||||||
Model::SkinLocations Model::_skinNormalSpecularMapLocations;
|
Model::SkinLocations Model::_skinNormalSpecularMapLocations;
|
||||||
Model::SkinLocations Model::_skinShadowLocations;
|
|
||||||
Model::SkinLocations Model::_skinTranslucentLocations;
|
Model::SkinLocations Model::_skinTranslucentLocations;
|
||||||
|
Model::SkinLocations Model::_skinShadowLocations;
|
||||||
|
|
||||||
AbstractViewStateInterface* Model::_viewState = NULL;
|
AbstractViewStateInterface* Model::_viewState = NULL;
|
||||||
|
|
||||||
|
@ -284,8 +286,7 @@ void Model::init() {
|
||||||
|
|
||||||
_shadowProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelShadowVertex, modelShadowPixel));
|
_shadowProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelShadowVertex, modelShadowPixel));
|
||||||
makeResult = gpu::Shader::makeProgram(*_shadowProgram, slotBindings);
|
makeResult = gpu::Shader::makeProgram(*_shadowProgram, slotBindings);
|
||||||
Model::Locations tempShadowLoc;
|
initProgram(_shadowProgram, _shadowLocations);
|
||||||
initProgram(_shadowProgram, tempShadowLoc);
|
|
||||||
|
|
||||||
_lightmapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelLightmapVertex, modelLightmapPixel));
|
_lightmapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelLightmapVertex, modelLightmapPixel));
|
||||||
makeResult = gpu::Shader::makeProgram(*_lightmapProgram, slotBindings);
|
makeResult = gpu::Shader::makeProgram(*_lightmapProgram, slotBindings);
|
||||||
|
@ -656,7 +657,7 @@ bool Model::render(float alpha, RenderMode mode, RenderArgs* args) {
|
||||||
renderSetup(args);
|
renderSetup(args);
|
||||||
return renderCore(alpha, mode, args);
|
return renderCore(alpha, mode, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
if (!_viewState) {
|
if (!_viewState) {
|
||||||
|
@ -670,7 +671,12 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
||||||
// Setup the projection matrix
|
// Setup the projection matrix
|
||||||
if (args && args->_viewFrustum) {
|
if (args && args->_viewFrustum) {
|
||||||
glm::mat4 proj;
|
glm::mat4 proj;
|
||||||
args->_viewFrustum->evalProjectionMatrix(proj);
|
// If for easier debug depending on the pass
|
||||||
|
if (mode == RenderArgs::SHADOW_RENDER_MODE) {
|
||||||
|
args->_viewFrustum->evalProjectionMatrix(proj);
|
||||||
|
} else {
|
||||||
|
args->_viewFrustum->evalProjectionMatrix(proj);
|
||||||
|
}
|
||||||
batch.setProjectionTransform(proj);
|
batch.setProjectionTransform(proj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -678,7 +684,9 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
||||||
if (_transforms.empty()) {
|
if (_transforms.empty()) {
|
||||||
_transforms.push_back(Transform());
|
_transforms.push_back(Transform());
|
||||||
}
|
}
|
||||||
|
|
||||||
_transforms[0] = _viewState->getViewTransform();
|
_transforms[0] = _viewState->getViewTransform();
|
||||||
|
|
||||||
// apply entity translation offset to the viewTransform in one go (it's a preTranslate because viewTransform goes from world to eye space)
|
// apply entity translation offset to the viewTransform in one go (it's a preTranslate because viewTransform goes from world to eye space)
|
||||||
_transforms[0].preTranslate(-_translation);
|
_transforms[0].preTranslate(-_translation);
|
||||||
|
|
||||||
|
@ -699,7 +707,7 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
||||||
|
|
||||||
GLBATCH(glDisable)(GL_BLEND);
|
GLBATCH(glDisable)(GL_BLEND);
|
||||||
GLBATCH(glEnable)(GL_ALPHA_TEST);
|
GLBATCH(glEnable)(GL_ALPHA_TEST);
|
||||||
|
|
||||||
if (mode == SHADOW_RENDER_MODE) {
|
if (mode == SHADOW_RENDER_MODE) {
|
||||||
GLBATCH(glAlphaFunc)(GL_EQUAL, 0.0f);
|
GLBATCH(glAlphaFunc)(GL_EQUAL, 0.0f);
|
||||||
}
|
}
|
||||||
|
@ -1710,14 +1718,19 @@ void Model::startScene(RenderArgs::RenderSide renderSide) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::setupBatchTransform(gpu::Batch& batch) {
|
void Model::setupBatchTransform(gpu::Batch& batch, RenderArgs* args) {
|
||||||
|
|
||||||
// Capture the view matrix once for the rendering of this model
|
// Capture the view matrix once for the rendering of this model
|
||||||
if (_transforms.empty()) {
|
if (_transforms.empty()) {
|
||||||
_transforms.push_back(Transform());
|
_transforms.push_back(Transform());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We should be able to use the Frustum viewpoint onstead of the "viewTransform"
|
||||||
|
// but it s still buggy in some cases, so let's s wait and fix it...
|
||||||
_transforms[0] = _viewState->getViewTransform();
|
_transforms[0] = _viewState->getViewTransform();
|
||||||
|
|
||||||
_transforms[0].preTranslate(-_translation);
|
_transforms[0].preTranslate(-_translation);
|
||||||
|
|
||||||
batch.setViewTransform(_transforms[0]);
|
batch.setViewTransform(_transforms[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1738,7 +1751,12 @@ void Model::endScene(RenderMode mode, RenderArgs* args) {
|
||||||
|
|
||||||
if (args) {
|
if (args) {
|
||||||
glm::mat4 proj;
|
glm::mat4 proj;
|
||||||
args->_viewFrustum->evalProjectionMatrix(proj);
|
// If for easier debug depending on the pass
|
||||||
|
if (mode == RenderArgs::SHADOW_RENDER_MODE) {
|
||||||
|
args->_viewFrustum->evalProjectionMatrix(proj);
|
||||||
|
} else {
|
||||||
|
args->_viewFrustum->evalProjectionMatrix(proj);
|
||||||
|
}
|
||||||
gpu::Batch batch;
|
gpu::Batch batch;
|
||||||
batch.setProjectionTransform(proj);
|
batch.setProjectionTransform(proj);
|
||||||
backend.render(batch);
|
backend.render(batch);
|
||||||
|
@ -2286,6 +2304,7 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f
|
||||||
skinLocations = &_skinLocations;
|
skinLocations = &_skinLocations;
|
||||||
if (mode == SHADOW_RENDER_MODE) {
|
if (mode == SHADOW_RENDER_MODE) {
|
||||||
program = _shadowProgram;
|
program = _shadowProgram;
|
||||||
|
locations = &_shadowLocations;
|
||||||
skinProgram = _skinShadowProgram;
|
skinProgram = _skinShadowProgram;
|
||||||
skinLocations = &_skinShadowLocations;
|
skinLocations = &_skinShadowLocations;
|
||||||
} else if (translucent && alphaThreshold == 0.0f) {
|
} else if (translucent && alphaThreshold == 0.0f) {
|
||||||
|
@ -2376,7 +2395,7 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool
|
||||||
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, args, locations, skinLocations);
|
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, args, locations, skinLocations);
|
||||||
pickProgramsNeeded = false;
|
pickProgramsNeeded = false;
|
||||||
}
|
}
|
||||||
model->setupBatchTransform(batch);
|
model->setupBatchTransform(batch, args);
|
||||||
meshPartsRendered += model->renderMeshesFromList(list, batch, mode, translucent, alphaThreshold, args, locations, skinLocations);
|
meshPartsRendered += model->renderMeshesFromList(list, batch, mode, translucent, alphaThreshold, args, locations, skinLocations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -357,6 +357,7 @@ private:
|
||||||
static Locations _specularMapLocations;
|
static Locations _specularMapLocations;
|
||||||
static Locations _normalSpecularMapLocations;
|
static Locations _normalSpecularMapLocations;
|
||||||
static Locations _translucentLocations;
|
static Locations _translucentLocations;
|
||||||
|
static Locations _shadowLocations;
|
||||||
|
|
||||||
static Locations _lightmapLocations;
|
static Locations _lightmapLocations;
|
||||||
static Locations _lightmapNormalMapLocations;
|
static Locations _lightmapNormalMapLocations;
|
||||||
|
@ -377,8 +378,9 @@ private:
|
||||||
static SkinLocations _skinNormalMapLocations;
|
static SkinLocations _skinNormalMapLocations;
|
||||||
static SkinLocations _skinSpecularMapLocations;
|
static SkinLocations _skinSpecularMapLocations;
|
||||||
static SkinLocations _skinNormalSpecularMapLocations;
|
static SkinLocations _skinNormalSpecularMapLocations;
|
||||||
static SkinLocations _skinShadowLocations;
|
|
||||||
static SkinLocations _skinTranslucentLocations;
|
static SkinLocations _skinTranslucentLocations;
|
||||||
|
static SkinLocations _skinShadowLocations;
|
||||||
|
|
||||||
|
|
||||||
static void initSkinProgram(ProgramObject& program, SkinLocations& locations);
|
static void initSkinProgram(ProgramObject& program, SkinLocations& locations);
|
||||||
static void initSkinProgram(gpu::ShaderPointer& program, SkinLocations& locations);
|
static void initSkinProgram(gpu::ShaderPointer& program, SkinLocations& locations);
|
||||||
|
@ -463,7 +465,7 @@ private:
|
||||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args = NULL,
|
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args = NULL,
|
||||||
bool forceRenderMeshes = false);
|
bool forceRenderMeshes = false);
|
||||||
|
|
||||||
void setupBatchTransform(gpu::Batch& batch);
|
void setupBatchTransform(gpu::Batch& batch, RenderArgs* args);
|
||||||
QVector<int>* pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned);
|
QVector<int>* pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned);
|
||||||
|
|
||||||
int renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
int renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||||
|
|
Loading…
Reference in a new issue