mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 07:57:30 +02:00
commit
30389ad51f
23 changed files with 647 additions and 90 deletions
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
var isGrabbing = false;
|
var isGrabbing = false;
|
||||||
var grabbedEntity = null;
|
var grabbedEntity = null;
|
||||||
|
var actionID = null;
|
||||||
var prevMouse = {};
|
var prevMouse = {};
|
||||||
var deltaMouse = {
|
var deltaMouse = {
|
||||||
z: 0
|
z: 0
|
||||||
|
@ -88,6 +89,7 @@ function mousePressEvent(event) {
|
||||||
gravity: {x: 0, y: 0, z: 0}
|
gravity: {x: 0, y: 0, z: 0}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Controller.mouseMoveEvent.connect(mouseMoveEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +112,10 @@ function updateDropLine(position) {
|
||||||
|
|
||||||
function mouseReleaseEvent() {
|
function mouseReleaseEvent() {
|
||||||
if (isGrabbing) {
|
if (isGrabbing) {
|
||||||
|
Controller.mouseMoveEvent.disconnect(mouseMoveEvent);
|
||||||
isGrabbing = false;
|
isGrabbing = false;
|
||||||
|
Entities.deleteAction(grabbedEntity, actionID);
|
||||||
|
actionID = null;
|
||||||
|
|
||||||
// only restore the original gravity if it's not zero. This is to avoid...
|
// 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
|
// 1. interface A grabs an entity and locally saves off its gravity
|
||||||
|
@ -228,21 +233,25 @@ function update(deltaTime) {
|
||||||
}
|
}
|
||||||
if (shouldRotate) {
|
if (shouldRotate) {
|
||||||
angularVelocity = Vec3.subtract(angularVelocity, Vec3.multiply(angularVelocity, ANGULAR_DAMPING_RATE));
|
angularVelocity = Vec3.subtract(angularVelocity, Vec3.multiply(angularVelocity, ANGULAR_DAMPING_RATE));
|
||||||
|
Entities.editEntity(grabbedEntity, {
|
||||||
|
rotation: currentRotation,
|
||||||
|
angularVelocity: angularVelocity
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
angularVelocity = entityProps.angularVelocity;
|
angularVelocity = entityProps.angularVelocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entities.editEntity(grabbedEntity, {
|
var newSpeed = Vec3.length(newVelocity);
|
||||||
position: currentPosition,
|
if (!actionID) {
|
||||||
rotation: currentRotation,
|
actionID = Entities.addAction("pull-to-point", grabbedEntity, {target: targetPosition, speed: newSpeed});
|
||||||
velocity: newVelocity,
|
} else {
|
||||||
angularVelocity: angularVelocity
|
Entities.updateAction(grabbedEntity, actionID, {target: targetPosition, speed: newSpeed});
|
||||||
});
|
}
|
||||||
|
|
||||||
updateDropLine(targetPosition);
|
updateDropLine(targetPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller.mouseMoveEvent.connect(mouseMoveEvent);
|
|
||||||
Controller.mousePressEvent.connect(mousePressEvent);
|
Controller.mousePressEvent.connect(mousePressEvent);
|
||||||
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
|
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
|
||||||
Controller.keyPressEvent.connect(keyPressEvent);
|
Controller.keyPressEvent.connect(keyPressEvent);
|
||||||
|
|
|
@ -2459,7 +2459,8 @@ void Application::update(float deltaTime) {
|
||||||
|
|
||||||
updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process...
|
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
|
updateCamera(deltaTime); // handle various camera tweaks like off axis projection
|
||||||
updateDialogs(deltaTime); // update various stats dialogs if present
|
updateDialogs(deltaTime); // update various stats dialogs if present
|
||||||
|
@ -2473,6 +2474,7 @@ void Application::update(float deltaTime) {
|
||||||
_physicsEngine.deleteObjects(_entitySimulation.getObjectsToDelete());
|
_physicsEngine.deleteObjects(_entitySimulation.getObjectsToDelete());
|
||||||
_physicsEngine.addObjects(_entitySimulation.getObjectsToAdd());
|
_physicsEngine.addObjects(_entitySimulation.getObjectsToAdd());
|
||||||
_physicsEngine.changeObjects(_entitySimulation.getObjectsToChange());
|
_physicsEngine.changeObjects(_entitySimulation.getObjectsToChange());
|
||||||
|
_entitySimulation.applyActionChanges();
|
||||||
_entitySimulation.unlock();
|
_entitySimulation.unlock();
|
||||||
|
|
||||||
AvatarManager* avatarManager = DependencyManager::get<AvatarManager>().data();
|
AvatarManager* avatarManager = DependencyManager::get<AvatarManager>().data();
|
||||||
|
@ -2495,7 +2497,8 @@ void Application::update(float deltaTime) {
|
||||||
|
|
||||||
if (!_aboutToQuit) {
|
if (!_aboutToQuit) {
|
||||||
PerformanceTimer perfTimer("entities");
|
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);
|
_entitySimulation.handleCollisionEvents(collisionEvents);
|
||||||
// NOTE: the _entities.update() call below will wait for lock
|
// NOTE: the _entities.update() call below will wait for lock
|
||||||
// and will simulate entity motion (the EntityTree has been given an EntitySimulation).
|
// and will simulate entity motion (the EntityTree has been given an EntitySimulation).
|
||||||
|
@ -2512,7 +2515,8 @@ void Application::update(float deltaTime) {
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("myAvatar");
|
PerformanceTimer perfTimer("myAvatar");
|
||||||
updateMyAvatarLookAtPosition();
|
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) {
|
void RenderableLineEntityItem::render(RenderArgs* args) {
|
||||||
PerformanceTimer perfTimer("RenderableLineEntityItem::render");
|
PerformanceTimer perfTimer("RenderableLineEntityItem::render");
|
||||||
assert(getType() == EntityTypes::Line);
|
assert(getType() == EntityTypes::Line);
|
||||||
glm::vec3 position = getPosition();
|
// glm::vec3 position = getPosition();
|
||||||
glm::vec3 dimensions = getDimensions();
|
// glm::vec3 dimensions = getDimensions();
|
||||||
glm::quat rotation = getRotation();
|
glm::quat rotation = getRotation();
|
||||||
glm::vec4 lineColor(toGlm(getXColor()), getLocalRenderAlpha());
|
glm::vec4 lineColor(toGlm(getXColor()), getLocalRenderAlpha());
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
|
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 "EntityItem.h"
|
||||||
#include "EntitiesLogging.h"
|
#include "EntitiesLogging.h"
|
||||||
#include "EntityTree.h"
|
#include "EntityTree.h"
|
||||||
|
#include "EntitySimulation.h"
|
||||||
|
|
||||||
bool EntityItem::_sendPhysicsUpdates = true;
|
bool EntityItem::_sendPhysicsUpdates = true;
|
||||||
|
|
||||||
|
@ -1306,3 +1307,46 @@ void EntityItem::updateSimulatorID(const QUuid& value) {
|
||||||
_dirtyFlags |= EntityItem::DIRTY_SIMULATOR_ID;
|
_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "EntityItemID.h"
|
#include "EntityItemID.h"
|
||||||
#include "EntityItemProperties.h"
|
#include "EntityItemProperties.h"
|
||||||
#include "EntityItemPropertiesDefaults.h"
|
#include "EntityItemPropertiesDefaults.h"
|
||||||
|
#include "EntityActionInterface.h"
|
||||||
#include "EntityTypes.h"
|
#include "EntityTypes.h"
|
||||||
|
|
||||||
class EntitySimulation;
|
class EntitySimulation;
|
||||||
|
@ -177,9 +178,7 @@ public:
|
||||||
EntityTypes::EntityType getType() const { return _type; }
|
EntityTypes::EntityType getType() const { return _type; }
|
||||||
const glm::vec3& getPosition() const { return _position; } /// get position in meters
|
const glm::vec3& getPosition() const { return _position; } /// get position in meters
|
||||||
|
|
||||||
void setPosition(const glm::vec3& value) {
|
void setPosition(const glm::vec3& value) { _position = value; }
|
||||||
_position = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec3 getCenter() const;
|
glm::vec3 getCenter() const;
|
||||||
|
|
||||||
|
@ -348,12 +347,18 @@ public:
|
||||||
|
|
||||||
void getAllTerseUpdateProperties(EntityItemProperties& properties) const;
|
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:
|
protected:
|
||||||
|
|
||||||
static bool _sendPhysicsUpdates;
|
static bool _sendPhysicsUpdates;
|
||||||
EntityTypes::EntityType _type;
|
EntityTypes::EntityType _type;
|
||||||
QUuid _id;
|
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 _lastUpdated; // last time this entity called update(), this includes animations and non-physics changes
|
||||||
quint64 _lastEdited; // last official local or remote edit time
|
quint64 _lastEdited; // last official local or remote edit time
|
||||||
quint64 _lastBroadcast; // the last time we sent an edit packet about this entity
|
quint64 _lastBroadcast; // the last time we sent an edit packet about this entity
|
||||||
|
@ -418,6 +423,8 @@ protected:
|
||||||
EntityTreeElement* _element = nullptr; // set by EntityTreeElement
|
EntityTreeElement* _element = nullptr; // set by EntityTreeElement
|
||||||
void* _physicsInfo = nullptr; // set by EntitySimulation
|
void* _physicsInfo = nullptr; // set by EntitySimulation
|
||||||
bool _simulated; // set by EntitySimulation
|
bool _simulated; // set by EntitySimulation
|
||||||
|
|
||||||
|
QHash<QUuid, EntityActionPointer> _objectActions;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_EntityItem_h
|
#endif // hifi_EntityItem_h
|
||||||
|
|
|
@ -11,13 +11,14 @@
|
||||||
|
|
||||||
#include <VariantMapToScriptValue.h>
|
#include <VariantMapToScriptValue.h>
|
||||||
|
|
||||||
#include "EntityScriptingInterface.h"
|
|
||||||
#include "EntityTree.h"
|
#include "EntityTree.h"
|
||||||
#include "LightEntityItem.h"
|
#include "LightEntityItem.h"
|
||||||
#include "ModelEntityItem.h"
|
#include "ModelEntityItem.h"
|
||||||
#include "ZoneEntityItem.h"
|
#include "ZoneEntityItem.h"
|
||||||
#include "EntitiesLogging.h"
|
#include "EntitiesLogging.h"
|
||||||
|
#include "EntitySimulation.h"
|
||||||
|
|
||||||
|
#include "EntityScriptingInterface.h"
|
||||||
|
|
||||||
EntityScriptingInterface::EntityScriptingInterface() :
|
EntityScriptingInterface::EntityScriptingInterface() :
|
||||||
_entityTree(NULL)
|
_entityTree(NULL)
|
||||||
|
@ -83,7 +84,8 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties
|
||||||
entity->setLastBroadcast(usecTimestampNow());
|
entity->setLastBroadcast(usecTimestampNow());
|
||||||
// This Node is creating a new object. If it's in motion, set this Node as the simulator.
|
// This Node is creating a new object. If it's in motion, set this Node as the simulator.
|
||||||
bidForSimulationOwnership(propertiesWithSimID);
|
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 {
|
} else {
|
||||||
qCDebug(entities) << "script failed to add new Entity to local Octree";
|
qCDebug(entities) << "script failed to add new Entity to local Octree";
|
||||||
success = false;
|
success = false;
|
||||||
|
@ -401,7 +403,6 @@ void RayToEntityIntersectionResultFromScriptValue(const QScriptValue& object, Ra
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool EntityScriptingInterface::setVoxels(QUuid entityID,
|
bool EntityScriptingInterface::setVoxels(QUuid entityID,
|
||||||
std::function<void(PolyVoxEntityItem&)> actor) {
|
std::function<void(PolyVoxEntityItem&)> actor) {
|
||||||
if (!_entityTree) {
|
if (!_entityTree) {
|
||||||
|
@ -439,23 +440,83 @@ bool EntityScriptingInterface::setVoxels(QUuid entityID,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool EntityScriptingInterface::setVoxelSphere(QUuid entityID, const glm::vec3& center, float radius, int value) {
|
bool EntityScriptingInterface::setVoxelSphere(QUuid entityID, const glm::vec3& center, float radius, int value) {
|
||||||
return setVoxels(entityID, [center, radius, value](PolyVoxEntityItem& polyVoxEntity) {
|
return setVoxels(entityID, [center, radius, value](PolyVoxEntityItem& polyVoxEntity) {
|
||||||
polyVoxEntity.setSphere(center, radius, value);
|
polyVoxEntity.setSphere(center, radius, value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool EntityScriptingInterface::setVoxel(QUuid entityID, const glm::vec3& position, int value) {
|
bool EntityScriptingInterface::setVoxel(QUuid entityID, const glm::vec3& position, int value) {
|
||||||
return setVoxels(entityID, [position, value](PolyVoxEntityItem& polyVoxEntity) {
|
return setVoxels(entityID, [position, value](PolyVoxEntityItem& polyVoxEntity) {
|
||||||
polyVoxEntity.setVoxelInVolume(position, value);
|
polyVoxEntity.setVoxelInVolume(position, value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool EntityScriptingInterface::setAllVoxels(QUuid entityID, int value) {
|
bool EntityScriptingInterface::setAllVoxels(QUuid entityID, int value) {
|
||||||
return setVoxels(entityID, [value](PolyVoxEntityItem& polyVoxEntity) {
|
return setVoxels(entityID, [value](PolyVoxEntityItem& polyVoxEntity) {
|
||||||
polyVoxEntity.setAll(value);
|
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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -118,13 +118,16 @@ public slots:
|
||||||
Q_INVOKABLE void setSendPhysicsUpdates(bool value);
|
Q_INVOKABLE void setSendPhysicsUpdates(bool value);
|
||||||
Q_INVOKABLE bool getSendPhysicsUpdates() const;
|
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 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 setVoxel(QUuid entityID, const glm::vec3& position, int value);
|
||||||
Q_INVOKABLE bool setAllVoxels(QUuid entityID, int value);
|
Q_INVOKABLE bool setAllVoxels(QUuid entityID, int value);
|
||||||
|
|
||||||
Q_INVOKABLE void dumpTree() const;
|
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:
|
signals:
|
||||||
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
||||||
void collisionWithEntity(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();
|
void clearingEntities();
|
||||||
|
|
||||||
private:
|
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);
|
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
|
/// actually does the work of finding the ray intersection, can be called in locking mode or tryLock mode
|
||||||
|
|
|
@ -56,6 +56,15 @@ public:
|
||||||
|
|
||||||
friend class EntityTree;
|
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?
|
protected: // these only called by the EntityTree?
|
||||||
/// \param entity pointer to EntityItem to be added
|
/// \param entity pointer to EntityItem to be added
|
||||||
/// \sideeffect sets relevant backpointers in entity, but maybe later when appropriate data structures are locked
|
/// \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 _entitiesToDelete; // entities simulation decided needed to be deleted (EntityTree will actually delete)
|
||||||
SetOfEntities _simpleKinematicEntities; // entities undergoing non-colliding kinematic motion
|
SetOfEntities _simpleKinematicEntities; // entities undergoing non-colliding kinematic motion
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void moveSimpleKinematics();
|
void moveSimpleKinematics();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QList<EntityActionPointer> _actionsToAdd;
|
||||||
|
QList<QUuid> _actionsToRemove;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_EntitySimulation_h
|
#endif // hifi_EntitySimulation_h
|
||||||
|
|
|
@ -381,6 +381,7 @@ void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_simulation) {
|
if (_simulation) {
|
||||||
|
theEntity->clearActions(_simulation);
|
||||||
_simulation->removeEntity(theEntity);
|
_simulation->removeEntity(theEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,6 +158,7 @@ public:
|
||||||
void emitEntityScriptChanging(const EntityItemID& entityItemID);
|
void emitEntityScriptChanging(const EntityItemID& entityItemID);
|
||||||
|
|
||||||
void setSimulation(EntitySimulation* simulation);
|
void setSimulation(EntitySimulation* simulation);
|
||||||
|
EntitySimulation* getSimulation() const { return _simulation; }
|
||||||
|
|
||||||
bool wantEditLogging() const { return _wantEditLogging; }
|
bool wantEditLogging() const { return _wantEditLogging; }
|
||||||
void setWantEditLogging(bool value) { _wantEditLogging = value; }
|
void setWantEditLogging(bool value) { _wantEditLogging = value; }
|
||||||
|
|
|
@ -152,6 +152,7 @@ public:
|
||||||
bool hasEntities() const { return _entityItems ? _entityItems->size() > 0 : false; }
|
bool hasEntities() const { return _entityItems ? _entityItems->size() > 0 : false; }
|
||||||
|
|
||||||
void setTree(EntityTree* tree) { _myTree = tree; }
|
void setTree(EntityTree* tree) { _myTree = tree; }
|
||||||
|
EntityTree* getTree() const { return _myTree; }
|
||||||
|
|
||||||
bool updateEntity(const EntityItem& entity);
|
bool updateEntity(const EntityItem& entity);
|
||||||
void addEntityItem(EntityItemPointer entity);
|
void addEntityItem(EntityItemPointer entity);
|
||||||
|
|
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
|
|
@ -9,10 +9,12 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "PhysicalEntitySimulation.h"
|
|
||||||
#include "PhysicsHelpers.h"
|
#include "PhysicsHelpers.h"
|
||||||
#include "PhysicsLogging.h"
|
#include "PhysicsLogging.h"
|
||||||
#include "ShapeManager.h"
|
#include "ShapeManager.h"
|
||||||
|
#include "ObjectActionPullToPoint.h"
|
||||||
|
|
||||||
|
#include "PhysicalEntitySimulation.h"
|
||||||
|
|
||||||
PhysicalEntitySimulation::PhysicalEntitySimulation() {
|
PhysicalEntitySimulation::PhysicalEntitySimulation() {
|
||||||
}
|
}
|
||||||
|
@ -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);
|
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
|
protected: // only called by EntitySimulation
|
||||||
// overrides for EntitySimulation
|
// overrides for EntitySimulation
|
||||||
virtual void updateEntitiesInternal(const quint64& now);
|
virtual void updateEntitiesInternal(const quint64& now);
|
||||||
|
|
|
@ -436,3 +436,28 @@ int16_t PhysicsEngine::getCollisionMask(int16_t group) const {
|
||||||
const int16_t* mask = _collisionMasks.find(btHashInt((int)group));
|
const int16_t* mask = _collisionMasks.find(btHashInt((int)group));
|
||||||
return mask ? *mask : COLLISION_MASK_DEFAULT;
|
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 "DynamicCharacterController.h"
|
||||||
#include "ObjectMotionState.h"
|
#include "ObjectMotionState.h"
|
||||||
#include "ThreadSafeDynamicsWorld.h"
|
#include "ThreadSafeDynamicsWorld.h"
|
||||||
|
#include "ObjectAction.h"
|
||||||
|
|
||||||
const float HALF_SIMULATION_EXTENT = 512.0f; // meters
|
const float HALF_SIMULATION_EXTENT = 512.0f; // meters
|
||||||
|
|
||||||
|
@ -93,6 +94,9 @@ public:
|
||||||
|
|
||||||
int16_t getCollisionMask(int16_t group) const;
|
int16_t getCollisionMask(int16_t group) const;
|
||||||
|
|
||||||
|
void addAction(EntityActionPointer action);
|
||||||
|
void removeAction(const QUuid actionID);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void removeContacts(ObjectMotionState* motionState);
|
void removeContacts(ObjectMotionState* motionState);
|
||||||
|
|
||||||
|
@ -120,6 +124,9 @@ private:
|
||||||
|
|
||||||
QUuid _sessionID;
|
QUuid _sessionID;
|
||||||
CollisionEvents _collisionEvents;
|
CollisionEvents _collisionEvents;
|
||||||
|
|
||||||
|
QHash<QUuid, EntityActionPointer> _objectActions;
|
||||||
|
|
||||||
btHashMap<btHashInt, int16_t> _collisionMasks;
|
btHashMap<btHashInt, int16_t> _collisionMasks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,6 @@ public:
|
||||||
bool setScriptContents(const QString& scriptContents, const QString& fileNameString = QString(""));
|
bool setScriptContents(const QString& scriptContents, const QString& fileNameString = QString(""));
|
||||||
|
|
||||||
const QString& getScriptName() const { return _scriptName; }
|
const QString& getScriptName() const { return _scriptName; }
|
||||||
void cleanupMenuItems();
|
|
||||||
|
|
||||||
QScriptValue registerGlobalObject(const QString& name, QObject* object); /// registers a global object by name
|
QScriptValue registerGlobalObject(const QString& name, QObject* object); /// registers a global object by name
|
||||||
void registerGetterSetter(const QString& name, QScriptEngine::FunctionSignature getter,
|
void registerGetterSetter(const QString& name, QScriptEngine::FunctionSignature getter,
|
||||||
|
|
Loading…
Reference in a new issue