History

more Models->Entities renaming

ZappoMan committed 12 years ago

Commit c4fe36b1 parent a60e66b25 files · +8 −8Browse files

Showing the changes to libraries/entities/src/EntityScriptingInterface.cpp (1 of 25 files). Show all

Unified · Split

libraries/entities/src/EntityScriptingInterface.cpp+287−0
@@ -0,0 +1,287 @@
1+//
2+// EntityScriptingInterface.cpp
3+// libraries/models/src
4+//
5+// Created by Brad Hefta-Gaub on 12/6/13.
6+// Copyright 2013 High Fidelity, Inc.
7+//
8+// Distributed under the Apache License, Version 2.0.
9+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
10+//
11+
12+#include "EntityScriptingInterface.h"
13+#include "EntityTree.h"
14+
15+EntityScriptingInterface::EntityScriptingInterface() :
16+ _nextCreatorTokenID(0),
17+ _entityTree(NULL)
18+{
19+}
20+
21+
22+void EntityScriptingInterface::queueEntityMessage(PacketType packetType,
23+ EntityItemID entityID, const EntityItemProperties& properties) {
24+ getEntityPacketSender()->queueEntityEditMessage(packetType, entityID, properties);
25+}
26+
27+EntityItemID EntityScriptingInterface::addEntity(const EntityItemProperties& properties) {
28+
29+ // The application will keep track of creatorTokenID
30+ uint32_t creatorTokenID = EntityItem::getNextCreatorTokenID();
31+
32+ EntityItemID id(NEW_MODEL, creatorTokenID, false );
33+
34+ // queue the packet
35+ queueEntityMessage(PacketTypeEntityAddOrEdit, id, properties);
36+
37+ // If we have a local model tree set, then also update it.
38+ if (_entityTree) {
39+ _entityTree->lockForWrite();
40+ _entityTree->addEntity(id, properties);
41+ _entityTree->unlock();
42+ }
43+
44+ return id;
45+}
46+
47+EntityItemID EntityScriptingInterface::identifyEntity(EntityItemID entityID) {
48+ uint32_t actualID = entityID.id;
49+
50+ if (!entityID.isKnownID) {
51+ actualID = EntityItem::getIDfromCreatorTokenID(entityID.creatorTokenID);
52+ if (actualID == UNKNOWN_MODEL_ID) {
53+ return entityID; // bailing early
54+ }
55+
56+ // found it!
57+ entityID.id = actualID;
58+ entityID.isKnownID = true;
59+ }
60+ return entityID;
61+}
62+
63+EntityItemProperties EntityScriptingInterface::getEntityProperties(EntityItemID entityID) {
64+ EntityItemProperties results;
65+ EntityItemID identity = identifyEntity(entityID);
66+ if (!identity.isKnownID) {
67+ results.setIsUnknownID();
68+ return results;
69+ }
70+ if (_entityTree) {
71+ _entityTree->lockForRead();
72+ const EntityItem* model = _entityTree->findEntityByID(identity.id, true);
73+ if (model) {
74+ results.copyFromEntityItem(*model);
75+ } else {
76+ results.setIsUnknownID();
77+ }
78+ _entityTree->unlock();
79+ }
80+
81+ return results;
82+}
83+
84+
85+
86+EntityItemID EntityScriptingInterface::editEntity(EntityItemID entityID, const EntityItemProperties& properties) {
87+ uint32_t actualID = entityID.id;
88+
89+ // if the model is unknown, attempt to look it up
90+ if (!entityID.isKnownID) {
91+ actualID = EntityItem::getIDfromCreatorTokenID(entityID.creatorTokenID);
92+ }
93+
94+ // if at this point, we know the id, send the update to the model server
95+ if (actualID != UNKNOWN_MODEL_ID) {
96+ entityID.id = actualID;
97+ entityID.isKnownID = true;
98+ queueEntityMessage(PacketTypeEntityAddOrEdit, entityID, properties);
99+ }
100+
101+ // If we have a local model tree set, then also update it. We can do this even if we don't know
102+ // the actual id, because we can edit out local models just with creatorTokenID
103+ if (_entityTree) {
104+ _entityTree->lockForWrite();
105+ _entityTree->updateEntity(entityID, properties);
106+ _entityTree->unlock();
107+ }
108+ return entityID;
109+}
110+
111+
112+// TODO: This deleteEntity() method uses the PacketType_MODEL_ADD_OR_EDIT message to send
113+// a changed model with a shouldDie() property set to true. This works and is currently the only
114+// way to tell the model server to delete a model. But we should change this to use the PacketType_MODEL_ERASE
115+// message which takes a list of model id's to delete.
116+void EntityScriptingInterface::deleteEntity(EntityItemID entityID) {
117+
118+ // setup properties to kill the model
119+ EntityItemProperties properties;
120+ properties.setShouldDie(true);
121+
122+ uint32_t actualID = entityID.id;
123+
124+ // if the model is unknown, attempt to look it up
125+ if (!entityID.isKnownID) {
126+ actualID = EntityItem::getIDfromCreatorTokenID(entityID.creatorTokenID);
127+ }
128+
129+ // if at this point, we know the id, send the update to the model server
130+ if (actualID != UNKNOWN_MODEL_ID) {
131+ entityID.id = actualID;
132+ entityID.isKnownID = true;
133+ queueEntityMessage(PacketTypeEntityAddOrEdit, entityID, properties);
134+ }
135+
136+ // If we have a local model tree set, then also update it.
137+ if (_entityTree) {
138+ _entityTree->lockForWrite();
139+ _entityTree->deleteEntity(entityID);
140+ _entityTree->unlock();
141+ }
142+}
143+
144+EntityItemID EntityScriptingInterface::findClosestEntity(const glm::vec3& center, float radius) const {
145+ EntityItemID result(UNKNOWN_MODEL_ID, UNKNOWN_MODEL_TOKEN, false);
146+ if (_entityTree) {
147+ _entityTree->lockForRead();
148+ const EntityItem* closestEntity = _entityTree->findClosestEntity(center/(float)TREE_SCALE,
149+ radius/(float)TREE_SCALE);
150+ _entityTree->unlock();
151+ if (closestEntity) {
152+ result.id = closestEntity->getID();
153+ result.isKnownID = true;
154+ }
155+ }
156+ return result;
157+}
158+
159+
160+QVector<EntityItemID> EntityScriptingInterface::findEntities(const glm::vec3& center, float radius) const {
161+ QVector<EntityItemID> result;
162+ if (_entityTree) {
163+ _entityTree->lockForRead();
164+ QVector<const EntityItem*> models;
165+ _entityTree->findEntities(center/(float)TREE_SCALE, radius/(float)TREE_SCALE, models);
166+ _entityTree->unlock();
167+
168+ foreach (const EntityItem* model, models) {
169+ EntityItemID thisEntityItemID(model->getID(), UNKNOWN_MODEL_TOKEN, true);
170+ result << thisEntityItemID;
171+ }
172+ }
173+ return result;
174+}
175+
176+RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersection(const PickRay& ray) {
177+ return findRayIntersectionWorker(ray, Octree::TryLock);
178+}
179+
180+RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionBlocking(const PickRay& ray) {
181+ return findRayIntersectionWorker(ray, Octree::Lock);
182+}
183+
184+RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionWorker(const PickRay& ray,
185+ Octree::lockType lockType) {
186+ RayToEntityIntersectionResult result;
187+ if (_entityTree) {
188+ OctreeElement* element;
189+ EntityItem* intersectedEntity;
190+ result.intersects = _entityTree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face,
191+ (void**)&intersectedEntity, lockType, &result.accurate);
192+ if (result.intersects && intersectedEntity) {
193+ result.entityID = intersectedEntity->getEntityItemID();
194+ result.properties = intersectedEntity->getProperties();
195+ result.intersection = ray.origin + (ray.direction * result.distance);
196+ }
197+ }
198+ return result;
199+}
200+
201+
202+RayToEntityIntersectionResult::RayToEntityIntersectionResult() :
203+ intersects(false),
204+ accurate(true), // assume it's accurate
205+ entityID(),
206+ properties(),
207+ distance(0),
208+ face()
209+{
210+};
211+
212+QScriptValue RayToEntityIntersectionResultToScriptValue(QScriptEngine* engine, const RayToEntityIntersectionResult& value) {
213+ QScriptValue obj = engine->newObject();
214+ obj.setProperty("intersects", value.intersects);
215+ obj.setProperty("accurate", value.accurate);
216+ QScriptValue modelItemValue = EntityItemIDtoScriptValue(engine, value.entityID);
217+ obj.setProperty("entityID", modelItemValue);
218+
219+ QScriptValue modelPropertiesValue = EntityItemPropertiesToScriptValue(engine, value.properties);
220+ obj.setProperty("properties", modelPropertiesValue);
221+
222+ obj.setProperty("distance", value.distance);
223+
224+ QString faceName = "";
225+ // handle BoxFace
226+ switch (value.face) {
227+ case MIN_X_FACE:
228+ faceName = "MIN_X_FACE";
229+ break;
230+ case MAX_X_FACE:
231+ faceName = "MAX_X_FACE";
232+ break;
233+ case MIN_Y_FACE:
234+ faceName = "MIN_Y_FACE";
235+ break;
236+ case MAX_Y_FACE:
237+ faceName = "MAX_Y_FACE";
238+ break;
239+ case MIN_Z_FACE:
240+ faceName = "MIN_Z_FACE";
241+ break;
242+ case MAX_Z_FACE:
243+ faceName = "MAX_Z_FACE";
244+ break;
245+ case UNKNOWN_FACE:
246+ faceName = "UNKNOWN_FACE";
247+ break;
248+ }
249+ obj.setProperty("face", faceName);
250+
251+ QScriptValue intersection = vec3toScriptValue(engine, value.intersection);
252+ obj.setProperty("intersection", intersection);
253+ return obj;
254+}
255+
256+void RayToEntityIntersectionResultFromScriptValue(const QScriptValue& object, RayToEntityIntersectionResult& value) {
257+ value.intersects = object.property("intersects").toVariant().toBool();
258+ value.accurate = object.property("accurate").toVariant().toBool();
259+ QScriptValue modelIDValue = object.property("entityID");
260+ if (modelIDValue.isValid()) {
261+ EntityItemIDfromScriptValue(modelIDValue, value.entityID);
262+ }
263+ QScriptValue modelPropertiesValue = object.property("properties");
264+ if (modelPropertiesValue.isValid()) {
265+ EntityItemPropertiesFromScriptValue(modelPropertiesValue, value.properties);
266+ }
267+ value.distance = object.property("distance").toVariant().toFloat();
268+
269+ QString faceName = object.property("face").toVariant().toString();
270+ if (faceName == "MIN_X_FACE") {
271+ value.face = MIN_X_FACE;
272+ } else if (faceName == "MAX_X_FACE") {
273+ value.face = MAX_X_FACE;
274+ } else if (faceName == "MIN_Y_FACE") {
275+ value.face = MIN_Y_FACE;
276+ } else if (faceName == "MAX_Y_FACE") {
277+ value.face = MAX_Y_FACE;
278+ } else if (faceName == "MIN_Z_FACE") {
279+ value.face = MIN_Z_FACE;
280+ } else {
281+ value.face = MAX_Z_FACE;
282+ };
283+ QScriptValue intersection = object.property("intersection");
284+ if (intersection.isValid()) {
285+ vec3FromScriptValue(intersection, value.intersection);
286+ }
287+}