mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 21:15:07 +02:00
add support for scripts to call methods on entity scripts
This commit is contained in:
parent
8f5055d212
commit
0d37511071
7 changed files with 92 additions and 46 deletions
|
@ -69,6 +69,7 @@ var STATE_CLOSE_GRABBING = 2;
|
|||
var STATE_CONTINUE_CLOSE_GRABBING = 3;
|
||||
var STATE_RELEASE = 4;
|
||||
|
||||
var GRAB_USER_DATA_KEY = "grabKey";
|
||||
|
||||
function controller(hand, triggerAction) {
|
||||
this.hand = hand;
|
||||
|
@ -89,6 +90,7 @@ function controller(hand, triggerAction) {
|
|||
this.state = 0; // 0 = searching, 1 = distanceHolding, 2 = closeGrabbing
|
||||
this.pointer = null; // entity-id of line object
|
||||
this.triggerValue = 0; // rolling average of trigger value
|
||||
this.alreadyDistanceHolding = false; // FIXME - I'll leave it to Seth to potentially make this another state
|
||||
|
||||
this.update = function() {
|
||||
switch(this.state) {
|
||||
|
@ -210,13 +212,20 @@ function controller(hand, triggerAction) {
|
|||
this.distanceHolding = function() {
|
||||
if (!this.triggerSmoothedSqueezed()) {
|
||||
this.state = STATE_RELEASE;
|
||||
this.alreadyDistanceHolding = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.alreadyDistanceHolding) {
|
||||
this.activateEntity(this.grabbedEntity);
|
||||
this.alreadyDistanceHolding = true;
|
||||
}
|
||||
|
||||
var handPosition = this.getHandPosition();
|
||||
var handControllerPosition = Controller.getSpatialControlPosition(this.palm);
|
||||
var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm));
|
||||
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity);
|
||||
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position","rotation"]);
|
||||
Entities.callEntityMethod(this.grabbedEntity, "distanceHolding");
|
||||
|
||||
this.lineOn(handPosition, Vec3.subtract(grabbedProperties.position, handPosition), INTERSECT_COLOR);
|
||||
|
||||
|
@ -270,7 +279,9 @@ function controller(hand, triggerAction) {
|
|||
|
||||
this.lineOff();
|
||||
|
||||
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity);
|
||||
this.activateEntity(this.grabbedEntity);
|
||||
|
||||
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, "position");
|
||||
|
||||
var handRotation = this.getHandRotation();
|
||||
var handPosition = this.getHandPosition();
|
||||
|
@ -294,6 +305,7 @@ function controller(hand, triggerAction) {
|
|||
} else {
|
||||
this.state = STATE_CONTINUE_CLOSE_GRABBING;
|
||||
}
|
||||
Entities.callEntityMethod(this.grabbedEntity, "closeGrabbing");
|
||||
}
|
||||
|
||||
|
||||
|
@ -324,6 +336,7 @@ function controller(hand, triggerAction) {
|
|||
|
||||
this.currentObjectPosition = grabbedProperties.position;
|
||||
this.currentObjectTime = now;
|
||||
Entities.callEntityMethod(this.grabbedEntity, "continueCloseGrabbing");
|
||||
}
|
||||
|
||||
|
||||
|
@ -336,7 +349,10 @@ function controller(hand, triggerAction) {
|
|||
|
||||
// the action will tend to quickly bring an object's velocity to zero. now that
|
||||
// the action is gone, set the objects velocity to something the holder might expect.
|
||||
Entities.editEntity(this.grabbedEntity, {velocity: this.grabbedVelocity});
|
||||
Entities.editEntity(this.grabbedEntity, { velocity: this.grabbedVelocity });
|
||||
|
||||
Entities.callEntityMethod(this.grabbedEntity, "release");
|
||||
this.deactivateEntity(this.grabbedEntity);
|
||||
|
||||
this.grabbedVelocity = ZERO_VEC;
|
||||
this.grabbedEntity = null;
|
||||
|
@ -348,6 +364,22 @@ function controller(hand, triggerAction) {
|
|||
this.cleanup = function() {
|
||||
release();
|
||||
}
|
||||
|
||||
this.activateEntity = function(entity) {
|
||||
var data = {
|
||||
activated: true,
|
||||
avatarId: MyAvatar.sessionUUID
|
||||
};
|
||||
setEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, data);
|
||||
}
|
||||
|
||||
this.deactivateEntity = function(entity) {
|
||||
var data = {
|
||||
activated: false,
|
||||
avatarId: null
|
||||
};
|
||||
setEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
//
|
||||
|
||||
(function() {
|
||||
Script.include("../libraries/utils.js");
|
||||
|
||||
var _this;
|
||||
|
||||
|
@ -24,39 +23,18 @@
|
|||
|
||||
DetectGrabbed.prototype = {
|
||||
|
||||
// update() will be called regulary, because we've hooked the update signal in our preload() function
|
||||
// we will check out userData for the grabData. In the case of the hydraGrab script, it will tell us
|
||||
// if we're currently being grabbed and if the person grabbing us is the current interfaces avatar.
|
||||
// we will watch this for state changes and print out if we're being grabbed or released when it changes.
|
||||
update: function() {
|
||||
var GRAB_USER_DATA_KEY = "grabKey";
|
||||
distanceHolding: function () {
|
||||
print("I am being distance held... entity:" + this.entityID);
|
||||
},
|
||||
|
||||
// because the update() signal doesn't have a valid this, we need to use our memorized _this to access our entityID
|
||||
var entityID = _this.entityID;
|
||||
|
||||
// we want to assume that if there is no grab data, then we are not being grabbed
|
||||
var defaultGrabData = { activated: false, avatarId: null };
|
||||
|
||||
// this handy function getEntityCustomData() is available in utils.js and it will return just the specific section
|
||||
// of user data we asked for. If it's not available it returns our default data.
|
||||
var grabData = getEntityCustomData(GRAB_USER_DATA_KEY, entityID, defaultGrabData);
|
||||
|
||||
// if the grabData says we're being grabbed, and the owner ID is our session, then we are being grabbed by this interface
|
||||
if (grabData.activated && grabData.avatarId == MyAvatar.sessionUUID) {
|
||||
|
||||
// remember we're being grabbed so we can detect being released
|
||||
_this.beingGrabbed = true;
|
||||
|
||||
// print out that we're being grabbed
|
||||
print("I'm being grabbed...");
|
||||
|
||||
} else if (_this.beingGrabbed) {
|
||||
|
||||
// if we are not being grabbed, and we previously were, then we were just released, remember that
|
||||
// and print out a message
|
||||
_this.beingGrabbed = false;
|
||||
print("I'm was released...");
|
||||
}
|
||||
closeGrabbing: function () {
|
||||
print("I was just grabbed... entity:" + this.entityID);
|
||||
},
|
||||
continueCloseGrabbing: function () {
|
||||
print("I am still being grabbed... entity:" + this.entityID);
|
||||
},
|
||||
release: function () {
|
||||
print("I was released... entity:" + this.entityID);
|
||||
},
|
||||
|
||||
// preload() will be called when the entity has become visible (or known) to the interface
|
||||
|
@ -65,14 +43,6 @@
|
|||
// * connecting to the update signal so we can check our grabbed state
|
||||
preload: function(entityID) {
|
||||
this.entityID = entityID;
|
||||
Script.update.connect(this.update);
|
||||
},
|
||||
|
||||
// unload() will be called when our entity is no longer available. It may be because we were deleted,
|
||||
// or because we've left the domain or quit the application. In all cases we want to unhook our connection
|
||||
// to the update signal
|
||||
unload: function(entityID) {
|
||||
Script.update.disconnect(this.update);
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -112,6 +112,7 @@ void EntityTreeRenderer::init() {
|
|||
_scriptingServices->getControllerScriptingInterface());
|
||||
_scriptingServices->registerScriptEngineWithApplicationServices(_entitiesScriptEngine);
|
||||
_entitiesScriptEngine->runInThread();
|
||||
DependencyManager::get<EntityScriptingInterface>()->setEntitiesScriptEngine(_entitiesScriptEngine);
|
||||
}
|
||||
|
||||
// make sure our "last avatar position" is something other than our current position, so that on our
|
||||
|
|
25
libraries/entities/src/EntitiesScriptEngineProvider.h
Normal file
25
libraries/entities/src/EntitiesScriptEngineProvider.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// EntitiesScriptEngineProvider.h
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on Sept. 18, 2015
|
||||
// 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
|
||||
//
|
||||
// TODO: How will we handle collision callbacks with Entities
|
||||
//
|
||||
|
||||
#ifndef hifi_EntitiesScriptEngineProvider_h
|
||||
#define hifi_EntitiesScriptEngineProvider_h
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include "EntityItemID.h"
|
||||
|
||||
class EntitiesScriptEngineProvider {
|
||||
public:
|
||||
virtual void callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName) = 0;
|
||||
};
|
||||
|
||||
#endif // hifi_EntitiesScriptEngineProvider_h
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "EntityScriptingInterface.h"
|
||||
|
||||
#include "EntityItemID.h"
|
||||
#include <VariantMapToScriptValue.h>
|
||||
|
||||
#include "EntitiesLogging.h"
|
||||
|
@ -211,6 +212,14 @@ void EntityScriptingInterface::deleteEntity(QUuid id) {
|
|||
}
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::callEntityMethod(QUuid id, const QString& method) {
|
||||
if (_entitiesScriptEngine) {
|
||||
EntityItemID entityID{ id };
|
||||
_entitiesScriptEngine->callEntityScriptMethod(entityID, method);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QUuid EntityScriptingInterface::findClosestEntity(const glm::vec3& center, float radius) const {
|
||||
EntityItemID result;
|
||||
if (_entityTree) {
|
||||
|
|
|
@ -20,18 +20,19 @@
|
|||
#include <Octree.h>
|
||||
#include <OctreeScriptingInterface.h>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
|
||||
#include "PolyVoxEntityItem.h"
|
||||
#include "LineEntityItem.h"
|
||||
#include "PolyLineEntityItem.h"
|
||||
#include "EntityTree.h"
|
||||
|
||||
#include "EntityEditPacketSender.h"
|
||||
#include "EntitiesScriptEngineProvider.h"
|
||||
|
||||
|
||||
class EntityTree;
|
||||
class MouseEvent;
|
||||
|
||||
|
||||
class RayToEntityIntersectionResult {
|
||||
public:
|
||||
RayToEntityIntersectionResult();
|
||||
|
@ -63,6 +64,7 @@ public:
|
|||
|
||||
void setEntityTree(EntityTreePointer modelTree);
|
||||
EntityTreePointer getEntityTree() { return _entityTree; }
|
||||
void setEntitiesScriptEngine(EntitiesScriptEngineProvider* engine) { _entitiesScriptEngine = engine; }
|
||||
|
||||
public slots:
|
||||
|
||||
|
@ -86,6 +88,11 @@ public slots:
|
|||
/// deletes a model
|
||||
Q_INVOKABLE void deleteEntity(QUuid entityID);
|
||||
|
||||
/// Allows a script to call a method on an entity's script. The method will execute in the entity script
|
||||
/// engine. If the entity does not have an entity script or the method does not exist, this call will have
|
||||
/// no effect.
|
||||
Q_INVOKABLE void callEntityMethod(QUuid entityID, const QString& method);
|
||||
|
||||
/// finds the closest model to the center point, within the radius
|
||||
/// 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
|
||||
|
@ -180,6 +187,7 @@ private:
|
|||
bool precisionPicking);
|
||||
|
||||
EntityTreePointer _entityTree;
|
||||
EntitiesScriptEngineProvider* _entitiesScriptEngine = nullptr;
|
||||
};
|
||||
|
||||
#endif // hifi_EntityScriptingInterface_h
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <AvatarHashMap.h>
|
||||
#include <LimitedNodeList.h>
|
||||
#include <EntityItemID.h>
|
||||
#include <EntitiesScriptEngineProvider.h>
|
||||
|
||||
#include "AbstractControllerScriptingInterface.h"
|
||||
#include "ArrayBufferClass.h"
|
||||
|
@ -46,7 +47,7 @@ public:
|
|||
QScriptValue scriptObject;
|
||||
};
|
||||
|
||||
class ScriptEngine : public QScriptEngine, public ScriptUser {
|
||||
class ScriptEngine : public QScriptEngine, public ScriptUser, public EntitiesScriptEngineProvider {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ScriptEngine(const QString& scriptContents = NO_SCRIPT,
|
||||
|
|
Loading…
Reference in a new issue