mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 11:45:36 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi
This commit is contained in:
commit
827d8bd854
28 changed files with 696 additions and 160 deletions
|
@ -13,6 +13,7 @@
|
|||
|
||||
var isGrabbing = false;
|
||||
var grabbedEntity = null;
|
||||
var actionID = null;
|
||||
var prevMouse = {};
|
||||
var deltaMouse = {
|
||||
z: 0
|
||||
|
@ -88,6 +89,7 @@ function mousePressEvent(event) {
|
|||
gravity: {x: 0, y: 0, z: 0}
|
||||
});
|
||||
|
||||
Controller.mouseMoveEvent.connect(mouseMoveEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,7 +112,10 @@ function updateDropLine(position) {
|
|||
|
||||
function mouseReleaseEvent() {
|
||||
if (isGrabbing) {
|
||||
Controller.mouseMoveEvent.disconnect(mouseMoveEvent);
|
||||
isGrabbing = false;
|
||||
Entities.deleteAction(grabbedEntity, actionID);
|
||||
actionID = null;
|
||||
|
||||
// only restore the original gravity if it's not zero. This is to avoid...
|
||||
// 1. interface A grabs an entity and locally saves off its gravity
|
||||
|
@ -228,21 +233,25 @@ function update(deltaTime) {
|
|||
}
|
||||
if (shouldRotate) {
|
||||
angularVelocity = Vec3.subtract(angularVelocity, Vec3.multiply(angularVelocity, ANGULAR_DAMPING_RATE));
|
||||
Entities.editEntity(grabbedEntity, {
|
||||
rotation: currentRotation,
|
||||
angularVelocity: angularVelocity
|
||||
});
|
||||
} else {
|
||||
angularVelocity = entityProps.angularVelocity;
|
||||
}
|
||||
|
||||
Entities.editEntity(grabbedEntity, {
|
||||
position: currentPosition,
|
||||
rotation: currentRotation,
|
||||
velocity: newVelocity,
|
||||
angularVelocity: angularVelocity
|
||||
});
|
||||
var newSpeed = Vec3.length(newVelocity);
|
||||
if (!actionID) {
|
||||
actionID = Entities.addAction("pull-to-point", grabbedEntity, {target: targetPosition, speed: newSpeed});
|
||||
} else {
|
||||
Entities.updateAction(grabbedEntity, actionID, {target: targetPosition, speed: newSpeed});
|
||||
}
|
||||
|
||||
updateDropLine(targetPosition);
|
||||
}
|
||||
}
|
||||
|
||||
Controller.mouseMoveEvent.connect(mouseMoveEvent);
|
||||
Controller.mousePressEvent.connect(mousePressEvent);
|
||||
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
|
||||
Controller.keyPressEvent.connect(keyPressEvent);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
//
|
||||
Script.include('lineRider.js')
|
||||
var MAX_POINTS_PER_LINE = 30;
|
||||
var DRAWING_DISTANCE = 5;
|
||||
|
||||
|
||||
var colorPalette = [{
|
||||
red: 236,
|
||||
|
@ -69,6 +69,7 @@ function hydraCheck() {
|
|||
//************ Mouse Paint **************************
|
||||
|
||||
function MousePaint() {
|
||||
var DRAWING_DISTANCE = 2;
|
||||
var lines = [];
|
||||
var deletedLines = [];
|
||||
var isDrawing = false;
|
||||
|
@ -91,7 +92,7 @@ function MousePaint() {
|
|||
var points = [];
|
||||
|
||||
|
||||
var BRUSH_SIZE = 0.08;
|
||||
var BRUSH_SIZE = 0.02;
|
||||
|
||||
var brush = Entities.addEntity({
|
||||
type: 'Sphere',
|
||||
|
@ -244,7 +245,6 @@ function HydraPaint() {
|
|||
var currentTime = 0;
|
||||
|
||||
|
||||
var DISTANCE_FROM_HAND = 2;
|
||||
var minBrushSize = .02;
|
||||
var maxBrushSize = .04
|
||||
|
||||
|
@ -268,8 +268,8 @@ function HydraPaint() {
|
|||
|
||||
var STROKE_SMOOTH_FACTOR = 1;
|
||||
|
||||
var MIN_DRAW_DISTANCE = 1;
|
||||
var MAX_DRAW_DISTANCE = 2;
|
||||
var MIN_DRAW_DISTANCE = 0.2;
|
||||
var MAX_DRAW_DISTANCE = 0.4;
|
||||
|
||||
function controller(side, undoButton, redoButton, cycleColorButton, startRideButton) {
|
||||
this.triggerHeld = false;
|
||||
|
|
|
@ -2458,8 +2458,9 @@ void Application::update(float deltaTime) {
|
|||
|
||||
|
||||
updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process...
|
||||
|
||||
DependencyManager::get<AvatarManager>()->updateOtherAvatars(deltaTime); //loop through all the other avatars and simulate them...
|
||||
|
||||
//loop through all the other avatars and simulate them...
|
||||
DependencyManager::get<AvatarManager>()->updateOtherAvatars(deltaTime);
|
||||
|
||||
updateCamera(deltaTime); // handle various camera tweaks like off axis projection
|
||||
updateDialogs(deltaTime); // update various stats dialogs if present
|
||||
|
@ -2473,6 +2474,7 @@ void Application::update(float deltaTime) {
|
|||
_physicsEngine.deleteObjects(_entitySimulation.getObjectsToDelete());
|
||||
_physicsEngine.addObjects(_entitySimulation.getObjectsToAdd());
|
||||
_physicsEngine.changeObjects(_entitySimulation.getObjectsToChange());
|
||||
_entitySimulation.applyActionChanges();
|
||||
_entitySimulation.unlock();
|
||||
|
||||
AvatarManager* avatarManager = DependencyManager::get<AvatarManager>().data();
|
||||
|
@ -2495,7 +2497,8 @@ void Application::update(float deltaTime) {
|
|||
|
||||
if (!_aboutToQuit) {
|
||||
PerformanceTimer perfTimer("entities");
|
||||
// Collision events (and their scripts) must not be handled when we're locked, above. (That would risk deadlock.)
|
||||
// Collision events (and their scripts) must not be handled when we're locked, above. (That would risk
|
||||
// deadlock.)
|
||||
_entitySimulation.handleCollisionEvents(collisionEvents);
|
||||
// NOTE: the _entities.update() call below will wait for lock
|
||||
// and will simulate entity motion (the EntityTree has been given an EntitySimulation).
|
||||
|
@ -2508,11 +2511,12 @@ void Application::update(float deltaTime) {
|
|||
PerformanceTimer perfTimer("overlays");
|
||||
_overlays.update(deltaTime);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("myAvatar");
|
||||
updateMyAvatarLookAtPosition();
|
||||
DependencyManager::get<AvatarManager>()->updateMyAvatar(deltaTime); // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes
|
||||
// Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes
|
||||
DependencyManager::get<AvatarManager>()->updateMyAvatar(deltaTime);
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -26,8 +26,8 @@ EntityItemPointer RenderableLineEntityItem::factory(const EntityItemID& entityID
|
|||
void RenderableLineEntityItem::render(RenderArgs* args) {
|
||||
PerformanceTimer perfTimer("RenderableLineEntityItem::render");
|
||||
assert(getType() == EntityTypes::Line);
|
||||
glm::vec3 position = getPosition();
|
||||
glm::vec3 dimensions = getDimensions();
|
||||
// glm::vec3 position = getPosition();
|
||||
// glm::vec3 dimensions = getDimensions();
|
||||
glm::quat rotation = getRotation();
|
||||
glm::vec4 lineColor(toGlm(getXColor()), getLocalRenderAlpha());
|
||||
glPushMatrix();
|
||||
|
@ -49,6 +49,6 @@ void RenderableLineEntityItem::render(RenderArgs* args) {
|
|||
}
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
|
||||
RenderableDebugableEntityItem::render(this, args);
|
||||
};
|
||||
|
|
|
@ -8,10 +8,13 @@
|
|||
|
||||
#include "RenderableWebEntityItem.h"
|
||||
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
|
||||
#include <gpu/GPUConfig.h>
|
||||
|
||||
#include <GlowEffect.h>
|
||||
#include <DeferredLightingEffect.h>
|
||||
#include <GeometryCache.h>
|
||||
#include <PerfStat.h>
|
||||
|
@ -64,7 +67,6 @@ RenderableWebEntityItem::~RenderableWebEntityItem() {
|
|||
void RenderableWebEntityItem::render(RenderArgs* args) {
|
||||
QOpenGLContext * currentContext = QOpenGLContext::currentContext();
|
||||
QSurface * currentSurface = currentContext->surface();
|
||||
|
||||
if (!_webSurface) {
|
||||
_webSurface = new OffscreenQmlSurface();
|
||||
_webSurface->create(currentContext);
|
||||
|
@ -98,16 +100,35 @@ void RenderableWebEntityItem::render(RenderArgs* args) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (event->button() == Qt::MouseButton::RightButton) {
|
||||
if (event->type() == QEvent::MouseButtonPress) {
|
||||
const QMouseEvent* mouseEvent = static_cast<const QMouseEvent*>(event);
|
||||
_lastPress = toGlm(mouseEvent->pos());
|
||||
}
|
||||
}
|
||||
|
||||
if (intersection.entityID == getID()) {
|
||||
if (event->button() == Qt::MouseButton::RightButton) {
|
||||
if (event->type() == QEvent::MouseButtonRelease) {
|
||||
AbstractViewStateInterface::instance()->postLambdaEvent([this] {
|
||||
QMetaObject::invokeMethod(_webSurface->getRootItem(), "goBack");
|
||||
});
|
||||
const QMouseEvent* mouseEvent = static_cast<const QMouseEvent*>(event);
|
||||
ivec2 dist = glm::abs(toGlm(mouseEvent->pos()) - _lastPress);
|
||||
if (!glm::any(glm::greaterThan(dist, ivec2(1)))) {
|
||||
AbstractViewStateInterface::instance()->postLambdaEvent([this] {
|
||||
QMetaObject::invokeMethod(_webSurface->getRootItem(), "goBack");
|
||||
});
|
||||
}
|
||||
_lastPress = ivec2(INT_MIN);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME doesn't work... double click events not received
|
||||
if (event->type() == QEvent::MouseButtonDblClick) {
|
||||
AbstractViewStateInterface::instance()->postLambdaEvent([this] {
|
||||
_webSurface->getRootItem()->setProperty("url", _sourceUrl);
|
||||
});
|
||||
}
|
||||
|
||||
if (event->button() == Qt::MouseButton::MiddleButton) {
|
||||
if (event->type() == QEvent::MouseButtonRelease) {
|
||||
AbstractViewStateInterface::instance()->postLambdaEvent([this] {
|
||||
|
@ -133,6 +154,7 @@ void RenderableWebEntityItem::render(RenderArgs* args) {
|
|||
QCoreApplication::sendEvent(_webSurface->getWindow(), &mappedEvent);
|
||||
}
|
||||
};
|
||||
|
||||
EntityTreeRenderer* renderer = static_cast<EntityTreeRenderer*>(args->_renderer);
|
||||
QObject::connect(renderer, &EntityTreeRenderer::mousePressOnEntity, forwardMouseEvent);
|
||||
QObject::connect(renderer, &EntityTreeRenderer::mouseReleaseOnEntity, forwardMouseEvent);
|
||||
|
@ -147,6 +169,7 @@ void RenderableWebEntityItem::render(RenderArgs* args) {
|
|||
_webSurface->resize(QSize(dims.x, dims.y));
|
||||
currentContext->makeCurrent(currentSurface);
|
||||
|
||||
Glower glow(0);
|
||||
PerformanceTimer perfTimer("RenderableWebEntityItem::render");
|
||||
assert(getType() == EntityTypes::Web);
|
||||
glm::vec3 position = getPosition();
|
||||
|
@ -181,6 +204,7 @@ void RenderableWebEntityItem::render(RenderArgs* args) {
|
|||
}
|
||||
|
||||
void RenderableWebEntityItem::setSourceUrl(const QString& value) {
|
||||
qDebug() << "Setting web entity source URL to " << value;
|
||||
if (_sourceUrl != value) {
|
||||
_sourceUrl = value;
|
||||
if (_webSurface) {
|
||||
|
|
|
@ -29,6 +29,7 @@ private:
|
|||
OffscreenQmlSurface* _webSurface{ nullptr };
|
||||
QMetaObject::Connection _connection;
|
||||
uint32_t _texture{ 0 };
|
||||
ivec2 _lastPress{ INT_MIN };
|
||||
QMutex _textureLock;
|
||||
};
|
||||
|
||||
|
|
101
libraries/entities/src/EntityActionInterface.cpp
Normal file
101
libraries/entities/src/EntityActionInterface.cpp
Normal file
|
@ -0,0 +1,101 @@
|
|||
//
|
||||
// EntityActionInterface.cpp
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Seth Alves on 2015-6-4
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "EntityItem.h"
|
||||
|
||||
#include "EntityActionInterface.h"
|
||||
|
||||
|
||||
EntityActionType EntityActionInterface::actionTypeFromString(QString actionTypeString) {
|
||||
QString normalizedActionTypeString = actionTypeString.toLower().remove('-').remove('_');
|
||||
if (normalizedActionTypeString == "none") {
|
||||
return ACTION_TYPE_NONE;
|
||||
}
|
||||
if (normalizedActionTypeString == "pulltopoint") {
|
||||
return ACTION_TYPE_PULL_TO_POINT;
|
||||
}
|
||||
|
||||
qDebug() << "Warning -- EntityActionInterface::actionTypeFromString got unknown action-type name" << actionTypeString;
|
||||
return ACTION_TYPE_NONE;
|
||||
}
|
||||
|
||||
QString EntityActionInterface::actionTypeToString(EntityActionType actionType) {
|
||||
switch(actionType) {
|
||||
case ACTION_TYPE_NONE:
|
||||
return "none";
|
||||
case ACTION_TYPE_PULL_TO_POINT:
|
||||
return "pullToPoint";
|
||||
}
|
||||
assert(false);
|
||||
return "none";
|
||||
}
|
||||
|
||||
glm::vec3 EntityActionInterface::extractVec3Argument(QString objectName, QVariantMap arguments,
|
||||
QString argumentName, bool& ok) {
|
||||
if (!arguments.contains(argumentName)) {
|
||||
qDebug() << objectName << "requires argument:" << argumentName;
|
||||
ok = false;
|
||||
return vec3();
|
||||
}
|
||||
|
||||
QVariant resultV = arguments[argumentName];
|
||||
if (resultV.type() != (QVariant::Type) QMetaType::QVariantMap) {
|
||||
qDebug() << objectName << "argument" << argumentName << "must be a map";
|
||||
ok = false;
|
||||
return vec3();
|
||||
}
|
||||
|
||||
QVariantMap resultVM = resultV.toMap();
|
||||
if (!resultVM.contains("x") || !resultVM.contains("y") || !resultVM.contains("z")) {
|
||||
qDebug() << objectName << "argument" << argumentName << "must be a map with keys of x, y, z";
|
||||
ok = false;
|
||||
return vec3();
|
||||
}
|
||||
|
||||
QVariant xV = resultVM["x"];
|
||||
QVariant yV = resultVM["y"];
|
||||
QVariant zV = resultVM["z"];
|
||||
|
||||
bool xOk = true;
|
||||
bool yOk = true;
|
||||
bool zOk = true;
|
||||
float x = xV.toFloat(&xOk);
|
||||
float y = yV.toFloat(&yOk);
|
||||
float z = zV.toFloat(&zOk);
|
||||
if (!xOk || !yOk || !zOk) {
|
||||
qDebug() << objectName << "argument" << argumentName << "must be a map with keys of x, y, z and values of type float.";
|
||||
ok = false;
|
||||
return vec3();
|
||||
}
|
||||
|
||||
return vec3(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
float EntityActionInterface::extractFloatArgument(QString objectName, QVariantMap arguments,
|
||||
QString argumentName, bool& ok) {
|
||||
if (!arguments.contains(argumentName)) {
|
||||
qDebug() << objectName << "requires argument:" << argumentName;
|
||||
ok = false;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
QVariant vV = arguments[argumentName];
|
||||
bool vOk = true;
|
||||
float v = vV.toFloat(&vOk);
|
||||
|
||||
if (!vOk) {
|
||||
ok = false;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
49
libraries/entities/src/EntityActionInterface.h
Normal file
49
libraries/entities/src/EntityActionInterface.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
//
|
||||
// EntityActionInterface.h
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Seth Alves on 2015-6-2
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_EntityActionInterface_h
|
||||
#define hifi_EntityActionInterface_h
|
||||
|
||||
#include <QUuid>
|
||||
|
||||
class EntitySimulation;
|
||||
|
||||
enum EntityActionType {
|
||||
// keep these synchronized with actionTypeFromString and actionTypeToString
|
||||
ACTION_TYPE_NONE,
|
||||
ACTION_TYPE_PULL_TO_POINT
|
||||
};
|
||||
|
||||
|
||||
class EntityActionInterface {
|
||||
public:
|
||||
EntityActionInterface() { }
|
||||
virtual ~EntityActionInterface() { }
|
||||
virtual const QUuid& getID() const = 0;
|
||||
virtual void removeFromSimulation(EntitySimulation* simulation) const = 0;
|
||||
virtual const EntityItemPointer& getOwnerEntity() const = 0;
|
||||
virtual void setOwnerEntity(const EntityItemPointer ownerEntity) = 0;
|
||||
virtual bool updateArguments(QVariantMap arguments) = 0;
|
||||
// virtual QByteArray serialize() = 0;
|
||||
// static EntityActionPointer deserialize(EntityItemPointer ownerEntity, QByteArray data);
|
||||
|
||||
static EntityActionType actionTypeFromString(QString actionTypeString);
|
||||
static QString actionTypeToString(EntityActionType actionType);
|
||||
|
||||
protected:
|
||||
|
||||
static glm::vec3 extractVec3Argument(QString objectName, QVariantMap arguments, QString argumentName, bool& ok);
|
||||
static float extractFloatArgument(QString objectName, QVariantMap arguments, QString argumentName, bool& ok);
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<EntityActionInterface> EntityActionPointer;
|
||||
|
||||
#endif // hifi_EntityActionInterface_h
|
|
@ -25,6 +25,7 @@
|
|||
#include "EntityItem.h"
|
||||
#include "EntitiesLogging.h"
|
||||
#include "EntityTree.h"
|
||||
#include "EntitySimulation.h"
|
||||
|
||||
bool EntityItem::_sendPhysicsUpdates = true;
|
||||
|
||||
|
@ -82,7 +83,7 @@ EntityItem::EntityItem(const EntityItemID& entityItemID, const EntityItemPropert
|
|||
}
|
||||
|
||||
EntityItem::~EntityItem() {
|
||||
// these pointers MUST be NULL at delete, else we probably have a dangling backpointer
|
||||
// these pointers MUST be correct at delete, else we probably have a dangling backpointer
|
||||
// to this EntityItem in the corresponding data structure.
|
||||
assert(!_simulated);
|
||||
assert(!_element);
|
||||
|
@ -517,12 +518,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
EntityPropertyFlags propertyFlags = encodedPropertyFlags;
|
||||
dataAt += propertyFlags.getEncodedLength();
|
||||
bytesRead += propertyFlags.getEncodedLength();
|
||||
bool useMeters = (args.bitstreamVersion >= VERSION_ENTITIES_USE_METERS_AND_RADIANS);
|
||||
if (useMeters) {
|
||||
READ_ENTITY_PROPERTY(PROP_POSITION, glm::vec3, updatePosition);
|
||||
} else {
|
||||
READ_ENTITY_PROPERTY(PROP_POSITION, glm::vec3, updatePositionInDomainUnits);
|
||||
}
|
||||
READ_ENTITY_PROPERTY(PROP_POSITION, glm::vec3, updatePosition);
|
||||
|
||||
// Old bitstreams had PROP_RADIUS, new bitstreams have PROP_DIMENSIONS
|
||||
if (args.bitstreamVersion < VERSION_ENTITIES_SUPPORT_DIMENSIONS) {
|
||||
|
@ -536,22 +532,13 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (useMeters) {
|
||||
READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, updateDimensions);
|
||||
} else {
|
||||
READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, updateDimensionsInDomainUnits);
|
||||
}
|
||||
READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, updateDimensions);
|
||||
}
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_ROTATION, glm::quat, updateRotation);
|
||||
READ_ENTITY_PROPERTY(PROP_DENSITY, float, updateDensity);
|
||||
if (useMeters) {
|
||||
READ_ENTITY_PROPERTY(PROP_VELOCITY, glm::vec3, updateVelocity);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAVITY, glm::vec3, updateGravity);
|
||||
} else {
|
||||
READ_ENTITY_PROPERTY(PROP_VELOCITY, glm::vec3, updateVelocityInDomainUnits);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAVITY, glm::vec3, updateGravityInDomainUnits);
|
||||
}
|
||||
READ_ENTITY_PROPERTY(PROP_VELOCITY, glm::vec3, updateVelocity);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAVITY, glm::vec3, updateGravity);
|
||||
if (args.bitstreamVersion >= VERSION_ENTITIES_HAVE_ACCELERATION) {
|
||||
READ_ENTITY_PROPERTY(PROP_ACCELERATION, glm::vec3, setAcceleration);
|
||||
}
|
||||
|
@ -562,11 +549,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
READ_ENTITY_PROPERTY(PROP_LIFETIME, float, updateLifetime);
|
||||
READ_ENTITY_PROPERTY(PROP_SCRIPT, QString, setScript);
|
||||
READ_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, glm::vec3, setRegistrationPoint);
|
||||
if (useMeters) {
|
||||
READ_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, glm::vec3, updateAngularVelocity);
|
||||
} else {
|
||||
READ_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, glm::vec3, updateAngularVelocityInDegrees);
|
||||
}
|
||||
READ_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, glm::vec3, updateAngularVelocity);
|
||||
//READ_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, glm::vec3, updateAngularVelocityInDegrees);
|
||||
READ_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, float, updateAngularDamping);
|
||||
READ_ENTITY_PROPERTY(PROP_VISIBLE, bool, setVisible);
|
||||
READ_ENTITY_PROPERTY(PROP_IGNORE_FOR_COLLISIONS, bool, updateIgnoreForCollisions);
|
||||
|
@ -1134,11 +1118,6 @@ void EntityItem::computeShapeInfo(ShapeInfo& info) {
|
|||
info.setParams(getShapeType(), 0.5f * getDimensions());
|
||||
}
|
||||
|
||||
void EntityItem::updatePositionInDomainUnits(const glm::vec3& value) {
|
||||
glm::vec3 position = value * (float)TREE_SCALE;
|
||||
updatePosition(position);
|
||||
}
|
||||
|
||||
void EntityItem::updatePosition(const glm::vec3& value) {
|
||||
auto delta = glm::distance(_position, value);
|
||||
if (delta > IGNORE_POSITION_DELTA) {
|
||||
|
@ -1150,11 +1129,6 @@ void EntityItem::updatePosition(const glm::vec3& value) {
|
|||
}
|
||||
}
|
||||
|
||||
void EntityItem::updateDimensionsInDomainUnits(const glm::vec3& value) {
|
||||
glm::vec3 dimensions = value * (float)TREE_SCALE;
|
||||
updateDimensions(dimensions);
|
||||
}
|
||||
|
||||
void EntityItem::updateDimensions(const glm::vec3& value) {
|
||||
auto delta = glm::distance(_dimensions, value);
|
||||
if (delta > IGNORE_DIMENSIONS_DELTA) {
|
||||
|
@ -1206,11 +1180,6 @@ void EntityItem::updateMass(float mass) {
|
|||
}
|
||||
}
|
||||
|
||||
void EntityItem::updateVelocityInDomainUnits(const glm::vec3& value) {
|
||||
glm::vec3 velocity = value * (float)TREE_SCALE;
|
||||
updateVelocity(velocity);
|
||||
}
|
||||
|
||||
void EntityItem::updateVelocity(const glm::vec3& value) {
|
||||
auto delta = glm::distance(_velocity, value);
|
||||
if (delta > IGNORE_LINEAR_VELOCITY_DELTA) {
|
||||
|
@ -1236,11 +1205,6 @@ void EntityItem::updateDamping(float value) {
|
|||
}
|
||||
}
|
||||
|
||||
void EntityItem::updateGravityInDomainUnits(const glm::vec3& value) {
|
||||
glm::vec3 gravity = value * (float) TREE_SCALE;
|
||||
updateGravity(gravity);
|
||||
}
|
||||
|
||||
void EntityItem::updateGravity(const glm::vec3& value) {
|
||||
auto delta = glm::distance(_gravity, value);
|
||||
if (delta > IGNORE_GRAVITY_DELTA) {
|
||||
|
@ -1343,3 +1307,46 @@ void EntityItem::updateSimulatorID(const QUuid& value) {
|
|||
_dirtyFlags |= EntityItem::DIRTY_SIMULATOR_ID;
|
||||
}
|
||||
}
|
||||
|
||||
bool EntityItem::addAction(EntitySimulation* simulation, EntityActionPointer action) {
|
||||
assert(action);
|
||||
const QUuid& actionID = action->getID();
|
||||
assert(!_objectActions.contains(actionID) || _objectActions[actionID] == action);
|
||||
_objectActions[actionID] = action;
|
||||
|
||||
assert(action->getOwnerEntity().get() == this);
|
||||
|
||||
simulation->addAction(action);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EntityItem::updateAction(EntitySimulation* simulation, const QUuid& actionID, const QVariantMap& arguments) {
|
||||
if (!_objectActions.contains(actionID)) {
|
||||
return false;
|
||||
}
|
||||
EntityActionPointer action = _objectActions[actionID];
|
||||
return action->updateArguments(arguments);
|
||||
}
|
||||
|
||||
bool EntityItem::removeAction(EntitySimulation* simulation, const QUuid& actionID) {
|
||||
if (_objectActions.contains(actionID)) {
|
||||
EntityActionPointer action = _objectActions[actionID];
|
||||
_objectActions.remove(actionID);
|
||||
action->setOwnerEntity(nullptr);
|
||||
action->removeFromSimulation(simulation);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void EntityItem::clearActions(EntitySimulation* simulation) {
|
||||
QHash<QUuid, EntityActionPointer>::iterator i = _objectActions.begin();
|
||||
while (i != _objectActions.end()) {
|
||||
const QUuid id = i.key();
|
||||
EntityActionPointer action = _objectActions[id];
|
||||
i = _objectActions.erase(i);
|
||||
action->setOwnerEntity(nullptr);
|
||||
action->removeFromSimulation(simulation);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,9 +23,10 @@
|
|||
#include <OctreePacketData.h>
|
||||
#include <ShapeInfo.h>
|
||||
|
||||
#include "EntityItemID.h"
|
||||
#include "EntityItemProperties.h"
|
||||
#include "EntityItemPropertiesDefaults.h"
|
||||
#include "EntityItemID.h"
|
||||
#include "EntityItemProperties.h"
|
||||
#include "EntityItemPropertiesDefaults.h"
|
||||
#include "EntityActionInterface.h"
|
||||
#include "EntityTypes.h"
|
||||
|
||||
class EntitySimulation;
|
||||
|
@ -88,7 +89,7 @@ public:
|
|||
};
|
||||
|
||||
DONT_ALLOW_INSTANTIATION // This class can not be instantiated directly
|
||||
|
||||
|
||||
EntityItem(const EntityItemID& entityItemID);
|
||||
EntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||
virtual ~EntityItem();
|
||||
|
@ -100,7 +101,7 @@ public:
|
|||
|
||||
// methods for getting/setting all properties of an entity
|
||||
virtual EntityItemProperties getProperties() const;
|
||||
|
||||
|
||||
/// returns true if something changed
|
||||
virtual bool setProperties(const EntityItemProperties& properties);
|
||||
|
||||
|
@ -114,7 +115,7 @@ public:
|
|||
|
||||
/// Last edited time of this entity universal usecs
|
||||
quint64 getLastEdited() const { return _lastEdited; }
|
||||
void setLastEdited(quint64 lastEdited)
|
||||
void setLastEdited(quint64 lastEdited)
|
||||
{ _lastEdited = _lastUpdated = lastEdited; _changedOnServer = glm::max(lastEdited, _changedOnServer); }
|
||||
float getEditedAgo() const /// Elapsed seconds since this entity was last edited
|
||||
{ return (float)(usecTimestampNow() - getLastEdited()) / (float)USECS_PER_SECOND; }
|
||||
|
@ -128,26 +129,26 @@ public:
|
|||
|
||||
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;
|
||||
|
||||
|
||||
virtual OctreeElement::AppendState appendEntityData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
||||
EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData) const;
|
||||
|
||||
virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
||||
virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
||||
EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const { /* do nothing*/ };
|
||||
|
||||
static EntityItemID readEntityItemIDFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
static EntityItemID readEntityItemIDFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
ReadBitstreamToTreeParams& args);
|
||||
|
||||
virtual int readEntityDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args);
|
||||
|
||||
virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
ReadBitstreamToTreeParams& args,
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData)
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData)
|
||||
{ return 0; }
|
||||
|
||||
virtual void render(RenderArgs* args) { } // by default entity items don't know how to render
|
||||
|
@ -159,7 +160,7 @@ public:
|
|||
// perform update
|
||||
virtual void update(const quint64& now) { _lastUpdated = now; }
|
||||
quint64 getLastUpdated() const { return _lastUpdated; }
|
||||
|
||||
|
||||
// perform linear extrapolation for SimpleEntitySimulation
|
||||
void simulate(const quint64& now);
|
||||
void simulateKinematicMotion(float timeElapsed, bool setFlags=true);
|
||||
|
@ -167,19 +168,17 @@ public:
|
|||
virtual bool needsToCallUpdate() const { return false; }
|
||||
|
||||
virtual void debugDump() const;
|
||||
|
||||
|
||||
virtual bool supportsDetailedRayIntersection() const { return false; }
|
||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
||||
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
||||
void** intersectedObject, bool precisionPicking) const { return true; }
|
||||
|
||||
// attributes applicable to all entity types
|
||||
EntityTypes::EntityType getType() const { return _type; }
|
||||
const glm::vec3& getPosition() const { return _position; } /// get position in meters
|
||||
|
||||
void setPosition(const glm::vec3& value) {
|
||||
_position = value;
|
||||
}
|
||||
|
||||
void setPosition(const glm::vec3& value) { _position = value; }
|
||||
|
||||
glm::vec3 getCenter() const;
|
||||
|
||||
|
@ -214,7 +213,7 @@ public:
|
|||
const glm::vec3& getAcceleration() const { return _acceleration; } /// get acceleration in meters/second/second
|
||||
void setAcceleration(const glm::vec3& value) { _acceleration = value; } /// acceleration in meters/second/second
|
||||
bool hasAcceleration() const { return _acceleration != ENTITY_ITEM_ZERO_VEC3; }
|
||||
|
||||
|
||||
float getDamping() const { return _damping; }
|
||||
void setDamping(float value) { _damping = value; }
|
||||
|
||||
|
@ -236,7 +235,7 @@ public:
|
|||
|
||||
/// is this entity mortal, in that it has a lifetime set, and will automatically be deleted when that lifetime expires
|
||||
bool isMortal() const { return _lifetime != ENTITY_ITEM_IMMORTAL_LIFETIME; }
|
||||
|
||||
|
||||
/// age of this entity in seconds
|
||||
float getAge() const { return (float)(usecTimestampNow() - _created) / (float)USECS_PER_SECOND; }
|
||||
bool lifetimeHasExpired() const;
|
||||
|
@ -255,7 +254,7 @@ public:
|
|||
const glm::vec3& getRegistrationPoint() const { return _registrationPoint; } /// registration point as ratio of entity
|
||||
|
||||
/// registration point as ratio of entity
|
||||
void setRegistrationPoint(const glm::vec3& value)
|
||||
void setRegistrationPoint(const glm::vec3& value)
|
||||
{ _registrationPoint = glm::clamp(value, 0.0f, 1.0f); }
|
||||
|
||||
const glm::vec3& getAngularVelocity() const { return _angularVelocity; }
|
||||
|
@ -283,7 +282,7 @@ public:
|
|||
|
||||
bool getLocked() const { return _locked; }
|
||||
void setLocked(bool value) { _locked = value; }
|
||||
|
||||
|
||||
const QString& getUserData() const { return _userData; }
|
||||
void setUserData(const QString& value) { _userData = value; }
|
||||
|
||||
|
@ -291,13 +290,13 @@ public:
|
|||
void setSimulatorID(const QUuid& value);
|
||||
void updateSimulatorID(const QUuid& value);
|
||||
quint64 getSimulatorIDChangedTime() const { return _simulatorIDChangedTime; }
|
||||
|
||||
|
||||
const QString& getMarketplaceID() const { return _marketplaceID; }
|
||||
void setMarketplaceID(const QString& value) { _marketplaceID = value; }
|
||||
|
||||
// TODO: get rid of users of getRadius()...
|
||||
|
||||
// TODO: get rid of users of getRadius()...
|
||||
float getRadius() const;
|
||||
|
||||
|
||||
virtual bool contains(const glm::vec3& point) const;
|
||||
|
||||
virtual bool isReadyToComputeShape() { return true; }
|
||||
|
@ -308,22 +307,17 @@ public:
|
|||
virtual ShapeType getShapeType() const { return SHAPE_TYPE_NONE; }
|
||||
|
||||
// updateFoo() methods to be used when changes need to be accumulated in the _dirtyFlags
|
||||
void updatePositionInDomainUnits(const glm::vec3& value);
|
||||
void updatePosition(const glm::vec3& value);
|
||||
void updateDimensionsInDomainUnits(const glm::vec3& value);
|
||||
void updateDimensions(const glm::vec3& value);
|
||||
void updateRotation(const glm::quat& rotation);
|
||||
void updateDensity(float value);
|
||||
void updateMass(float value);
|
||||
void updateVelocityInDomainUnits(const glm::vec3& value);
|
||||
void updateVelocity(const glm::vec3& value);
|
||||
void updateDamping(float value);
|
||||
void updateRestitution(float value);
|
||||
void updateFriction(float value);
|
||||
void updateGravityInDomainUnits(const glm::vec3& value);
|
||||
void updateGravity(const glm::vec3& value);
|
||||
void updateAngularVelocity(const glm::vec3& value);
|
||||
void updateAngularVelocityInDegrees(const glm::vec3& value) { updateAngularVelocity(glm::radians(value)); }
|
||||
void updateAngularDamping(float value);
|
||||
void updateIgnoreForCollisions(bool value);
|
||||
void updateCollisionsWillMove(bool value);
|
||||
|
@ -333,11 +327,11 @@ public:
|
|||
|
||||
uint32_t getDirtyFlags() const { return _dirtyFlags; }
|
||||
void clearDirtyFlags(uint32_t mask = 0xffff) { _dirtyFlags &= ~mask; }
|
||||
|
||||
|
||||
bool isMoving() const;
|
||||
|
||||
void* getPhysicsInfo() const { return _physicsInfo; }
|
||||
|
||||
|
||||
void setPhysicsInfo(void* data) { _physicsInfo = data; }
|
||||
EntityTreeElement* getElement() const { return _element; }
|
||||
|
||||
|
@ -353,12 +347,18 @@ public:
|
|||
|
||||
void getAllTerseUpdateProperties(EntityItemProperties& properties) const;
|
||||
|
||||
bool addAction(EntitySimulation* simulation, EntityActionPointer action);
|
||||
bool updateAction(EntitySimulation* simulation, const QUuid& actionID, const QVariantMap& arguments);
|
||||
bool removeAction(EntitySimulation* simulation, const QUuid& actionID);
|
||||
void clearActions(EntitySimulation* simulation);
|
||||
|
||||
protected:
|
||||
|
||||
static bool _sendPhysicsUpdates;
|
||||
EntityTypes::EntityType _type;
|
||||
QUuid _id;
|
||||
quint64 _lastSimulated; // last time this entity called simulate(), this includes velocity, angular velocity, and physics changes
|
||||
quint64 _lastSimulated; // last time this entity called simulate(), this includes velocity, angular velocity,
|
||||
// and physics changes
|
||||
quint64 _lastUpdated; // last time this entity called update(), this includes animations and non-physics changes
|
||||
quint64 _lastEdited; // last official local or remote edit time
|
||||
quint64 _lastBroadcast; // the last time we sent an edit packet about this entity
|
||||
|
@ -409,12 +409,12 @@ protected:
|
|||
//
|
||||
// damping = 1 - exp(-1 / timescale)
|
||||
//
|
||||
|
||||
// NOTE: Radius support is obsolete, but these private helper functions are available for this class to
|
||||
|
||||
// NOTE: Radius support is obsolete, but these private helper functions are available for this class to
|
||||
// parse old data streams
|
||||
|
||||
|
||||
/// set radius in domain scale units (0.0 - 1.0) this will also reset dimensions to be equal for each axis
|
||||
void setRadius(float value);
|
||||
void setRadius(float value);
|
||||
|
||||
// DirtyFlags are set whenever a property changes that the EntitySimulation needs to know about.
|
||||
uint32_t _dirtyFlags; // things that have changed from EXTERNAL changes (via script or packet) but NOT from simulation
|
||||
|
@ -423,6 +423,8 @@ protected:
|
|||
EntityTreeElement* _element = nullptr; // set by EntityTreeElement
|
||||
void* _physicsInfo = nullptr; // set by EntitySimulation
|
||||
bool _simulated; // set by EntitySimulation
|
||||
|
||||
QHash<QUuid, EntityActionPointer> _objectActions;
|
||||
};
|
||||
|
||||
#endif // hifi_EntityItem_h
|
||||
|
|
|
@ -11,13 +11,14 @@
|
|||
|
||||
#include <VariantMapToScriptValue.h>
|
||||
|
||||
#include "EntityScriptingInterface.h"
|
||||
#include "EntityTree.h"
|
||||
#include "LightEntityItem.h"
|
||||
#include "ModelEntityItem.h"
|
||||
#include "ZoneEntityItem.h"
|
||||
#include "EntitiesLogging.h"
|
||||
#include "EntitySimulation.h"
|
||||
|
||||
#include "EntityScriptingInterface.h"
|
||||
|
||||
EntityScriptingInterface::EntityScriptingInterface() :
|
||||
_entityTree(NULL)
|
||||
|
@ -83,7 +84,8 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties
|
|||
entity->setLastBroadcast(usecTimestampNow());
|
||||
// This Node is creating a new object. If it's in motion, set this Node as the simulator.
|
||||
bidForSimulationOwnership(propertiesWithSimID);
|
||||
entity->setSimulatorID(propertiesWithSimID.getSimulatorID()); // and make note of it now, so we can act on it right away.
|
||||
// and make note of it now, so we can act on it right away.
|
||||
entity->setSimulatorID(propertiesWithSimID.getSimulatorID());
|
||||
} else {
|
||||
qCDebug(entities) << "script failed to add new Entity to local Octree";
|
||||
success = false;
|
||||
|
@ -105,7 +107,7 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit
|
|||
_entityTree->lockForRead();
|
||||
|
||||
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(identity));
|
||||
|
||||
|
||||
if (entity) {
|
||||
results = entity->getProperties();
|
||||
|
||||
|
@ -124,7 +126,7 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit
|
|||
}
|
||||
_entityTree->unlock();
|
||||
}
|
||||
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
@ -228,7 +230,7 @@ QVector<QUuid> EntityScriptingInterface::findEntities(const glm::vec3& center, f
|
|||
QVector<EntityItemPointer> entities;
|
||||
_entityTree->findEntities(center, radius, entities);
|
||||
_entityTree->unlock();
|
||||
|
||||
|
||||
foreach (EntityItemPointer entity, entities) {
|
||||
result << entity->getEntityItemID();
|
||||
}
|
||||
|
@ -244,7 +246,7 @@ QVector<QUuid> EntityScriptingInterface::findEntitiesInBox(const glm::vec3& corn
|
|||
QVector<EntityItemPointer> entities;
|
||||
_entityTree->findEntities(box, entities);
|
||||
_entityTree->unlock();
|
||||
|
||||
|
||||
foreach (EntityItemPointer entity, entities) {
|
||||
result << entity->getEntityItemID();
|
||||
}
|
||||
|
@ -401,7 +403,6 @@ void RayToEntityIntersectionResultFromScriptValue(const QScriptValue& object, Ra
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
bool EntityScriptingInterface::setVoxels(QUuid entityID,
|
||||
std::function<void(PolyVoxEntityItem&)> actor) {
|
||||
if (!_entityTree) {
|
||||
|
@ -439,23 +440,83 @@ bool EntityScriptingInterface::setVoxels(QUuid entityID,
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool EntityScriptingInterface::setVoxelSphere(QUuid entityID, const glm::vec3& center, float radius, int value) {
|
||||
return setVoxels(entityID, [center, radius, value](PolyVoxEntityItem& polyVoxEntity) {
|
||||
polyVoxEntity.setSphere(center, radius, value);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
bool EntityScriptingInterface::setVoxel(QUuid entityID, const glm::vec3& position, int value) {
|
||||
return setVoxels(entityID, [position, value](PolyVoxEntityItem& polyVoxEntity) {
|
||||
polyVoxEntity.setVoxelInVolume(position, value);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
bool EntityScriptingInterface::setAllVoxels(QUuid entityID, int value) {
|
||||
return setVoxels(entityID, [value](PolyVoxEntityItem& polyVoxEntity) {
|
||||
polyVoxEntity.setAll(value);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
bool EntityScriptingInterface::actionWorker(const QUuid& entityID,
|
||||
std::function<bool(EntitySimulation*, EntityItemPointer)> actor) {
|
||||
if (!_entityTree) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_entityTree->lockForWrite();
|
||||
|
||||
EntitySimulation* simulation = _entityTree->getSimulation();
|
||||
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID);
|
||||
if (!entity) {
|
||||
qDebug() << "actionWorker -- unknown entity" << entityID;
|
||||
_entityTree->unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!simulation) {
|
||||
qDebug() << "actionWorker -- no simulation" << entityID;
|
||||
_entityTree->unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = actor(simulation, entity);
|
||||
_entityTree->unlock();
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
QUuid EntityScriptingInterface::addAction(const QString& actionTypeString,
|
||||
const QUuid& entityID,
|
||||
const QVariantMap& arguments) {
|
||||
QUuid actionID = QUuid::createUuid();
|
||||
bool success = actionWorker(entityID, [&](EntitySimulation* simulation, EntityItemPointer entity) {
|
||||
EntityActionType actionType = EntityActionInterface::actionTypeFromString(actionTypeString);
|
||||
if (actionType == ACTION_TYPE_NONE) {
|
||||
return false;
|
||||
}
|
||||
if (simulation->actionFactory(actionType, actionID, entity, arguments)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (success) {
|
||||
return actionID;
|
||||
}
|
||||
return QUuid();
|
||||
}
|
||||
|
||||
|
||||
bool EntityScriptingInterface::updateAction(const QUuid& entityID, const QUuid& actionID, const QVariantMap& arguments) {
|
||||
return actionWorker(entityID, [&](EntitySimulation* simulation, EntityItemPointer entity) {
|
||||
return entity->updateAction(simulation, actionID, arguments);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
bool EntityScriptingInterface::deleteAction(const QUuid& entityID, const QUuid& actionID) {
|
||||
return actionWorker(entityID, [&](EntitySimulation* simulation, EntityItemPointer entity) {
|
||||
return entity->removeAction(simulation, actionID);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -54,14 +54,14 @@ class EntityScriptingInterface : public OctreeScriptingInterface, public Depende
|
|||
Q_OBJECT
|
||||
public:
|
||||
EntityScriptingInterface();
|
||||
|
||||
|
||||
EntityEditPacketSender* getEntityPacketSender() const { return (EntityEditPacketSender*)getPacketSender(); }
|
||||
virtual NodeType_t getServerNodeType() const { return NodeType::EntityServer; }
|
||||
virtual OctreeEditPacketSender* createPacketSender() { return new EntityEditPacketSender(); }
|
||||
|
||||
void setEntityTree(EntityTree* modelTree);
|
||||
EntityTree* getEntityTree(EntityTree*) { return _entityTree; }
|
||||
|
||||
|
||||
public slots:
|
||||
|
||||
// returns true if the DomainServer will allow this Node/Avatar to make changes
|
||||
|
@ -88,11 +88,11 @@ public slots:
|
|||
/// will return a EntityItemID.isKnownID = false if no models are in the radius
|
||||
/// this function will not find any models in script engine contexts which don't have access to models
|
||||
Q_INVOKABLE QUuid findClosestEntity(const glm::vec3& center, float radius) const;
|
||||
|
||||
|
||||
/// finds models within the search sphere specified by the center point and radius
|
||||
/// this function will not find any models in script engine contexts which don't have access to models
|
||||
Q_INVOKABLE QVector<QUuid> findEntities(const glm::vec3& center, float radius) const;
|
||||
|
||||
|
||||
/// finds models within the search sphere specified by the center point and radius
|
||||
/// this function will not find any models in script engine contexts which don't have access to models
|
||||
Q_INVOKABLE QVector<QUuid> findEntitiesInBox(const glm::vec3& corner, const glm::vec3& dimensions) const;
|
||||
|
@ -118,13 +118,16 @@ public slots:
|
|||
Q_INVOKABLE void setSendPhysicsUpdates(bool value);
|
||||
Q_INVOKABLE bool getSendPhysicsUpdates() const;
|
||||
|
||||
bool setVoxels(QUuid entityID, std::function<void(PolyVoxEntityItem&)> actor);
|
||||
Q_INVOKABLE bool setVoxelSphere(QUuid entityID, const glm::vec3& center, float radius, int value);
|
||||
Q_INVOKABLE bool setVoxel(QUuid entityID, const glm::vec3& position, int value);
|
||||
Q_INVOKABLE bool setAllVoxels(QUuid entityID, int value);
|
||||
|
||||
Q_INVOKABLE void dumpTree() const;
|
||||
|
||||
Q_INVOKABLE QUuid addAction(const QString& actionTypeString, const QUuid& entityID, const QVariantMap& arguments);
|
||||
Q_INVOKABLE bool updateAction(const QUuid& entityID, const QUuid& actionID, const QVariantMap& arguments);
|
||||
Q_INVOKABLE bool deleteAction(const QUuid& entityID, const QUuid& actionID);
|
||||
|
||||
signals:
|
||||
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
||||
void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
||||
|
@ -152,6 +155,8 @@ signals:
|
|||
void clearingEntities();
|
||||
|
||||
private:
|
||||
bool actionWorker(const QUuid& entityID, std::function<bool(EntitySimulation*, EntityItemPointer)> actor);
|
||||
bool setVoxels(QUuid entityID, std::function<void(PolyVoxEntityItem&)> actor);
|
||||
void queueEntityMessage(PacketType packetType, EntityItemID entityID, const EntityItemProperties& properties);
|
||||
|
||||
/// actually does the work of finding the ray intersection, can be called in locking mode or tryLock mode
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
typedef QSet<EntityItemPointer> SetOfEntities;
|
||||
typedef QVector<EntityItemPointer> VectorOfEntities;
|
||||
|
||||
// the EntitySimulation needs to know when these things change on an entity,
|
||||
// the EntitySimulation needs to know when these things change on an entity,
|
||||
// so it can sort EntityItem or relay its state to the PhysicsEngine.
|
||||
const int DIRTY_SIMULATION_FLAGS =
|
||||
const int DIRTY_SIMULATION_FLAGS =
|
||||
EntityItem::DIRTY_POSITION |
|
||||
EntityItem::DIRTY_ROTATION |
|
||||
EntityItem::DIRTY_LINEAR_VELOCITY |
|
||||
|
@ -56,6 +56,15 @@ public:
|
|||
|
||||
friend class EntityTree;
|
||||
|
||||
virtual EntityActionPointer actionFactory(EntityActionType type,
|
||||
QUuid id,
|
||||
EntityItemPointer ownerEntity,
|
||||
QVariantMap arguments) { return nullptr; }
|
||||
virtual void addAction(EntityActionPointer action) { _actionsToAdd += action; }
|
||||
virtual void removeAction(const QUuid actionID) { _actionsToRemove += actionID; }
|
||||
virtual void removeActions(QList<QUuid> actionIDsToRemove) { _actionsToRemove += actionIDsToRemove; }
|
||||
virtual void applyActionChanges() { _actionsToAdd.clear(); _actionsToRemove.clear(); }
|
||||
|
||||
protected: // these only called by the EntityTree?
|
||||
/// \param entity pointer to EntityItem to be added
|
||||
/// \sideeffect sets relevant backpointers in entity, but maybe later when appropriate data structures are locked
|
||||
|
@ -112,8 +121,12 @@ protected:
|
|||
SetOfEntities _entitiesToDelete; // entities simulation decided needed to be deleted (EntityTree will actually delete)
|
||||
SetOfEntities _simpleKinematicEntities; // entities undergoing non-colliding kinematic motion
|
||||
|
||||
private:
|
||||
private:
|
||||
void moveSimpleKinematics();
|
||||
|
||||
protected:
|
||||
QList<EntityActionPointer> _actionsToAdd;
|
||||
QList<QUuid> _actionsToRemove;
|
||||
};
|
||||
|
||||
#endif // hifi_EntitySimulation_h
|
||||
|
|
|
@ -279,7 +279,7 @@ void EntityTree::setSimulation(EntitySimulation* simulation) {
|
|||
if (simulation) {
|
||||
// assert that the simulation's backpointer has already been properly connected
|
||||
assert(simulation->getEntityTree() == this);
|
||||
}
|
||||
}
|
||||
if (_simulation && _simulation != simulation) {
|
||||
// It's important to clearEntities() on the simulation since taht will update each
|
||||
// EntityItem::_simulationState correctly so as to not confuse the next _simulation.
|
||||
|
@ -381,6 +381,7 @@ void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator)
|
|||
}
|
||||
|
||||
if (_simulation) {
|
||||
theEntity->clearActions(_simulation);
|
||||
_simulation->removeEntity(theEntity);
|
||||
}
|
||||
}
|
||||
|
@ -681,7 +682,6 @@ void EntityTree::update() {
|
|||
QSet<EntityItemID> idsToDelete;
|
||||
|
||||
for (auto entity : pendingDeletes) {
|
||||
assert(!entity->getPhysicsInfo()); // TODO: Andrew to remove this after testing
|
||||
idsToDelete.insert(entity->getEntityItemID());
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ public:
|
|||
class EntityItemFBXService {
|
||||
public:
|
||||
virtual const FBXGeometry* getGeometryForEntity(EntityItemPointer entityItem) = 0;
|
||||
virtual const Model* getModelForEntityItem(EntityItemPointer entityItem) = 0;
|
||||
virtual const Model* getModelForEntityItem(EntityItemPointer entityItem) = 0;
|
||||
virtual const FBXGeometry* getCollisionGeometryForEntity(EntityItemPointer entityItem) = 0;
|
||||
};
|
||||
|
||||
|
@ -63,23 +63,23 @@ public:
|
|||
// own definition. Implement these to allow your octree based server to support editing
|
||||
virtual bool getWantSVOfileVersions() const { return true; }
|
||||
virtual PacketType expectedDataPacketType() const { return PacketTypeEntityData; }
|
||||
virtual bool canProcessVersion(PacketVersion thisVersion) const
|
||||
{ return thisVersion >= VERSION_ENTITIES_SUPPORT_SPLIT_MTU; } // we support all versions with split mtu
|
||||
virtual bool canProcessVersion(PacketVersion thisVersion) const
|
||||
{ return thisVersion >= VERSION_ENTITIES_USE_METERS_AND_RADIANS; }
|
||||
virtual bool handlesEditPacketType(PacketType packetType) const;
|
||||
virtual int processEditPacketData(PacketType packetType, const unsigned char* packetData, int packetLength,
|
||||
const unsigned char* editData, int maxLength, const SharedNodePointer& senderNode);
|
||||
|
||||
virtual bool rootElementHasData() const { return true; }
|
||||
|
||||
|
||||
// the root at least needs to store the number of entities in the packet/buffer
|
||||
virtual int minimumRequiredRootDataBytes() const { return sizeof(uint16_t); }
|
||||
virtual bool suppressEmptySubtrees() const { return false; }
|
||||
virtual void releaseSceneEncodeData(OctreeElementExtraEncodeData* extraEncodeData) const;
|
||||
virtual bool mustIncludeAllChildData() const { return false; }
|
||||
|
||||
virtual bool versionHasSVOfileBreaks(PacketVersion thisVersion) const
|
||||
virtual bool versionHasSVOfileBreaks(PacketVersion thisVersion) const
|
||||
{ return thisVersion >= VERSION_ENTITIES_HAS_FILE_BREAKS; }
|
||||
|
||||
|
||||
virtual void update();
|
||||
|
||||
// The newer API...
|
||||
|
@ -111,13 +111,13 @@ public:
|
|||
/// \param foundEntities[out] vector of EntityItemPointer
|
||||
/// \remark Side effect: any initial contents in foundEntities will be lost
|
||||
void findEntities(const glm::vec3& center, float radius, QVector<EntityItemPointer>& foundEntities);
|
||||
|
||||
|
||||
/// finds all entities that touch a cube
|
||||
/// \param cube the query cube in world-frame (meters)
|
||||
/// \param foundEntities[out] vector of non-EntityItemPointer
|
||||
/// \remark Side effect: any initial contents in entities will be lost
|
||||
void findEntities(const AACube& cube, QVector<EntityItemPointer>& foundEntities);
|
||||
|
||||
|
||||
/// finds all entities that touch a box
|
||||
/// \param box the query box in world-frame (meters)
|
||||
/// \param foundEntities[out] vector of non-EntityItemPointer
|
||||
|
@ -129,13 +129,13 @@ public:
|
|||
|
||||
bool hasAnyDeletedEntities() const { return _recentlyDeletedEntityItemIDs.size() > 0; }
|
||||
bool hasEntitiesDeletedSince(quint64 sinceTime);
|
||||
bool encodeEntitiesDeletedSince(OCTREE_PACKET_SEQUENCE sequenceNumber, quint64& sinceTime,
|
||||
bool encodeEntitiesDeletedSince(OCTREE_PACKET_SEQUENCE sequenceNumber, quint64& sinceTime,
|
||||
unsigned char* packetData, size_t maxLength, size_t& outputLength);
|
||||
void forgetEntitiesDeletedBefore(quint64 sinceTime);
|
||||
|
||||
int processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode);
|
||||
int processEraseMessageDetails(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode);
|
||||
|
||||
|
||||
EntityItemFBXService* getFBXService() const { return _fbxService; }
|
||||
void setFBXService(EntityItemFBXService* service) { _fbxService = service; }
|
||||
const FBXGeometry* getGeometryForEntity(EntityItemPointer entityItem) {
|
||||
|
@ -144,7 +144,7 @@ public:
|
|||
const Model* getModelForEntityItem(EntityItemPointer entityItem) {
|
||||
return _fbxService ? _fbxService->getModelForEntityItem(entityItem) : NULL;
|
||||
}
|
||||
|
||||
|
||||
EntityTreeElement* getContainingElement(const EntityItemID& entityItemID) /*const*/;
|
||||
void setContainingElement(const EntityItemID& entityItemID, EntityTreeElement* element);
|
||||
void debugDumpMap();
|
||||
|
@ -158,13 +158,14 @@ public:
|
|||
void emitEntityScriptChanging(const EntityItemID& entityItemID);
|
||||
|
||||
void setSimulation(EntitySimulation* simulation);
|
||||
|
||||
EntitySimulation* getSimulation() const { return _simulation; }
|
||||
|
||||
bool wantEditLogging() const { return _wantEditLogging; }
|
||||
void setWantEditLogging(bool value) { _wantEditLogging = value; }
|
||||
|
||||
bool writeToMap(QVariantMap& entityDescription, OctreeElement* element, bool skipDefaultValues);
|
||||
bool readFromMap(QVariantMap& entityDescription);
|
||||
|
||||
|
||||
float getContentsLargestDimension();
|
||||
|
||||
signals:
|
||||
|
@ -177,7 +178,7 @@ signals:
|
|||
private:
|
||||
|
||||
void processRemovedEntities(const DeleteEntityOperator& theOperator);
|
||||
bool updateEntityWithElement(EntityItemPointer entity, const EntityItemProperties& properties,
|
||||
bool updateEntityWithElement(EntityItemPointer entity, const EntityItemProperties& properties,
|
||||
EntityTreeElement* containingElement,
|
||||
const SharedNodePointer& senderNode = SharedNodePointer(nullptr));
|
||||
static bool findNearPointOperation(OctreeElement* element, void* extraData);
|
||||
|
@ -198,7 +199,7 @@ private:
|
|||
QHash<EntityItemID, EntityTreeElement*> _entityToElementMap;
|
||||
|
||||
EntitySimulation* _simulation;
|
||||
|
||||
|
||||
bool _wantEditLogging = false;
|
||||
void maybeNotifyNewCollisionSoundURL(const QString& oldCollisionSoundURL, const QString& newCollisionSoundURL);
|
||||
};
|
||||
|
|
|
@ -33,7 +33,7 @@ public:
|
|||
_totalItems(0),
|
||||
_movingItems(0)
|
||||
{ }
|
||||
|
||||
|
||||
QList<EntityItemPointer> _movingEntities;
|
||||
int _totalElements;
|
||||
int _totalItems;
|
||||
|
@ -42,8 +42,8 @@ public:
|
|||
|
||||
class EntityTreeElementExtraEncodeData {
|
||||
public:
|
||||
EntityTreeElementExtraEncodeData() :
|
||||
elementCompleted(false),
|
||||
EntityTreeElementExtraEncodeData() :
|
||||
elementCompleted(false),
|
||||
subtreeCompleted(false),
|
||||
entities() {
|
||||
memset(childCompleted, 0, sizeof(childCompleted));
|
||||
|
@ -140,7 +140,7 @@ public:
|
|||
|
||||
virtual bool canRayIntersect() const { return hasEntities(); }
|
||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
||||
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
||||
void** intersectedObject, bool precisionPicking, float distanceToElementCube);
|
||||
|
||||
virtual bool findSpherePenetration(const glm::vec3& center, float radius,
|
||||
|
@ -148,10 +148,11 @@ public:
|
|||
|
||||
const EntityItems& getEntities() const { return *_entityItems; }
|
||||
EntityItems& getEntities() { return *_entityItems; }
|
||||
|
||||
|
||||
bool hasEntities() const { return _entityItems ? _entityItems->size() > 0 : false; }
|
||||
|
||||
void setTree(EntityTree* tree) { _myTree = tree; }
|
||||
EntityTree* getTree() const { return _myTree; }
|
||||
|
||||
bool updateEntity(const EntityItem& entity);
|
||||
void addEntityItem(EntityItemPointer entity);
|
||||
|
|
|
@ -156,7 +156,7 @@ void DynamicCharacterController::playerStep(btCollisionWorld* dynaWorld, btScala
|
|||
velocityCorrection -= velocityCorrection.dot(_currentUp) * _currentUp;
|
||||
}
|
||||
_rigidBody->setLinearVelocity(actualVelocity + tau * velocityCorrection);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
35
libraries/physics/src/ObjectAction.cpp
Normal file
35
libraries/physics/src/ObjectAction.cpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// ObjectAction.cpp
|
||||
// libraries/physcis/src
|
||||
//
|
||||
// Created by Seth Alves 2015-6-2
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "EntitySimulation.h"
|
||||
|
||||
#include "ObjectAction.h"
|
||||
|
||||
ObjectAction::ObjectAction(QUuid id, EntityItemPointer ownerEntity) :
|
||||
btActionInterface(),
|
||||
_id(id),
|
||||
_active(false),
|
||||
_ownerEntity(ownerEntity) {
|
||||
}
|
||||
|
||||
ObjectAction::~ObjectAction() {
|
||||
}
|
||||
|
||||
void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep) {
|
||||
qDebug() << "ObjectAction::updateAction called";
|
||||
}
|
||||
|
||||
void ObjectAction::debugDraw(btIDebugDraw* debugDrawer) {
|
||||
}
|
||||
|
||||
void ObjectAction::removeFromSimulation(EntitySimulation* simulation) const {
|
||||
simulation->removeAction(_id);
|
||||
}
|
50
libraries/physics/src/ObjectAction.h
Normal file
50
libraries/physics/src/ObjectAction.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
//
|
||||
// ObjectAction.h
|
||||
// libraries/physcis/src
|
||||
//
|
||||
// Created by Seth Alves 2015-6-2
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
// http://bulletphysics.org/Bullet/BulletFull/classbtActionInterface.html
|
||||
|
||||
#ifndef hifi_ObjectAction_h
|
||||
#define hifi_ObjectAction_h
|
||||
|
||||
#include <btBulletDynamicsCommon.h>
|
||||
|
||||
#include <QUuid>
|
||||
|
||||
#include <EntityItem.h>
|
||||
|
||||
class ObjectAction : public btActionInterface, public EntityActionInterface {
|
||||
public:
|
||||
ObjectAction(QUuid id, EntityItemPointer ownerEntity);
|
||||
virtual ~ObjectAction();
|
||||
|
||||
const QUuid& getID() const { return _id; }
|
||||
virtual void removeFromSimulation(EntitySimulation* simulation) const;
|
||||
virtual const EntityItemPointer& getOwnerEntity() const { return _ownerEntity; }
|
||||
virtual void setOwnerEntity(const EntityItemPointer ownerEntity) { _ownerEntity = ownerEntity; }
|
||||
virtual bool updateArguments(QVariantMap arguments) { return false; }
|
||||
|
||||
// these are from btActionInterface
|
||||
virtual void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep);
|
||||
virtual void debugDraw(btIDebugDraw* debugDrawer);
|
||||
|
||||
private:
|
||||
QUuid _id;
|
||||
QReadWriteLock _lock;
|
||||
|
||||
protected:
|
||||
bool tryLockForRead() { return _lock.tryLockForRead(); }
|
||||
void lockForWrite() { _lock.lockForWrite(); }
|
||||
void unlock() { _lock.unlock(); }
|
||||
|
||||
bool _active;
|
||||
EntityItemPointer _ownerEntity;
|
||||
};
|
||||
|
||||
#endif // hifi_ObjectAction_h
|
69
libraries/physics/src/ObjectActionPullToPoint.cpp
Normal file
69
libraries/physics/src/ObjectActionPullToPoint.cpp
Normal file
|
@ -0,0 +1,69 @@
|
|||
//
|
||||
// ObjectActionPullToPoint.cpp
|
||||
// libraries/physics/src
|
||||
//
|
||||
// Created by Seth Alves 2015-6-2
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "ObjectMotionState.h"
|
||||
#include "BulletUtil.h"
|
||||
|
||||
#include "ObjectActionPullToPoint.h"
|
||||
|
||||
ObjectActionPullToPoint::ObjectActionPullToPoint(QUuid id, EntityItemPointer ownerEntity) :
|
||||
ObjectAction(id, ownerEntity) {
|
||||
#if WANT_DEBUG
|
||||
qDebug() << "ObjectActionPullToPoint::ObjectActionPullToPoint";
|
||||
#endif
|
||||
}
|
||||
|
||||
ObjectActionPullToPoint::~ObjectActionPullToPoint() {
|
||||
#if WANT_DEBUG
|
||||
qDebug() << "ObjectActionPullToPoint::~ObjectActionPullToPoint";
|
||||
#endif
|
||||
}
|
||||
|
||||
void ObjectActionPullToPoint::updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep) {
|
||||
if (!tryLockForRead()) {
|
||||
// don't risk hanging the thread running the physics simulation
|
||||
return;
|
||||
}
|
||||
void* physicsInfo = _ownerEntity->getPhysicsInfo();
|
||||
|
||||
if (_active && physicsInfo) {
|
||||
ObjectMotionState* motionState = static_cast<ObjectMotionState*>(physicsInfo);
|
||||
btRigidBody* rigidBody = motionState->getRigidBody();
|
||||
if (rigidBody) {
|
||||
glm::vec3 offset = _target - bulletToGLM(rigidBody->getCenterOfMassPosition());
|
||||
float offsetLength = glm::length(offset);
|
||||
if (offsetLength > IGNORE_POSITION_DELTA) {
|
||||
glm::vec3 newVelocity = glm::normalize(offset) * _speed;
|
||||
rigidBody->setLinearVelocity(glmToBullet(newVelocity));
|
||||
rigidBody->activate();
|
||||
} else {
|
||||
rigidBody->setLinearVelocity(glmToBullet(glm::vec3()));
|
||||
}
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
|
||||
bool ObjectActionPullToPoint::updateArguments(QVariantMap arguments) {
|
||||
bool ok = true;
|
||||
glm::vec3 target = EntityActionInterface::extractVec3Argument("pull-to-point action", arguments, "target", ok);
|
||||
float speed = EntityActionInterface::extractFloatArgument("pull-to-point action", arguments, "speed", ok);
|
||||
if (ok) {
|
||||
lockForWrite();
|
||||
_target = target;
|
||||
_speed = speed;
|
||||
_active = true;
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
34
libraries/physics/src/ObjectActionPullToPoint.h
Normal file
34
libraries/physics/src/ObjectActionPullToPoint.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
//
|
||||
// ObjectActionPullToPoint.h
|
||||
// libraries/physics/src
|
||||
//
|
||||
// Created by Seth Alves 2015-6-3
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_ObjectActionPullToPoint_h
|
||||
#define hifi_ObjectActionPullToPoint_h
|
||||
|
||||
#include <QUuid>
|
||||
|
||||
#include <EntityItem.h>
|
||||
#include "ObjectAction.h"
|
||||
|
||||
class ObjectActionPullToPoint : public ObjectAction {
|
||||
public:
|
||||
ObjectActionPullToPoint(QUuid id, EntityItemPointer ownerEntity);
|
||||
virtual ~ObjectActionPullToPoint();
|
||||
|
||||
virtual bool updateArguments(QVariantMap arguments);
|
||||
virtual void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep);
|
||||
|
||||
private:
|
||||
|
||||
glm::vec3 _target;
|
||||
float _speed;
|
||||
};
|
||||
|
||||
#endif // hifi_ObjectActionPullToPoint_h
|
|
@ -39,11 +39,12 @@ enum MotionStateType {
|
|||
// and re-added to the physics engine and "easy" which just updates the body properties.
|
||||
const uint32_t HARD_DIRTY_PHYSICS_FLAGS = (uint32_t)(EntityItem::DIRTY_MOTION_TYPE | EntityItem::DIRTY_SHAPE);
|
||||
const uint32_t EASY_DIRTY_PHYSICS_FLAGS = (uint32_t)(EntityItem::DIRTY_TRANSFORM | EntityItem::DIRTY_VELOCITIES |
|
||||
EntityItem::DIRTY_MASS | EntityItem::DIRTY_COLLISION_GROUP);
|
||||
EntityItem::DIRTY_MASS | EntityItem::DIRTY_COLLISION_GROUP |
|
||||
EntityItem::DIRTY_MATERIAL);
|
||||
|
||||
// These are the set of incoming flags that the PhysicsEngine needs to hear about:
|
||||
const uint32_t DIRTY_PHYSICS_FLAGS = HARD_DIRTY_PHYSICS_FLAGS | EASY_DIRTY_PHYSICS_FLAGS |
|
||||
EntityItem::DIRTY_MATERIAL | (uint32_t)EntityItem::DIRTY_PHYSICS_ACTIVATION;
|
||||
const uint32_t DIRTY_PHYSICS_FLAGS = (uint32_t)(HARD_DIRTY_PHYSICS_FLAGS | EASY_DIRTY_PHYSICS_FLAGS |
|
||||
EntityItem::DIRTY_PHYSICS_ACTIVATION);
|
||||
|
||||
// These are the outgoing flags that the PhysicsEngine can affect:
|
||||
const uint32_t OUTGOING_DIRTY_PHYSICS_FLAGS = EntityItem::DIRTY_TRANSFORM | EntityItem::DIRTY_VELOCITIES;
|
||||
|
|
|
@ -9,10 +9,12 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "PhysicalEntitySimulation.h"
|
||||
#include "PhysicsHelpers.h"
|
||||
#include "PhysicsLogging.h"
|
||||
#include "ShapeManager.h"
|
||||
#include "ObjectActionPullToPoint.h"
|
||||
|
||||
#include "PhysicalEntitySimulation.h"
|
||||
|
||||
PhysicalEntitySimulation::PhysicalEntitySimulation() {
|
||||
}
|
||||
|
@ -36,7 +38,7 @@ void PhysicalEntitySimulation::init(
|
|||
|
||||
// begin EntitySimulation overrides
|
||||
void PhysicalEntitySimulation::updateEntitiesInternal(const quint64& now) {
|
||||
// TODO: add back non-physical kinematic objects and step them forward here
|
||||
// Do nothing here because the "internal" update the PhysicsEngine::stepSimualtion() which is done elsewhere.
|
||||
}
|
||||
|
||||
void PhysicalEntitySimulation::addEntityInternal(EntityItemPointer entity) {
|
||||
|
@ -232,3 +234,37 @@ void PhysicalEntitySimulation::handleCollisionEvents(CollisionEvents& collisionE
|
|||
}
|
||||
}
|
||||
|
||||
EntityActionPointer PhysicalEntitySimulation::actionFactory(EntityActionType type,
|
||||
QUuid id,
|
||||
EntityItemPointer ownerEntity,
|
||||
QVariantMap arguments) {
|
||||
EntityActionPointer action = nullptr;
|
||||
switch (type) {
|
||||
case ACTION_TYPE_NONE:
|
||||
return nullptr;
|
||||
case ACTION_TYPE_PULL_TO_POINT:
|
||||
action = (EntityActionPointer) new ObjectActionPullToPoint(id, ownerEntity);
|
||||
break;
|
||||
}
|
||||
|
||||
bool ok = action->updateArguments(arguments);
|
||||
if (ok) {
|
||||
ownerEntity->addAction(this, action);
|
||||
return action;
|
||||
}
|
||||
|
||||
action = nullptr;
|
||||
return action;
|
||||
}
|
||||
|
||||
void PhysicalEntitySimulation::applyActionChanges() {
|
||||
if (_physicsEngine) {
|
||||
foreach (EntityActionPointer actionToAdd, _actionsToAdd) {
|
||||
_physicsEngine->addAction(actionToAdd);
|
||||
}
|
||||
foreach (QUuid actionToRemove, _actionsToRemove) {
|
||||
_physicsEngine->removeAction(actionToRemove);
|
||||
}
|
||||
}
|
||||
EntitySimulation::applyActionChanges();
|
||||
}
|
||||
|
|
|
@ -32,6 +32,12 @@ public:
|
|||
|
||||
void init(EntityTree* tree, PhysicsEngine* engine, EntityEditPacketSender* packetSender);
|
||||
|
||||
virtual EntityActionPointer actionFactory(EntityActionType type,
|
||||
QUuid id,
|
||||
EntityItemPointer ownerEntity,
|
||||
QVariantMap arguments);
|
||||
virtual void applyActionChanges();
|
||||
|
||||
protected: // only called by EntitySimulation
|
||||
// overrides for EntitySimulation
|
||||
virtual void updateEntitiesInternal(const quint64& now);
|
||||
|
|
|
@ -44,7 +44,6 @@ PhysicsEngine::~PhysicsEngine() {
|
|||
if (_characterController) {
|
||||
_characterController->setDynamicsWorld(nullptr);
|
||||
}
|
||||
// TODO: delete engine components... if we ever plan to create more than one instance
|
||||
delete _collisionConfig;
|
||||
delete _collisionDispatcher;
|
||||
delete _broadphaseFilter;
|
||||
|
@ -168,11 +167,11 @@ void PhysicsEngine::deleteObjects(VectorOfMotionStates& objects) {
|
|||
}
|
||||
}
|
||||
|
||||
// Same as above, but takes a Set instead of a Vector and ommits some cleanup operations. Only called during teardown.
|
||||
// Same as above, but takes a Set instead of a Vector. Should only be called during teardown.
|
||||
void PhysicsEngine::deleteObjects(SetOfMotionStates& objects) {
|
||||
for (auto object : objects) {
|
||||
btRigidBody* body = object->getRigidBody();
|
||||
_dynamicsWorld->removeRigidBody(body);
|
||||
removeObject(object);
|
||||
|
||||
// NOTE: setRigidBody() modifies body->m_userPointer so we should clear the MotionState's body BEFORE deleting it.
|
||||
object->setRigidBody(nullptr);
|
||||
|
@ -437,3 +436,28 @@ int16_t PhysicsEngine::getCollisionMask(int16_t group) const {
|
|||
const int16_t* mask = _collisionMasks.find(btHashInt((int)group));
|
||||
return mask ? *mask : COLLISION_MASK_DEFAULT;
|
||||
}
|
||||
|
||||
void PhysicsEngine::addAction(EntityActionPointer action) {
|
||||
assert(action);
|
||||
const QUuid& actionID = action->getID();
|
||||
if (_objectActions.contains(actionID)) {
|
||||
assert(_objectActions[actionID] == action);
|
||||
return;
|
||||
}
|
||||
|
||||
_objectActions[actionID] = action;
|
||||
|
||||
// bullet needs a pointer to the action, but it doesn't use shared pointers.
|
||||
// is there a way to bump the reference count?
|
||||
ObjectAction* objectAction = static_cast<ObjectAction*>(action.get());
|
||||
_dynamicsWorld->addAction(objectAction);
|
||||
}
|
||||
|
||||
void PhysicsEngine::removeAction(const QUuid actionID) {
|
||||
if (_objectActions.contains(actionID)) {
|
||||
EntityActionPointer action = _objectActions[actionID];
|
||||
ObjectAction* objectAction = static_cast<ObjectAction*>(action.get());
|
||||
_dynamicsWorld->removeAction(objectAction);
|
||||
_objectActions.remove(actionID);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "DynamicCharacterController.h"
|
||||
#include "ObjectMotionState.h"
|
||||
#include "ThreadSafeDynamicsWorld.h"
|
||||
#include "ObjectAction.h"
|
||||
|
||||
const float HALF_SIMULATION_EXTENT = 512.0f; // meters
|
||||
|
||||
|
@ -93,6 +94,9 @@ public:
|
|||
|
||||
int16_t getCollisionMask(int16_t group) const;
|
||||
|
||||
void addAction(EntityActionPointer action);
|
||||
void removeAction(const QUuid actionID);
|
||||
|
||||
private:
|
||||
void removeContacts(ObjectMotionState* motionState);
|
||||
|
||||
|
@ -120,6 +124,9 @@ private:
|
|||
|
||||
QUuid _sessionID;
|
||||
CollisionEvents _collisionEvents;
|
||||
|
||||
QHash<QUuid, EntityActionPointer> _objectActions;
|
||||
|
||||
btHashMap<btHashInt, int16_t> _collisionMasks;
|
||||
};
|
||||
|
||||
|
|
|
@ -19,11 +19,8 @@
|
|||
|
||||
// translates between ShapeInfo and btShape
|
||||
|
||||
// TODO: rename this to ShapeFactory
|
||||
namespace ShapeFactory {
|
||||
|
||||
btConvexHullShape* createConvexHull(const QVector<glm::vec3>& points);
|
||||
|
||||
btCollisionShape* createShapeFromInfo(const ShapeInfo& info);
|
||||
};
|
||||
|
||||
|
|
|
@ -54,7 +54,6 @@ public:
|
|||
bool setScriptContents(const QString& scriptContents, const QString& fileNameString = QString(""));
|
||||
|
||||
const QString& getScriptName() const { return _scriptName; }
|
||||
void cleanupMenuItems();
|
||||
|
||||
QScriptValue registerGlobalObject(const QString& name, QObject* object); /// registers a global object by name
|
||||
void registerGetterSetter(const QString& name, QScriptEngine::FunctionSignature getter,
|
||||
|
|
Loading…
Reference in a new issue