History

fix crash in butterflies.js

ZappoMan committed 12 years ago

Commit ffe1e2d1 parent d01b73b6 files · +167 −45Browse files

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

Unified · Split

libraries/entities/src/UpdateEntityOperator.cpp+121−21
@@ -36,6 +36,10 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTree* tree, · 35 unmodified lines
3636 {
3737 // caller must have verified existence of containingElement and oldEntity
3838 assert(_containingElement && _existingEntity);
39+
40+ if (_wantDebug) {
41+ qDebug() << "UpdateEntityOperator::UpdateEntityOperator() -----------------------------";
42+ }
3943
4044 // Here we have a choice to make, do we want to "tight fit" the actual minimum for the
4145 // entity into the the element, or do we want to use the entities "relaxed" bounds
@@ -50,10 +54,19 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTree* tree, · 8 unmodified lines
5054 if (_properties.containsPositionChange() && !_properties.containsDimensionsChange()) {
5155 glm::vec3 oldDimensionsInMeters = _existingEntity->getDimensions() * (float)TREE_SCALE;
5256 _properties.setDimensions(oldDimensionsInMeters);
57+
58+ if (_wantDebug) {
59+ qDebug() << " ** setting properties dimensions - had position change, no dimension change **";
60+ }
61+
5362 }
5463 if (!_properties.containsPositionChange() && _properties.containsDimensionsChange()) {
5564 glm::vec3 oldPositionInMeters = _existingEntity->getPosition() * (float)TREE_SCALE;
5665 _properties.setPosition(oldPositionInMeters);
66+
67+ if (_wantDebug) {
68+ qDebug() << " ** setting properties position - had dimensions change, no position change **";
69+ }
5770 }
5871
5972 // If our new properties don't have bounds details (no change to position, etc) or if this containing element would
@@ -64,6 +77,11 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTree* tree, · 4 unmodified lines
6477 // if we don't have bounds properties, then use our old clamped box to determine best fit
6578 if (!_properties.containsBoundsProperties()) {
6679 oldElementBestFit = _containingElement->bestFitBounds(_oldEntityBox);
80+
81+ if (_wantDebug) {
82+ qDebug() << " ** old Element best fit - no dimensions change, no position change **";
83+ }
84+
6785 }
6886
6987 // For some reason we've seen a case where the original containing element isn't a best fit for the old properties
@@ -71,20 +89,36 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTree* tree, · 1 unmodified line
7189 if (!_properties.containsBoundsProperties() && !oldElementBestFit) {
7290 _newEntityCube = _oldEntityCube;
7391 _removeOld = true; // our properties are going to move us, so remember this for later processing
92+
93+ if (_wantDebug) {
94+ qDebug() << " **** UNUSUAL CASE **** no changes, but not best fit... consider it a move.... **";
95+ }
96+
97+
7498 } else if (!_properties.containsBoundsProperties() || oldElementBestFit) {
7599 _foundOld = true;
76100 _newEntityCube = _oldEntityCube;
77101 _dontMove = true;
102+
103+ if (_wantDebug) {
104+ qDebug() << " **** TYPICAL NO MOVE CASE ****";
105+ qDebug() << " _properties.containsBoundsProperties():" << _properties.containsBoundsProperties();
106+ qDebug() << " oldElementBestFit:" << oldElementBestFit;
107+ }
108+
78109 } else {
79110 _newEntityCube = _properties.getMaximumAACubeInTreeUnits();
80111 _removeOld = true; // our properties are going to move us, so remember this for later processing
112+
113+ if (_wantDebug) {
114+ qDebug() << " **** TYPICAL MOVE CASE ****";
115+ }
81116 }
82117
83118 _newEntityBox = _newEntityCube.clamp(0.0f, 1.0f); // clamp to domain bounds
84119
85120
86121 if (_wantDebug) {
87− qDebug() << "UpdateEntityOperator::UpdateEntityOperator() -----------------------------";
88122 qDebug() << " _entityItemID:" << _entityItemID;
89123 qDebug() << " _containingElementCube:" << _containingElementCube;
90124 qDebug() << " _oldEntityCube:" << _oldEntityCube;
@@ -108,31 +142,30 @@ bool UpdateEntityOperator::subTreeContainsOldEntity(OctreeElement* element) { · 17 unmodified lines
108142 // so when we're searching the tree for the old element, we use the known cube for the known containing element
109143 bool elementContainsOldBox = element->getAACube().contains(_containingElementCube);
110144
111− /*
112− bool elementContainsOldCube = element->getAACube().contains(_oldEntityCube);
113− qDebug() << "UpdateEntityOperator::subTreeContainsOldEntity()....";
114− qDebug() << " element->getAACube()=" << element->getAACube();
115− qDebug() << " _oldEntityCube=" << _oldEntityCube;
116− qDebug() << " _oldEntityBox=" << _oldEntityBox;
117− qDebug() << " elementContainsOldCube=" << elementContainsOldCube;
118− qDebug() << " elementContainsOldBox=" << elementContainsOldBox;
119− */
120−
145+ if (_wantDebug) {
146+ bool elementContainsOldCube = element->getAACube().contains(_oldEntityCube);
147+ qDebug() << "UpdateEntityOperator::subTreeContainsOldEntity()....";
148+ qDebug() << " element->getAACube()=" << element->getAACube();
149+ qDebug() << " _oldEntityCube=" << _oldEntityCube;
150+ qDebug() << " _oldEntityBox=" << _oldEntityBox;
151+ qDebug() << " elementContainsOldCube=" << elementContainsOldCube;
152+ qDebug() << " elementContainsOldBox=" << elementContainsOldBox;
153+ }
121154 return elementContainsOldBox;
122155 }
123156
124157 bool UpdateEntityOperator::subTreeContainsNewEntity(OctreeElement* element) {
125158 bool elementContainsNewBox = element->getAACube().contains(_newEntityBox);
126159
127− /*
128− bool elementContainsNewCube = element->getAACube().contains(_newEntityCube);
129− qDebug() << "UpdateEntityOperator::subTreeContainsNewEntity()....";
130− qDebug() << " element->getAACube()=" << element->getAACube();
131− qDebug() << " _newEntityCube=" << _newEntityCube;
132− qDebug() << " _newEntityBox=" << _newEntityBox;
133− qDebug() << " elementContainsNewCube=" << elementContainsNewCube;
134− qDebug() << " elementContainsNewBox=" << elementContainsNewBox;
135− */
160+ if (_wantDebug) {
161+ bool elementContainsNewCube = element->getAACube().contains(_newEntityCube);
162+ qDebug() << "UpdateEntityOperator::subTreeContainsNewEntity()....";
163+ qDebug() << " element->getAACube()=" << element->getAACube();
164+ qDebug() << " _newEntityCube=" << _newEntityCube;
165+ qDebug() << " _newEntityBox=" << _newEntityBox;
166+ qDebug() << " elementContainsNewCube=" << elementContainsNewCube;
167+ qDebug() << " elementContainsNewBox=" << elementContainsNewBox;
168+ }
136169
137170 return elementContainsNewBox;
138171 }
@@ -155,18 +188,42 @@ bool UpdateEntityOperator::preRecursion(OctreeElement* element) { · 16 unmodified lines
155188 bool subtreeContainsOld = subTreeContainsOldEntity(element);
156189 bool subtreeContainsNew = subTreeContainsNewEntity(element);
157190
191+ if (_wantDebug) {
192+ qDebug() << "---- UpdateEntityOperator::preRecursion().... ----";
193+ qDebug() << " element=" << element->getAACube();
194+ qDebug() << " subtreeContainsOld=" << subtreeContainsOld;
195+ qDebug() << " subtreeContainsNew=" << subtreeContainsNew;
196+ qDebug() << " _foundOld=" << _foundOld;
197+ qDebug() << " _foundNew=" << _foundNew;
198+ }
199+
158200 // If we haven't yet found the old entity, and this subTreeContains our old
159201 // entity, then we need to keep searching.
160202 if (!_foundOld && subtreeContainsOld) {
161−
203+
204+ if (_wantDebug) {
205+ qDebug() << " OLD TREE CASE....";
206+ qDebug() << " entityTreeElement=" << entityTreeElement;
207+ qDebug() << " _containingElement=" << _containingElement;
208+ }
209+
162210 // If this is the element we're looking for, then ask it to remove the old entity
163211 // and we can stop searching.
164212 if (entityTreeElement == _containingElement) {
165213
214+ if (_wantDebug) {
215+ qDebug() << " *** it's the OLD ELEMENT! ***";
216+ }
217+
166218 // If the containgElement IS NOT the best fit for the new entity properties
167219 // then we need to remove it, and the updateEntity below will store it in the
168220 // correct element.
169221 if (_removeOld) {
222+
223+ if (_wantDebug) {
224+ qDebug() << " *** REMOVING from ELEMENT ***";
225+ }
226+
170227 entityTreeElement->removeEntityItem(_existingEntity); // NOTE: only removes the entity, doesn't delete it
171228
172229 // If we haven't yet found the new location, then we need to
@@ -174,6 +231,11 @@ bool UpdateEntityOperator::preRecursion(OctreeElement* element) { · 1 unmodified line
174231 // now we're not in that map
175232 if (!_foundNew) {
176233 _tree->setContainingElement(_entityItemID, NULL);
234+
235+ if (_wantDebug) {
236+ qDebug() << " *** REMOVING from MAP ***";
237+ }
238+
177239 }
178240 }
179241 _foundOld = true;
@@ -187,11 +249,27 @@ bool UpdateEntityOperator::preRecursion(OctreeElement* element) { · 7 unmodified lines
187249 // entity, then we need to keep searching.
188250 if (!_foundNew && subtreeContainsNew) {
189251
252+ if (_wantDebug) {
253+ qDebug() << " NEW TREE CASE....";
254+ qDebug() << " entityTreeElement=" << entityTreeElement;
255+ qDebug() << " _containingElement=" << _containingElement;
256+ qDebug() << " entityTreeElement->bestFitBounds(_newEntityBox)=" << entityTreeElement->bestFitBounds(_newEntityBox);
257+ }
258+
259+
190260 // If this element is the best fit for the new entity properties, then add/or update it
191261 if (entityTreeElement->bestFitBounds(_newEntityBox)) {
192262
263+ if (_wantDebug) {
264+ qDebug() << " *** THIS ELEMENT IS BEST FIT ***";
265+ }
266+
193267 // if we are the existing containing element, then we can just do the update of the entity properties
194268 if (entityTreeElement == _containingElement) {
269+
270+ if (_wantDebug) {
271+ qDebug() << " *** This is the same OLD ELEMENT ***";
272+ }
195273
196274 // TODO: We shouldn't be in a remove old case and also be the new best fit. This indicates that
197275 // we have some kind of a logic error in this operator. But, it can handle it properly by setting
@@ -201,21 +279,43 @@ bool UpdateEntityOperator::preRecursion(OctreeElement* element) { · 3 unmodified lines
201279 qDebug() << "UNEXPECTED - UpdateEntityOperator - "
202280 "we thought we needed to removeOld, but the old entity is our best fit.";
203281 _removeOld = false;
282+
283+ // if we thought we were supposed to remove the old item, and we already did, then we need
284+ // to repair this case.
285+ if (_foundOld) {
286+ if (_wantDebug) {
287+ qDebug() << " *** REPAIRING PREVIOUS REMOVAL from ELEMENT and MAP ***";
288+ }
289+ entityTreeElement->addEntityItem(_existingEntity);
290+ _tree->setContainingElement(_entityItemID, entityTreeElement);
291+ }
204292 }
205293
206294 // set the entity properties and mark our element as changed.
207295 _existingEntity->setProperties(_properties);
296+ if (_wantDebug) {
297+ qDebug() << " *** set properties ***";
298+ }
208299 } else {
209300 // otherwise, this is an add case.
210301 entityTreeElement->addEntityItem(_existingEntity);
211302 _existingEntity->setProperties(_properties); // still need to update the properties!
212303 _tree->setContainingElement(_entityItemID, entityTreeElement);
304+ if (_wantDebug) {
305+ qDebug() << " *** ADDING ENTITY to ELEMENT and MAP and SETTING PROPERTIES ***";
306+ }
213307 }
214308 _foundNew = true; // we found the new item!
215309 } else {
216310 keepSearching = true;
217311 }
218312 }
313+
314+ if (_wantDebug) {
315+ qDebug() << " FINAL --- keepSearching=" << keepSearching;
316+ qDebug() << "--------------------------------------------------";
317+ }
318+
219319
220320 return keepSearching; // if we haven't yet found it, keep looking
221321 }