mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 05:58:27 +02:00
Merge branch 'master' into hazeZone
This commit is contained in:
commit
f3147fc24f
7 changed files with 111 additions and 58 deletions
|
@ -1769,7 +1769,6 @@ void EntityItem::updateDimensions(const glm::vec3& value) {
|
||||||
setDimensions(value);
|
setDimensions(value);
|
||||||
markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS);
|
markDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS);
|
||||||
_queryAACubeSet = false;
|
_queryAACubeSet = false;
|
||||||
dimensionsChanged();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,12 +51,12 @@ namespace entity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// shapeCalculator is a hook for external code that knows how to configure a ShapeInfo
|
// hullShapeCalculator is a hook for external code that knows how to configure a ShapeInfo
|
||||||
// for given entity::Shape and dimensions
|
// for given entity::Shape and dimensions
|
||||||
ShapeEntityItem::ShapeInfoCalculator shapeCalculator = nullptr;
|
ShapeEntityItem::ShapeInfoCalculator hullShapeCalculator = nullptr;
|
||||||
|
|
||||||
void ShapeEntityItem::setShapeInfoCalulator(ShapeEntityItem::ShapeInfoCalculator callback) {
|
void ShapeEntityItem::setShapeInfoCalulator(ShapeEntityItem::ShapeInfoCalculator callback) {
|
||||||
shapeCalculator = callback;
|
hullShapeCalculator = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapeEntityItem::Pointer ShapeEntityItem::baseFactory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
ShapeEntityItem::Pointer ShapeEntityItem::baseFactory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
|
@ -104,6 +104,14 @@ void ShapeEntityItem::setShape(const entity::Shape& shape) {
|
||||||
case entity::Shape::Sphere:
|
case entity::Shape::Sphere:
|
||||||
_type = EntityTypes::Sphere;
|
_type = EntityTypes::Sphere;
|
||||||
break;
|
break;
|
||||||
|
case entity::Shape::Circle:
|
||||||
|
// Circle is implicitly flat so we enforce flat dimensions
|
||||||
|
setDimensions(getDimensions());
|
||||||
|
break;
|
||||||
|
case entity::Shape::Quad:
|
||||||
|
// Quad is implicitly flat so we enforce flat dimensions
|
||||||
|
setDimensions(getDimensions());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
_type = EntityTypes::Shape;
|
_type = EntityTypes::Shape;
|
||||||
break;
|
break;
|
||||||
|
@ -196,6 +204,18 @@ void ShapeEntityItem::setColor(const QColor& value) {
|
||||||
setAlpha(value.alpha());
|
setAlpha(value.alpha());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShapeEntityItem::setDimensions(const glm::vec3& value) {
|
||||||
|
const float MAX_FLAT_DIMENSION = 0.0001f;
|
||||||
|
if ((_shape == entity::Shape::Circle || _shape == entity::Shape::Quad) && value.y > MAX_FLAT_DIMENSION) {
|
||||||
|
// enforce flatness in Y
|
||||||
|
glm::vec3 newDimensions = value;
|
||||||
|
newDimensions.y = MAX_FLAT_DIMENSION;
|
||||||
|
EntityItem::setDimensions(newDimensions);
|
||||||
|
} else {
|
||||||
|
EntityItem::setDimensions(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ShapeEntityItem::supportsDetailedRayIntersection() const {
|
bool ShapeEntityItem::supportsDetailedRayIntersection() const {
|
||||||
return _shape == entity::Sphere;
|
return _shape == entity::Sphere;
|
||||||
}
|
}
|
||||||
|
@ -249,19 +269,13 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
const glm::vec3 entityDimensions = getDimensions();
|
const glm::vec3 entityDimensions = getDimensions();
|
||||||
|
|
||||||
switch (_shape){
|
switch (_shape){
|
||||||
case entity::Shape::Quad: {
|
case entity::Shape::Quad:
|
||||||
// Not in GeometryCache::buildShapes, unsupported.
|
// Quads collide like flat Cubes
|
||||||
_collisionShapeType = SHAPE_TYPE_ELLIPSOID;
|
|
||||||
//TODO WL21389: Add a SHAPE_TYPE_QUAD ShapeType and treat
|
|
||||||
// as a special box (later if desired support)
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case entity::Shape::Cube: {
|
case entity::Shape::Cube: {
|
||||||
_collisionShapeType = SHAPE_TYPE_BOX;
|
_collisionShapeType = SHAPE_TYPE_BOX;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case entity::Shape::Sphere: {
|
case entity::Shape::Sphere: {
|
||||||
|
|
||||||
float diameter = entityDimensions.x;
|
float diameter = entityDimensions.x;
|
||||||
const float MIN_DIAMETER = 0.001f;
|
const float MIN_DIAMETER = 0.001f;
|
||||||
const float MIN_RELATIVE_SPHERICAL_ERROR = 0.001f;
|
const float MIN_RELATIVE_SPHERICAL_ERROR = 0.001f;
|
||||||
|
@ -275,25 +289,28 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case entity::Shape::Circle: {
|
case entity::Shape::Circle:
|
||||||
_collisionShapeType = SHAPE_TYPE_CIRCLE;
|
// Circles collide like flat Cylinders
|
||||||
}
|
|
||||||
break;
|
|
||||||
case entity::Shape::Cylinder: {
|
case entity::Shape::Cylinder: {
|
||||||
_collisionShapeType = SHAPE_TYPE_CYLINDER_Y;
|
float diameter = entityDimensions.x;
|
||||||
// TODO WL21389: determine if rotation is axis-aligned
|
const float MIN_DIAMETER = 0.001f;
|
||||||
//const Transform::Quat & rot = _transform.getRotation();
|
const float MIN_RELATIVE_SPHERICAL_ERROR = 0.001f;
|
||||||
|
if (diameter > MIN_DIAMETER
|
||||||
// TODO WL21389: some way to tell apart SHAPE_TYPE_CYLINDER_Y, _X, _Z based on rotation and
|
&& fabsf(diameter - entityDimensions.z) / diameter < MIN_RELATIVE_SPHERICAL_ERROR) {
|
||||||
// hull ( or dimensions, need circular cross section)
|
_collisionShapeType = SHAPE_TYPE_SPHERE;
|
||||||
// Should allow for minor variance along axes?
|
} else if (hullShapeCalculator) {
|
||||||
|
hullShapeCalculator(this, info);
|
||||||
|
_collisionShapeType = SHAPE_TYPE_SIMPLE_HULL;
|
||||||
|
} else {
|
||||||
|
// woops, someone forgot to hook up the hullShapeCalculator()!
|
||||||
|
// final fallback is ellipsoid
|
||||||
|
_collisionShapeType = SHAPE_TYPE_ELLIPSOID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case entity::Shape::Cone: {
|
case entity::Shape::Cone: {
|
||||||
if (shapeCalculator) {
|
if (hullShapeCalculator) {
|
||||||
shapeCalculator(this, info);
|
hullShapeCalculator(this, info);
|
||||||
// shapeCalculator only supports convex shapes (e.g. SHAPE_TYPE_HULL)
|
|
||||||
_collisionShapeType = SHAPE_TYPE_SIMPLE_HULL;
|
_collisionShapeType = SHAPE_TYPE_SIMPLE_HULL;
|
||||||
} else {
|
} else {
|
||||||
_collisionShapeType = SHAPE_TYPE_ELLIPSOID;
|
_collisionShapeType = SHAPE_TYPE_ELLIPSOID;
|
||||||
|
@ -304,9 +321,8 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
case entity::Shape::Triangle:
|
case entity::Shape::Triangle:
|
||||||
case entity::Shape::Hexagon:
|
case entity::Shape::Hexagon:
|
||||||
case entity::Shape::Octagon: {
|
case entity::Shape::Octagon: {
|
||||||
if (shapeCalculator) {
|
if (hullShapeCalculator) {
|
||||||
shapeCalculator(this, info);
|
hullShapeCalculator(this, info);
|
||||||
// shapeCalculator only supports convex shapes (e.g. SHAPE_TYPE_HULL)
|
|
||||||
_collisionShapeType = SHAPE_TYPE_SIMPLE_HULL;
|
_collisionShapeType = SHAPE_TYPE_SIMPLE_HULL;
|
||||||
} else {
|
} else {
|
||||||
_collisionShapeType = SHAPE_TYPE_ELLIPSOID;
|
_collisionShapeType = SHAPE_TYPE_ELLIPSOID;
|
||||||
|
@ -318,9 +334,8 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
case entity::Shape::Octahedron:
|
case entity::Shape::Octahedron:
|
||||||
case entity::Shape::Dodecahedron:
|
case entity::Shape::Dodecahedron:
|
||||||
case entity::Shape::Icosahedron: {
|
case entity::Shape::Icosahedron: {
|
||||||
if ( shapeCalculator ) {
|
if ( hullShapeCalculator ) {
|
||||||
shapeCalculator(this, info);
|
hullShapeCalculator(this, info);
|
||||||
// shapeCalculator only supports convex shapes (e.g. SHAPE_TYPE_HULL)
|
|
||||||
_collisionShapeType = SHAPE_TYPE_SIMPLE_HULL;
|
_collisionShapeType = SHAPE_TYPE_SIMPLE_HULL;
|
||||||
} else {
|
} else {
|
||||||
_collisionShapeType = SHAPE_TYPE_ELLIPSOID;
|
_collisionShapeType = SHAPE_TYPE_ELLIPSOID;
|
||||||
|
@ -330,7 +345,7 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
case entity::Shape::Torus: {
|
case entity::Shape::Torus: {
|
||||||
// Not in GeometryCache::buildShapes, unsupported.
|
// Not in GeometryCache::buildShapes, unsupported.
|
||||||
_collisionShapeType = SHAPE_TYPE_ELLIPSOID;
|
_collisionShapeType = SHAPE_TYPE_ELLIPSOID;
|
||||||
//TODO WL21389: SHAPE_TYPE_SIMPLE_HULL and pointCollection (later if desired support)
|
//TODO handle this shape more correctly
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
|
|
|
@ -80,6 +80,8 @@ public:
|
||||||
const rgbColor& getColor() const { return _color; }
|
const rgbColor& getColor() const { return _color; }
|
||||||
void setColor(const rgbColor& value);
|
void setColor(const rgbColor& value);
|
||||||
|
|
||||||
|
void setDimensions(const glm::vec3& value) override;
|
||||||
|
|
||||||
xColor getXColor() const;
|
xColor getXColor() const;
|
||||||
void setColor(const xColor& value);
|
void setColor(const xColor& value);
|
||||||
|
|
||||||
|
|
|
@ -482,8 +482,10 @@ void GeometryCache::buildShapes() {
|
||||||
using namespace geometry;
|
using namespace geometry;
|
||||||
auto vertexBuffer = std::make_shared<gpu::Buffer>();
|
auto vertexBuffer = std::make_shared<gpu::Buffer>();
|
||||||
auto indexBuffer = std::make_shared<gpu::Buffer>();
|
auto indexBuffer = std::make_shared<gpu::Buffer>();
|
||||||
// Cube
|
// Cube
|
||||||
setupFlatShape(_shapes[Cube], geometry::cube(), _shapeVertices, _shapeIndices);
|
setupFlatShape(_shapes[Cube], geometry::cube(), _shapeVertices, _shapeIndices);
|
||||||
|
//Quad renders as flat Cube
|
||||||
|
setupFlatShape(_shapes[Quad], geometry::cube(), _shapeVertices, _shapeIndices);
|
||||||
// Tetrahedron
|
// Tetrahedron
|
||||||
setupFlatShape(_shapes[Tetrahedron], geometry::tetrahedron(), _shapeVertices, _shapeIndices);
|
setupFlatShape(_shapes[Tetrahedron], geometry::tetrahedron(), _shapeVertices, _shapeIndices);
|
||||||
// Icosahedron
|
// Icosahedron
|
||||||
|
@ -524,12 +526,10 @@ void GeometryCache::buildShapes() {
|
||||||
extrudePolygon<64>(_shapes[Cylinder], _shapeVertices, _shapeIndices);
|
extrudePolygon<64>(_shapes[Cylinder], _shapeVertices, _shapeIndices);
|
||||||
//Cone,
|
//Cone,
|
||||||
extrudePolygon<64>(_shapes[Cone], _shapeVertices, _shapeIndices, true);
|
extrudePolygon<64>(_shapes[Cone], _shapeVertices, _shapeIndices, true);
|
||||||
//Circle
|
// Circle renders as flat Cylinder
|
||||||
drawCircle(_shapes[Circle], _shapeVertices, _shapeIndices);
|
extrudePolygon<64>(_shapes[Circle], _shapeVertices, _shapeIndices);
|
||||||
// Not implemented yet:
|
// Not implemented yet:
|
||||||
//Quad,
|
//Torus,
|
||||||
//Torus,
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const GeometryCache::ShapeData * GeometryCache::getShapeData(const Shape shape) const {
|
const GeometryCache::ShapeData * GeometryCache::getShapeData(const Shape shape) const {
|
||||||
|
|
|
@ -225,28 +225,41 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAttachPointForHotspotFromSettings(hotspot, hand) {
|
function getAttachPointForHotspotFromSettings(hotspot, hand) {
|
||||||
|
var skeletonModelURL = MyAvatar.skeletonModelURL;
|
||||||
var attachPointSettings = getAttachPointSettings();
|
var attachPointSettings = getAttachPointSettings();
|
||||||
var jointName = (hand === RIGHT_HAND) ? "RightHand" : "LeftHand";
|
var avatarSettingsData = attachPointSettings[skeletonModelURL];
|
||||||
var joints = attachPointSettings[hotspot.key];
|
if (avatarSettingsData) {
|
||||||
if (joints) {
|
var jointName = (hand === RIGHT_HAND) ? "RightHand" : "LeftHand";
|
||||||
return joints[jointName];
|
var joints = avatarSettingsData[hotspot.key];
|
||||||
} else {
|
if (joints) {
|
||||||
return undefined;
|
return joints[jointName];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function storeAttachPointForHotspotInSettings(hotspot, hand, offsetPosition, offsetRotation) {
|
function storeAttachPointForHotspotInSettings(hotspot, hand, offsetPosition, offsetRotation) {
|
||||||
var attachPointSettings = getAttachPointSettings();
|
var attachPointSettings = getAttachPointSettings();
|
||||||
|
var skeletonModelURL = MyAvatar.skeletonModelURL;
|
||||||
|
var avatarSettingsData = attachPointSettings[skeletonModelURL];
|
||||||
|
if (!avatarSettingsData) {
|
||||||
|
avatarSettingsData = {};
|
||||||
|
attachPointSettings[skeletonModelURL] = avatarSettingsData;
|
||||||
|
}
|
||||||
var jointName = (hand === RIGHT_HAND) ? "RightHand" : "LeftHand";
|
var jointName = (hand === RIGHT_HAND) ? "RightHand" : "LeftHand";
|
||||||
var joints = attachPointSettings[hotspot.key];
|
var joints = avatarSettingsData[hotspot.key];
|
||||||
if (!joints) {
|
if (!joints) {
|
||||||
joints = {};
|
joints = {};
|
||||||
attachPointSettings[hotspot.key] = joints;
|
avatarSettingsData[hotspot.key] = joints;
|
||||||
}
|
}
|
||||||
joints[jointName] = [offsetPosition, offsetRotation];
|
joints[jointName] = [offsetPosition, offsetRotation];
|
||||||
setAttachPointSettings(attachPointSettings);
|
setAttachPointSettings(attachPointSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clearAttachPoints() {
|
||||||
|
setAttachPointSettings({});
|
||||||
|
}
|
||||||
|
|
||||||
function EquipEntity(hand) {
|
function EquipEntity(hand) {
|
||||||
this.hand = hand;
|
this.hand = hand;
|
||||||
this.targetEntityID = null;
|
this.targetEntityID = null;
|
||||||
|
@ -538,6 +551,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
};
|
};
|
||||||
|
|
||||||
this.endEquipEntity = function () {
|
this.endEquipEntity = function () {
|
||||||
|
this.storeAttachPointInSettings();
|
||||||
Entities.editEntity(this.targetEntityID, {
|
Entities.editEntity(this.targetEntityID, {
|
||||||
parentID: Uuid.NULL,
|
parentID: Uuid.NULL,
|
||||||
parentJointIndex: -1
|
parentJointIndex: -1
|
||||||
|
@ -684,14 +698,6 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
if (dropDetected && !this.waitForTriggerRelease && this.triggerSmoothedGrab()) {
|
if (dropDetected && !this.waitForTriggerRelease && this.triggerSmoothedGrab()) {
|
||||||
this.waitForTriggerRelease = true;
|
this.waitForTriggerRelease = true;
|
||||||
// store the offset attach points into preferences.
|
// store the offset attach points into preferences.
|
||||||
if (this.grabbedHotspot && this.targetEntityID) {
|
|
||||||
var prefprops = Entities.getEntityProperties(this.targetEntityID, ["localPosition", "localRotation"]);
|
|
||||||
if (prefprops && prefprops.localPosition && prefprops.localRotation) {
|
|
||||||
storeAttachPointForHotspotInSettings(this.grabbedHotspot, this.hand,
|
|
||||||
prefprops.localPosition, prefprops.localRotation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.endEquipEntity();
|
this.endEquipEntity();
|
||||||
return makeRunningValues(false, [], []);
|
return makeRunningValues(false, [], []);
|
||||||
}
|
}
|
||||||
|
@ -707,6 +713,16 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
return makeRunningValues(true, [this.targetEntityID], []);
|
return makeRunningValues(true, [this.targetEntityID], []);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.storeAttachPointInSettings = function() {
|
||||||
|
if (this.grabbedHotspot && this.targetEntityID) {
|
||||||
|
var prefProps = Entities.getEntityProperties(this.targetEntityID, ["localPosition", "localRotation"]);
|
||||||
|
if (prefProps && prefProps.localPosition && prefProps.localRotation) {
|
||||||
|
storeAttachPointForHotspotInSettings(this.grabbedHotspot, this.hand,
|
||||||
|
prefProps.localPosition, prefProps.localRotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.cleanup = function () {
|
this.cleanup = function () {
|
||||||
if (this.targetEntityID) {
|
if (this.targetEntityID) {
|
||||||
this.endEquipEntity();
|
this.endEquipEntity();
|
||||||
|
@ -751,11 +767,12 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
||||||
enableDispatcherModule("LeftEquipEntity", leftEquipEntity);
|
enableDispatcherModule("LeftEquipEntity", leftEquipEntity);
|
||||||
enableDispatcherModule("RightEquipEntity", rightEquipEntity);
|
enableDispatcherModule("RightEquipEntity", rightEquipEntity);
|
||||||
|
|
||||||
this.cleanup = function () {
|
function cleanup() {
|
||||||
leftEquipEntity.cleanup();
|
leftEquipEntity.cleanup();
|
||||||
rightEquipEntity.cleanup();
|
rightEquipEntity.cleanup();
|
||||||
disableDispatcherModule("LeftEquipEntity");
|
disableDispatcherModule("LeftEquipEntity");
|
||||||
disableDispatcherModule("RightEquipEntity");
|
disableDispatcherModule("RightEquipEntity");
|
||||||
|
clearAttachPoints();
|
||||||
};
|
};
|
||||||
Script.scriptEnding.connect(this.cleanup);
|
Script.scriptEnding.connect(cleanup);
|
||||||
}());
|
}());
|
||||||
|
|
|
@ -154,6 +154,25 @@ Script.include("/~/system/libraries/controllers.js");
|
||||||
|
|
||||||
this.showStylus = function() {
|
this.showStylus = function() {
|
||||||
if (this.stylus) {
|
if (this.stylus) {
|
||||||
|
var X_ROT_NEG_90 = { x: -0.70710678, y: 0, z: 0, w: 0.70710678 };
|
||||||
|
var modelOrientation = Quat.multiply(this.stylusTip.orientation, X_ROT_NEG_90);
|
||||||
|
var modelOrientationAngles = Quat.safeEulerAngles(modelOrientation);
|
||||||
|
|
||||||
|
var rotation = Overlays.getProperty(this.stylus, "rotation");
|
||||||
|
var rotationAngles = Quat.safeEulerAngles(rotation);
|
||||||
|
|
||||||
|
if(!Vec3.withinEpsilon(modelOrientationAngles, rotationAngles, 1)) {
|
||||||
|
var modelPositionOffset = Vec3.multiplyQbyV(modelOrientation, { x: 0, y: 0, z: MyAvatar.sensorToWorldScale * -WEB_STYLUS_LENGTH / 2 });
|
||||||
|
|
||||||
|
var updatedStylusProperties = {
|
||||||
|
position: Vec3.sum(this.stylusTip.position, modelPositionOffset),
|
||||||
|
rotation: modelOrientation,
|
||||||
|
dimensions: Vec3.multiply(MyAvatar.sensorToWorldScale, { x: 0.01, y: 0.01, z: WEB_STYLUS_LENGTH }),
|
||||||
|
};
|
||||||
|
|
||||||
|
Overlays.editOverlay(this.stylus, updatedStylusProperties);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
<option value="Cylinder">Cylinder</option>
|
<option value="Cylinder">Cylinder</option>
|
||||||
<option value="Cone">Cone</option>
|
<option value="Cone">Cone</option>
|
||||||
<option value="Circle">Circle</option>
|
<option value="Circle">Circle</option>
|
||||||
|
<option value="Quad">Quad</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="property text">
|
<div class="property text">
|
||||||
|
|
Loading…
Reference in a new issue