virtual entities checkpoint

This commit is contained in:
ZappoMan 2014-07-03 09:07:11 -07:00
parent 84101fce2c
commit 2c5209d1e7
17 changed files with 471 additions and 409 deletions

View file

@ -46,7 +46,7 @@ void EntityServer::beforeRun() {
pruneDeletedEntitysTimer->start(PRUNE_DELETED_MODELS_INTERVAL_MSECS);
}
void EntityServer::modelCreated(const EntityItem& newEntity, const SharedNodePointer& senderNode) {
void EntityServer::entityCreated(const EntityItem& newEntity, const SharedNodePointer& senderNode) {
unsigned char outputBuffer[MAX_PACKET_SIZE];
unsigned char* copyAt = outputBuffer;

View file

@ -40,7 +40,7 @@ public:
virtual bool hasSpecialPacketToSend(const SharedNodePointer& node);
virtual int sendSpecialPacket(const SharedNodePointer& node, OctreeQueryNode* queryNode, int& packetsSent);
virtual void modelCreated(const EntityItem& newEntity, const SharedNodePointer& senderNode);
virtual void entityCreated(const EntityItem& newEntity, const SharedNodePointer& senderNode);
public slots:
void pruneDeletedEntitys();

View file

@ -32,7 +32,7 @@ var originalProperties = {
blue: 0 },
modelURL: "http://www.fungibleinsight.com/faces/beta.fst",
modelRotation: rotation,
rotation: rotation,
animationURL: "http://www.fungibleinsight.com/faces/gangnam_style_2.fbx",
animationIsPlaying: true,
};

View file

@ -38,7 +38,7 @@ var originalProperties = {
//modelURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/minotaur/mino_full.fbx",
//modelURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/Combat_tank_V01.FBX",
modelRotation: rotation
rotation: rotation
};
var positionDelta = { x: 0, y: 0, z: 0 };

View file

@ -112,7 +112,7 @@ function controller(wichSide) {
this.positionAtGrab;
this.rotationAtGrab;
this.modelPositionAtGrab;
this.modelRotationAtGrab;
this.rotationAtGrab;
this.jointsIntersectingFromStart = [];
@ -168,13 +168,13 @@ function controller(wichSide) {
this.modelURL = properties.modelURL;
this.oldModelPosition = properties.position;
this.oldModelRotation = properties.modelRotation;
this.oldModelRotation = properties.rotation;
this.oldModelRadius = properties.radius;
this.positionAtGrab = this.palmPosition;
this.rotationAtGrab = this.rotation;
this.modelPositionAtGrab = properties.position;
this.modelRotationAtGrab = properties.modelRotation;
this.rotationAtGrab = properties.rotation;
this.jointsIntersectingFromStart = [];
for (var i = 0; i < jointList.length; i++) {
@ -394,13 +394,13 @@ function controller(wichSide) {
newRotation = Quat.multiply(this.rotation,
Quat.inverse(this.rotationAtGrab));
newRotation = Quat.multiply(newRotation,
this.modelRotationAtGrab);
this.rotationAtGrab);
break;
}
Entities.editEntity(this.entityID, {
position: newPosition,
modelRotation: newRotation
rotation: newRotation
});
this.oldModelRotation = newRotation;
@ -499,7 +499,7 @@ function controller(wichSide) {
newProperties = {
position: Vec3.sum(MyAvatar.getJointPosition(attachments[attachmentIndex].jointName),
Vec3.multiplyQbyV(MyAvatar.getJointCombinedRotation(attachments[attachmentIndex].jointName), attachments[attachmentIndex].translation)),
modelRotation: Quat.multiply(MyAvatar.getJointCombinedRotation(attachments[attachmentIndex].jointName),
rotation: Quat.multiply(MyAvatar.getJointCombinedRotation(attachments[attachmentIndex].jointName),
attachments[attachmentIndex].rotation),
radius: attachments[attachmentIndex].scale / 2.0,
modelURL: attachments[attachmentIndex].modelURL
@ -610,18 +610,18 @@ function moveModels() {
leftController.positionAtGrab = leftController.palmPosition;
leftController.rotationAtGrab = leftController.rotation;
leftController.modelPositionAtGrab = leftController.oldModelPosition;
leftController.modelRotationAtGrab = rotation;
leftController.rotationAtGrab = rotation;
rightController.positionAtGrab = rightController.palmPosition;
rightController.rotationAtGrab = rightController.rotation;
rightController.modelPositionAtGrab = rightController.oldModelPosition;
rightController.modelRotationAtGrab = rotation;
rightController.rotationAtGrab = rotation;
break;
}
Entities.editEntity(leftController.entityID, {
position: newPosition,
modelRotation: rotation,
rotation: rotation,
radius: leftController.oldModelRadius * ratio
});
@ -740,7 +740,7 @@ function Tooltip() {
Overlays.editOverlay(this.textOverlay, { visible: doShow });
}
this.updateText = function(properties) {
var angles = Quat.safeEulerAngles(properties.modelRotation);
var angles = Quat.safeEulerAngles(properties.rotation);
var text = "Model Properties:\n"
text += "x: " + properties.position.x.toFixed(this.decimals) + "\n"
text += "y: " + properties.position.y.toFixed(this.decimals) + "\n"
@ -865,10 +865,10 @@ function mousePressEvent(event) {
z: selectedEntityProperties.position.z,
};
selectedEntityProperties.oldRotation = {
x: selectedEntityProperties.modelRotation.x,
y: selectedEntityProperties.modelRotation.y,
z: selectedEntityProperties.modelRotation.z,
w: selectedEntityProperties.modelRotation.w,
x: selectedEntityProperties.rotation.x,
y: selectedEntityProperties.rotation.y,
z: selectedEntityProperties.rotation.z,
w: selectedEntityProperties.rotation.w,
};
selectedEntityProperties.glowLevel = 0.0;
@ -928,10 +928,10 @@ function mouseMoveEvent(event) {
z: selectedEntityProperties.position.z,
};
selectedEntityProperties.oldRotation = {
x: selectedEntityProperties.modelRotation.x,
y: selectedEntityProperties.modelRotation.y,
z: selectedEntityProperties.modelRotation.z,
w: selectedEntityProperties.modelRotation.w,
x: selectedEntityProperties.rotation.x,
y: selectedEntityProperties.rotation.y,
z: selectedEntityProperties.rotation.z,
w: selectedEntityProperties.rotation.w,
};
orientation = MyAvatar.orientation;
intersection = rayPlaneIntersection(pickRay,
@ -977,10 +977,10 @@ function mouseMoveEvent(event) {
case 3:
// Let's rotate
if (somethingChanged) {
selectedEntityProperties.oldRotation.x = selectedEntityProperties.modelRotation.x;
selectedEntityProperties.oldRotation.y = selectedEntityProperties.modelRotation.y;
selectedEntityProperties.oldRotation.z = selectedEntityProperties.modelRotation.z;
selectedEntityProperties.oldRotation.w = selectedEntityProperties.modelRotation.w;
selectedEntityProperties.oldRotation.x = selectedEntityProperties.rotation.x;
selectedEntityProperties.oldRotation.y = selectedEntityProperties.rotation.y;
selectedEntityProperties.oldRotation.z = selectedEntityProperties.rotation.z;
selectedEntityProperties.oldRotation.w = selectedEntityProperties.rotation.w;
mouseLastPosition.x = event.x;
mouseLastPosition.y = event.y;
somethingChanged = false;
@ -994,7 +994,7 @@ function mouseMoveEvent(event) {
var rotationAxis = (!zIsPressed && xIsPressed) ? { x: 1, y: 0, z: 0 } :
(!zIsPressed && !xIsPressed) ? { x: 0, y: 1, z: 0 } :
{ x: 0, y: 0, z: 1 };
rotationAxis = Vec3.multiplyQbyV(selectedEntityProperties.modelRotation, rotationAxis);
rotationAxis = Vec3.multiplyQbyV(selectedEntityProperties.rotation, rotationAxis);
var orthogonalAxis = Vec3.cross(cameraForward, rotationAxis);
var mouseDelta = { x: event.x - mouseLastPosition
.x, y: mouseLastPosition.y - event.y, z: 0 };
@ -1013,10 +1013,10 @@ function mouseMoveEvent(event) {
});
rotation = Quat.multiply(selectedEntityProperties.oldRotation, rotation);
selectedEntityProperties.modelRotation.x = rotation.x;
selectedEntityProperties.modelRotation.y = rotation.y;
selectedEntityProperties.modelRotation.z = rotation.z;
selectedEntityProperties.modelRotation.w = rotation.w;
selectedEntityProperties.rotation.x = rotation.x;
selectedEntityProperties.rotation.y = rotation.y;
selectedEntityProperties.rotation.z = rotation.z;
selectedEntityProperties.rotation.w = rotation.w;
break;
}
@ -1163,7 +1163,7 @@ Controller.keyPressEvent.connect(function(event) {
// resets model orientation when holding with mouse
if (event.text == "r" && entitySelected) {
selectedEntityProperties.modelRotation = Quat.fromVec3Degrees({ x: 0, y: 0, z: 0 });
selectedEntityProperties.rotation = Quat.fromVec3Degrees({ x: 0, y: 0, z: 0 });
Entities.editEntity(selectedEntityID, selectedEntityProperties);
tooltip.updateText(selectedEntityProperties);
somethingChanged = true;

View file

@ -200,7 +200,7 @@ function checkControllerSide(whichSide) {
y: modelPosition.y,
z: modelPosition.z },
radius: modelRadius,
modelRotation: palmRotation,
rotation: palmRotation,
};
debugPrint(">>>>>>>>>>>> EDIT MODEL.... modelRadius=" +modelRadius);
@ -225,7 +225,7 @@ function checkControllerSide(whichSide) {
y: modelPosition.y,
z: modelPosition.z },
radius: modelRadius,
modelRotation: palmRotation,
rotation: palmRotation,
modelURL: modelURLs[currentModelURL]
};
@ -277,7 +277,7 @@ function checkControllerSide(whichSide) {
y: modelPosition.y,
z: modelPosition.z },
radius: modelRadius,
modelRotation: palmRotation,
rotation: palmRotation,
};
debugPrint(">>>>>>>>>>>> EDIT MODEL.... modelRadius=" +modelRadius);

View file

@ -151,11 +151,11 @@ function standUp() {
var models = new Object();
function SeatIndicator(modelProperties, seatIndex) {
this.position = Vec3.sum(modelProperties.position,
Vec3.multiply(Vec3.multiplyQbyV(modelProperties.modelRotation,
Vec3.multiply(Vec3.multiplyQbyV(modelProperties.rotation,
modelProperties.sittingPoints[seatIndex].position),
modelProperties.radius));
this.orientation = Quat.multiply(modelProperties.modelRotation,
this.orientation = Quat.multiply(modelProperties.rotation,
modelProperties.sittingPoints[seatIndex].rotation);
this.scale = MyAvatar.scale / 12;
@ -230,9 +230,9 @@ Controller.mousePressEvent.connect(function(event) {
if (properties.sittingPoints.length > 0) {
print("Available seats, going to the first one: " + properties.sittingPoints[0].name);
seat.position = Vec3.sum(properties.position, Vec3.multiplyQbyV(properties.modelRotation, properties.sittingPoints[0].position));
seat.position = Vec3.sum(properties.position, Vec3.multiplyQbyV(properties.rotation, properties.sittingPoints[0].position));
Vec3.print("Seat position: ", seat.position);
seat.rotation = Quat.multiply(properties.modelRotation, properties.sittingPoints[0].rotation);
seat.rotation = Quat.multiply(properties.rotation, properties.sittingPoints[0].rotation);
Quat.print("Seat rotation: ", seat.rotation);
passedTime = 0.0;

View file

@ -79,6 +79,7 @@ const FBXGeometry* EntityTreeRenderer::getGeometryForEntity(const EntityItem& en
Model* EntityTreeRenderer::getModel(const EntityItem& entityItem) {
Model* model = NULL;
#ifdef HIDE_SUBCLASS_METHODS
if (entityItem.isKnownID()) {
if (_knownEntityItemModels.find(entityItem.getID()) != _knownEntityItemModels.end()) {
model = _knownEntityItemModels[entityItem.getID()];
@ -128,6 +129,7 @@ Model* EntityTreeRenderer::getModel(const EntityItem& entityItem) {
_unknownEntityItemModels[entityItem.getCreatorTokenID()] = model;
}
}
#endif
return model;
}
@ -137,7 +139,7 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
// we need to iterate the actual entityItems of the element
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
QList<EntityItem>& entityItems = entityTreeElement->getEntities();
QList<EntityItem*>& entityItems = entityTreeElement->getEntities();
uint16_t numberOfEntities = entityItems.size();
@ -222,11 +224,16 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
float radius = entityItem.getRadius() * (float)TREE_SCALE;
float size = entityItem.getSize() * (float)TREE_SCALE;
#ifdef HIDE_SUBCLASS_METHODS
bool drawAsModel = entityItem.hasModel();
#else
bool drawAsModel = false;
#endif
args->_itemsRendered++;
if (drawAsModel) {
#ifdef HIDE_SUBCLASS_METHODS
glPushMatrix();
{
const float alpha = 1.0f;
@ -341,6 +348,7 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
}
}
glPopMatrix();
#endif
} else {
//glColor3ub(entityItem.getColor()[RED_INDEX],entityItem.getColor()[GREEN_INDEX],entityItem.getColor()[BLUE_INDEX]);
glColor3f(1.0f, 0.0f, 0.0f);

View file

@ -98,12 +98,15 @@ void EntityItem::initFromEntityItemID(const EntityItemID& entityItemID) {
_position = glm::vec3(0,0,0);
_radius = 0;
_rotation = ENTITY_DEFAULT_ROTATION;
_shouldBeDeleted = false;
#ifdef HIDE_SUBCLASS_METHODS
rgbColor noColor = { 0, 0, 0 };
memcpy(_color, noColor, sizeof(_color));
_shouldBeDeleted = false;
_modelURL = ENTITY_DEFAULT_MODEL_URL;
_rotation = ENTITY_DEFAULT_ROTATION;
// animation related
_animationURL = ENTITY_DEFAULT_ANIMATION_URL;
_animationIsPlaying = false;
@ -113,6 +116,7 @@ void EntityItem::initFromEntityItemID(const EntityItemID& entityItemID) {
_jointMappingCompleted = false;
_lastAnimated = now;
#endif
}
EntityItem::EntityItem(const EntityItemID& entityItemID) {
@ -139,14 +143,15 @@ void EntityItem::init(glm::vec3 position, float radius, rgbColor color, uint32_t
quint64 now = usecTimestampNow();
_lastEdited = now;
_lastUpdated = now;
_position = position;
_radius = radius;
memcpy(_color, color, sizeof(_color));
_shouldBeDeleted = false;
_modelURL = ENTITY_DEFAULT_MODEL_URL;
_rotation = ENTITY_DEFAULT_ROTATION;
_shouldBeDeleted = false;
#ifdef HIDE_SUBCLASS_METHODS
memcpy(_color, color, sizeof(_color));
_modelURL = ENTITY_DEFAULT_MODEL_URL;
// animation related
_animationURL = ENTITY_DEFAULT_ANIMATION_URL;
_animationIsPlaying = false;
@ -155,6 +160,7 @@ void EntityItem::init(glm::vec3 position, float radius, rgbColor color, uint32_t
_glowLevel = 0.0f;
_jointMappingCompleted = false;
_lastAnimated = now;
#endif
}
OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packetData, EncodeBitstreamParams& params,
@ -274,26 +280,6 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
propertiesDidntFit -= PROP_RADIUS;
}
// PROP_MODEL_URL
if (requestedProperties.getHasProperty(PROP_MODEL_URL)) {
//qDebug() << "PROP_MODEL_URL requested...";
LevelDetails propertyLevel = packetData->startLevel();
successPropertyFits = packetData->appendValue(getModelURL());
if (successPropertyFits) {
propertyFlags |= PROP_MODEL_URL;
propertiesDidntFit -= PROP_MODEL_URL;
propertyCount++;
packetData->endLevel(propertyLevel);
} else {
//qDebug() << "PROP_MODEL_URL didn't fit...";
packetData->discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else {
//qDebug() << "PROP_MODEL_URL NOT requested...";
propertiesDidntFit -= PROP_MODEL_URL;
}
// PROP_ROTATION
if (requestedProperties.getHasProperty(PROP_ROTATION)) {
//qDebug() << "PROP_ROTATION requested...";
@ -314,6 +300,31 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
propertiesDidntFit -= PROP_ROTATION;
}
// PROP_SHOULD_BE_DELETED
if (requestedProperties.getHasProperty(PROP_SHOULD_BE_DELETED)) {
//qDebug() << "PROP_SHOULD_BE_DELETED requested...";
LevelDetails propertyLevel = packetData->startLevel();
successPropertyFits = packetData->appendValue(getShouldBeDeleted());
if (successPropertyFits) {
propertyFlags |= PROP_SHOULD_BE_DELETED;
propertiesDidntFit -= PROP_SHOULD_BE_DELETED;
propertyCount++;
packetData->endLevel(propertyLevel);
} else {
//qDebug() << "PROP_SHOULD_BE_DELETED didn't fit...";
packetData->discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else {
//qDebug() << "PROP_SHOULD_BE_DELETED NOT requested...";
propertiesDidntFit -= PROP_SHOULD_BE_DELETED;
}
// PROP_SCRIPT
// script would go here...
#ifdef HIDE_SUBCLASS_METHODS
// PROP_COLOR
if (requestedProperties.getHasProperty(PROP_COLOR)) {
//qDebug() << "PROP_COLOR requested...";
@ -334,9 +345,26 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
propertiesDidntFit -= PROP_COLOR;
}
// PROP_SCRIPT
// script would go here...
// PROP_MODEL_URL
if (requestedProperties.getHasProperty(PROP_MODEL_URL)) {
//qDebug() << "PROP_MODEL_URL requested...";
LevelDetails propertyLevel = packetData->startLevel();
successPropertyFits = packetData->appendValue(getModelURL());
if (successPropertyFits) {
propertyFlags |= PROP_MODEL_URL;
propertiesDidntFit -= PROP_MODEL_URL;
propertyCount++;
packetData->endLevel(propertyLevel);
} else {
//qDebug() << "PROP_MODEL_URL didn't fit...";
packetData->discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else {
//qDebug() << "PROP_MODEL_URL NOT requested...";
propertiesDidntFit -= PROP_MODEL_URL;
}
// PROP_ANIMATION_URL
if (requestedProperties.getHasProperty(PROP_ANIMATION_URL)) {
//qDebug() << "PROP_ANIMATION_URL requested...";
@ -417,25 +445,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
propertiesDidntFit -= PROP_ANIMATION_PLAYING;
}
// PROP_SHOULD_BE_DELETED
if (requestedProperties.getHasProperty(PROP_SHOULD_BE_DELETED)) {
//qDebug() << "PROP_SHOULD_BE_DELETED requested...";
LevelDetails propertyLevel = packetData->startLevel();
successPropertyFits = packetData->appendValue(getShouldBeDeleted());
if (successPropertyFits) {
propertyFlags |= PROP_SHOULD_BE_DELETED;
propertiesDidntFit -= PROP_SHOULD_BE_DELETED;
propertyCount++;
packetData->endLevel(propertyLevel);
} else {
//qDebug() << "PROP_SHOULD_BE_DELETED didn't fit...";
packetData->discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else {
//qDebug() << "PROP_SHOULD_BE_DELETED NOT requested...";
propertiesDidntFit -= PROP_SHOULD_BE_DELETED;
}
#endif //def HIDE_SUBCLASS_METHODS
}
if (propertyCount > 0) {
int endOfEntityItemData = packetData->getUncompressedByteOffset();
@ -530,9 +540,11 @@ int EntityItem::oldVersionReadEntityDataFromBuffer(const unsigned char* data, in
bytesRead += sizeof(_position);
// color
#ifdef HIDE_SUBCLASS_METHODS
memcpy(_color, dataAt, sizeof(_color));
dataAt += sizeof(_color);
bytesRead += sizeof(_color);
#endif
// shouldBeDeleted
memcpy(&_shouldBeDeleted, dataAt, sizeof(_shouldBeDeleted));
@ -545,11 +557,13 @@ int EntityItem::oldVersionReadEntityDataFromBuffer(const unsigned char* data, in
dataAt += sizeof(modelURLLength);
bytesRead += sizeof(modelURLLength);
QString modelURLString((const char*)dataAt);
#ifdef HIDE_SUBCLASS_METHODS
setModelURL(modelURLString);
#endif
dataAt += modelURLLength;
bytesRead += modelURLLength;
// modelRotation
// rotation
int bytes = unpackOrientationQuatFromBytes(dataAt, _rotation);
dataAt += bytes;
bytesRead += bytes;
@ -561,10 +575,13 @@ int EntityItem::oldVersionReadEntityDataFromBuffer(const unsigned char* data, in
dataAt += sizeof(animationURLLength);
bytesRead += sizeof(animationURLLength);
QString animationURLString((const char*)dataAt);
#ifdef HIDE_SUBCLASS_METHODS
setAnimationURL(animationURLString);
#endif
dataAt += animationURLLength;
bytesRead += animationURLLength;
#ifdef HIDE_SUBCLASS_METHODS
// animationIsPlaying
memcpy(&_animationIsPlaying, dataAt, sizeof(_animationIsPlaying));
dataAt += sizeof(_animationIsPlaying);
@ -579,6 +596,7 @@ int EntityItem::oldVersionReadEntityDataFromBuffer(const unsigned char* data, in
memcpy(&_animationFPS, dataAt, sizeof(_animationFPS));
dataAt += sizeof(_animationFPS);
bytesRead += sizeof(_animationFPS);
#endif
}
}
return bytesRead;
@ -679,6 +697,32 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
bytesRead += sizeof(_radius);
}
// PROP_ROTATION
if (propertyFlags.getHasProperty(PROP_ROTATION)) {
int bytes = unpackOrientationQuatFromBytes(dataAt, _rotation);
dataAt += bytes;
bytesRead += bytes;
}
// PROP_SHOULD_BE_DELETED
if (propertyFlags.getHasProperty(PROP_SHOULD_BE_DELETED)) {
memcpy(&_shouldBeDeleted, dataAt, sizeof(_shouldBeDeleted));
dataAt += sizeof(_shouldBeDeleted);
bytesRead += sizeof(_shouldBeDeleted);
}
// PROP_SCRIPT
// script would go here...
#ifdef HIDE_SUBCLASS_METHODS
// PROP_COLOR
if (propertyFlags.getHasProperty(PROP_COLOR)) {
memcpy(_color, dataAt, sizeof(_color));
dataAt += sizeof(_color);
bytesRead += sizeof(_color);
}
// PROP_MODEL_URL
if (propertyFlags.getHasProperty(PROP_MODEL_URL)) {
@ -693,23 +737,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
bytesRead += modelURLLength;
}
// PROP_ROTATION
if (propertyFlags.getHasProperty(PROP_ROTATION)) {
int bytes = unpackOrientationQuatFromBytes(dataAt, _rotation);
dataAt += bytes;
bytesRead += bytes;
}
// PROP_COLOR
if (propertyFlags.getHasProperty(PROP_COLOR)) {
memcpy(_color, dataAt, sizeof(_color));
dataAt += sizeof(_color);
bytesRead += sizeof(_color);
}
// PROP_SCRIPT
// script would go here...
// PROP_ANIMATION_URL
if (propertyFlags.getHasProperty(PROP_ANIMATION_URL)) {
// animationURL
@ -743,18 +770,14 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
dataAt += sizeof(_animationIsPlaying);
bytesRead += sizeof(_animationIsPlaying);
}
// PROP_SHOULD_BE_DELETED
if (propertyFlags.getHasProperty(PROP_SHOULD_BE_DELETED)) {
memcpy(&_shouldBeDeleted, dataAt, sizeof(_shouldBeDeleted));
dataAt += sizeof(_shouldBeDeleted);
bytesRead += sizeof(_shouldBeDeleted);
}
#endif
}
return bytesRead;
}
EntityItem EntityItem::fromEditPacket(const unsigned char* data, int length, int& processedBytes, EntityTree* tree, bool& valid) {
EntityItem* EntityItem::fromEditPacket(const unsigned char* data, int length, int& processedBytes, EntityTree* tree, bool& valid) {
EntityItem* result = NULL;
bool wantDebug = false;
if (wantDebug) {
qDebug() << "EntityItem EntityItem::fromEditPacket() length=" << length;
@ -839,17 +862,11 @@ EntityItem EntityItem::fromEditPacket(const unsigned char* data, int length, int
if (!packetContainsBits) {
//qDebug() << "edit packet didn't contain any information ignore it...";
valid = false;
return newEntityItem;
//return newEntityItem;
return NULL;
}
}
// radius
if (isNewEntityItem || ((packetContainsBits & ENTITY_PACKET_CONTAINS_RADIUS) == ENTITY_PACKET_CONTAINS_RADIUS)) {
memcpy(&newEntityItem._radius, dataAt, sizeof(newEntityItem._radius));
dataAt += sizeof(newEntityItem._radius);
processedBytes += sizeof(newEntityItem._radius);
}
// position
if (isNewEntityItem || ((packetContainsBits & ENTITY_PACKET_CONTAINS_POSITION) == ENTITY_PACKET_CONTAINS_POSITION)) {
memcpy(&newEntityItem._position, dataAt, sizeof(newEntityItem._position));
@ -857,11 +874,19 @@ EntityItem EntityItem::fromEditPacket(const unsigned char* data, int length, int
processedBytes += sizeof(newEntityItem._position);
}
// color
if (isNewEntityItem || ((packetContainsBits & ENTITY_PACKET_CONTAINS_COLOR) == ENTITY_PACKET_CONTAINS_COLOR)) {
memcpy(newEntityItem._color, dataAt, sizeof(newEntityItem._color));
dataAt += sizeof(newEntityItem._color);
processedBytes += sizeof(newEntityItem._color);
// radius
if (isNewEntityItem || ((packetContainsBits & ENTITY_PACKET_CONTAINS_RADIUS) == ENTITY_PACKET_CONTAINS_RADIUS)) {
memcpy(&newEntityItem._radius, dataAt, sizeof(newEntityItem._radius));
dataAt += sizeof(newEntityItem._radius);
processedBytes += sizeof(newEntityItem._radius);
}
// rotation
if (isNewEntityItem || ((packetContainsBits &
ENTITY_PACKET_CONTAINS_ROTATION) == ENTITY_PACKET_CONTAINS_ROTATION)) {
int bytes = unpackOrientationQuatFromBytes(dataAt, newEntityItem._rotation);
dataAt += bytes;
processedBytes += bytes;
}
// shouldBeDeleted
@ -871,6 +896,14 @@ EntityItem EntityItem::fromEditPacket(const unsigned char* data, int length, int
processedBytes += sizeof(newEntityItem._shouldBeDeleted);
}
#ifdef HIDE_SUBCLASS_METHODS
// color
if (isNewEntityItem || ((packetContainsBits & ENTITY_PACKET_CONTAINS_COLOR) == ENTITY_PACKET_CONTAINS_COLOR)) {
memcpy(newEntityItem._color, dataAt, sizeof(newEntityItem._color));
dataAt += sizeof(newEntityItem._color);
processedBytes += sizeof(newEntityItem._color);
}
// modelURL
if (isNewEntityItem || ((packetContainsBits & ENTITY_PACKET_CONTAINS_MODEL_URL) == ENTITY_PACKET_CONTAINS_MODEL_URL)) {
uint16_t modelURLLength;
@ -883,14 +916,6 @@ EntityItem EntityItem::fromEditPacket(const unsigned char* data, int length, int
processedBytes += modelURLLength;
}
// modelRotation
if (isNewEntityItem || ((packetContainsBits &
ENTITY_PACKET_CONTAINS_ROTATION) == ENTITY_PACKET_CONTAINS_ROTATION)) {
int bytes = unpackOrientationQuatFromBytes(dataAt, newEntityItem._rotation);
dataAt += bytes;
processedBytes += bytes;
}
// animationURL
if (isNewEntityItem || ((packetContainsBits & ENTITY_PACKET_CONTAINS_ANIMATION_URL) == ENTITY_PACKET_CONTAINS_ANIMATION_URL)) {
uint16_t animationURLLength;
@ -929,6 +954,7 @@ EntityItem EntityItem::fromEditPacket(const unsigned char* data, int length, int
dataAt += sizeof(newEntityItem._animationFPS);
processedBytes += sizeof(newEntityItem._animationFPS);
}
#endif
const bool wantDebugging = false;
if (wantDebugging) {
@ -937,7 +963,8 @@ EntityItem EntityItem::fromEditPacket(const unsigned char* data, int length, int
newEntityItem.debugDump();
}
return newEntityItem;
// TODO: need to make this actually return something...
return result;
}
void EntityItem::debugDump() const {
@ -946,8 +973,11 @@ void EntityItem::debugDump() const {
qDebug(" should die:%s", debug::valueOf(getShouldBeDeleted()));
qDebug(" position:%f,%f,%f", _position.x, _position.y, _position.z);
qDebug(" radius:%f", getRadius());
#ifdef HIDE_SUBCLASS_METHODS
qDebug(" color:%d,%d,%d", _color[0], _color[1], _color[2]);
qDebug() << " modelURL:" << qPrintable(getModelURL());
#endif
}
bool EntityItem::encodeEntityEditMessageDetails(PacketType command, EntityItemID id, const EntityItemProperties& properties,
@ -1011,14 +1041,6 @@ bool EntityItem::encodeEntityEditMessageDetails(PacketType command, EntityItemID
sizeOut += sizeof(packetContainsBits);
}
// radius
if (isNewEntityItem || ((packetContainsBits & ENTITY_PACKET_CONTAINS_RADIUS) == ENTITY_PACKET_CONTAINS_RADIUS)) {
float radius = properties.getRadius() / (float) TREE_SCALE;
memcpy(copyAt, &radius, sizeof(radius));
copyAt += sizeof(radius);
sizeOut += sizeof(radius);
}
// position
if (isNewEntityItem || ((packetContainsBits & ENTITY_PACKET_CONTAINS_POSITION) == ENTITY_PACKET_CONTAINS_POSITION)) {
glm::vec3 position = properties.getPosition() / (float)TREE_SCALE;
@ -1027,12 +1049,19 @@ bool EntityItem::encodeEntityEditMessageDetails(PacketType command, EntityItemID
sizeOut += sizeof(position);
}
// color
if (isNewEntityItem || ((packetContainsBits & ENTITY_PACKET_CONTAINS_COLOR) == ENTITY_PACKET_CONTAINS_COLOR)) {
rgbColor color = { properties.getColor().red, properties.getColor().green, properties.getColor().blue };
memcpy(copyAt, color, sizeof(color));
copyAt += sizeof(color);
sizeOut += sizeof(color);
// radius
if (isNewEntityItem || ((packetContainsBits & ENTITY_PACKET_CONTAINS_RADIUS) == ENTITY_PACKET_CONTAINS_RADIUS)) {
float radius = properties.getRadius() / (float) TREE_SCALE;
memcpy(copyAt, &radius, sizeof(radius));
copyAt += sizeof(radius);
sizeOut += sizeof(radius);
}
// rotation
if (isNewEntityItem || ((packetContainsBits & ENTITY_PACKET_CONTAINS_ROTATION) == ENTITY_PACKET_CONTAINS_ROTATION)) {
int bytes = packOrientationQuatToBytes(copyAt, properties.getRotation());
copyAt += bytes;
sizeOut += bytes;
}
// shoulDie
@ -1043,6 +1072,15 @@ bool EntityItem::encodeEntityEditMessageDetails(PacketType command, EntityItemID
sizeOut += sizeof(shouldBeDeleted);
}
#if 0 //def HIDE_SUBCLASS_METHODS
// color
if (isNewEntityItem || ((packetContainsBits & ENTITY_PACKET_CONTAINS_COLOR) == ENTITY_PACKET_CONTAINS_COLOR)) {
rgbColor color = { properties.getColor().red, properties.getColor().green, properties.getColor().blue };
memcpy(copyAt, color, sizeof(color));
copyAt += sizeof(color);
sizeOut += sizeof(color);
}
// modelURL
if (isNewEntityItem || ((packetContainsBits & ENTITY_PACKET_CONTAINS_MODEL_URL) == ENTITY_PACKET_CONTAINS_MODEL_URL)) {
uint16_t urlLength = properties.getModelURL().size() + 1;
@ -1054,13 +1092,6 @@ bool EntityItem::encodeEntityEditMessageDetails(PacketType command, EntityItemID
sizeOut += urlLength;
}
// modelRotation
if (isNewEntityItem || ((packetContainsBits & ENTITY_PACKET_CONTAINS_ROTATION) == ENTITY_PACKET_CONTAINS_ROTATION)) {
int bytes = packOrientationQuatToBytes(copyAt, properties.getRotation());
copyAt += bytes;
sizeOut += bytes;
}
// animationURL
if (isNewEntityItem || ((packetContainsBits & ENTITY_PACKET_CONTAINS_ANIMATION_URL) == ENTITY_PACKET_CONTAINS_ANIMATION_URL)) {
uint16_t urlLength = properties.getAnimationURL().size() + 1;
@ -1101,6 +1132,7 @@ bool EntityItem::encodeEntityEditMessageDetails(PacketType command, EntityItemID
copyAt += sizeof(animationFPS);
sizeOut += sizeof(animationFPS);
}
#endif
bool wantDebugging = false;
if (wantDebugging) {
@ -1148,6 +1180,7 @@ void EntityItem::adjustEditPacketForClockSkew(unsigned char* codeColorBuffer, ss
}
#ifdef HIDE_SUBCLASS_METHODS
QMap<QString, AnimationPointer> EntityItem::_loadedAnimations; // TODO: improve cleanup by leveraging the AnimationPointer(s)
AnimationCache EntityItem::_animationCache;
@ -1223,6 +1256,7 @@ QVector<glm::quat> EntityItem::getAnimationFrame() {
}
return frameData;
}
#endif
void EntityItem::update(const quint64& updateTime) {
_lastUpdated = updateTime;
@ -1231,6 +1265,7 @@ void EntityItem::update(const quint64& updateTime) {
quint64 now = usecTimestampNow();
// only advance the frame index if we're playing
#ifdef HIDE_SUBCLASS_METHODS
if (getAnimationIsPlaying()) {
float deltaTime = (float)(now - _lastAnimated) / (float)USECS_PER_SECOND;
@ -1252,6 +1287,7 @@ void EntityItem::update(const quint64& updateTime) {
} else {
_lastAnimated = now;
}
#endif
}
void EntityItem::copyChangedProperties(const EntityItem& other) {
@ -1260,12 +1296,117 @@ void EntityItem::copyChangedProperties(const EntityItem& other) {
EntityItemProperties EntityItem::getProperties() const {
EntityItemProperties properties;
properties.copyFromEntityItem(*this);
//properties.copyFromEntityItem(*this);
properties._id = getID();
properties._idSet = true;
properties._position = getPosition() * (float) TREE_SCALE;
properties._radius = getRadius() * (float) TREE_SCALE;
properties._rotation = getRotation();
properties._shouldBeDeleted = getShouldBeDeleted();
properties._positionChanged = false;
properties._radiusChanged = false;
properties._rotationChanged = false;
properties._shouldBeDeletedChanged = false;
#if 0 //def HIDE_SUBCLASS_METHODS
properties._color = getXColor();
properties._modelURL = getModelURL();
properties._animationURL = getAnimationURL();
properties._animationIsPlaying = getAnimationIsPlaying();
properties._animationFrameIndex = getAnimationFrameIndex();
properties._animationFPS = getAnimationFPS();
properties._glowLevel = getGlowLevel();
properties._sittingPoints = getSittingPoints(); // sitting support
properties._colorChanged = false;
properties._modelURLChanged = false;
properties._animationURLChanged = false;
properties._animationIsPlayingChanged = false;
properties._animationFrameIndexChanged = false;
properties._animationFPSChanged = false;
properties._glowLevelChanged = false;
#endif
properties._defaultSettings = false;
return properties;
}
void EntityItem::setProperties(const EntityItemProperties& properties, bool forceCopy) {
properties.copyToEntityItem(*this, forceCopy);
bool somethingChanged = false;
if (properties._positionChanged || forceCopy) {
setPosition(properties._position / (float) TREE_SCALE);
somethingChanged = true;
}
if (properties._radiusChanged || forceCopy) {
setRadius(properties._radius / (float) TREE_SCALE);
somethingChanged = true;
}
if (properties._rotationChanged || forceCopy) {
setRotation(properties._rotation);
somethingChanged = true;
}
if (properties._shouldBeDeletedChanged || forceCopy) {
setShouldBeDeleted(properties._shouldBeDeleted);
somethingChanged = true;
}
#if 0 // def HIDE_SUBCLASS_METHODS
if (properties._colorChanged || forceCopy) {
setColor(properties._color);
somethingChanged = true;
}
if (properties._modelURLChanged || forceCopy) {
setModelURL(properties._modelURL);
somethingChanged = true;
}
if (properties._animationURLChanged || forceCopy) {
setAnimationURL(properties._animationURL);
somethingChanged = true;
}
if (properties._animationIsPlayingChanged || forceCopy) {
setAnimationIsPlaying(properties._animationIsPlaying);
somethingChanged = true;
}
if (properties._animationFrameIndexChanged || forceCopy) {
setAnimationFrameIndex(properties._animationFrameIndex);
somethingChanged = true;
}
if (properties._animationFPSChanged || forceCopy) {
setAnimationFPS(properties._animationFPS);
somethingChanged = true;
}
if (properties._glowLevelChanged || forceCopy) {
setGlowLevel(properties._glowLevel);
somethingChanged = true;
}
#endif
if (somethingChanged) {
bool wantDebug = false;
if (wantDebug) {
uint64_t now = usecTimestampNow();
int elapsed = now - _lastEdited;
qDebug() << "EntityItem::setProperties() AFTER update... edited AGO=" << elapsed <<
"now=" << now << " _lastEdited=" << _lastEdited;
}
setLastEdited(properties._lastEdited);
}
}
EntityItemProperties::EntityItemProperties() :
@ -1276,28 +1417,33 @@ EntityItemProperties::EntityItemProperties() :
_position(0),
_radius(ENTITY_DEFAULT_RADIUS),
_rotation(ENTITY_DEFAULT_ROTATION),
_shouldBeDeleted(false),
_positionChanged(false),
_radiusChanged(false),
_rotationChanged(false),
_shouldBeDeletedChanged(false),
#if 0 //def HIDE_SUBCLASS_METHODS
_color(),
_modelURL(""),
_rotation(ENTITY_DEFAULT_ROTATION),
_animationURL(""),
_animationIsPlaying(false),
_animationFrameIndex(0.0),
_animationFPS(ENTITY_DEFAULT_ANIMATION_FPS),
_glowLevel(0.0f),
_positionChanged(false),
_radiusChanged(false),
_shouldBeDeletedChanged(false),
_colorChanged(false),
_modelURLChanged(false),
_rotationChanged(false),
_animationURLChanged(false),
_animationIsPlayingChanged(false),
_animationFrameIndexChanged(false),
_animationFPSChanged(false),
_glowLevelChanged(false),
#endif
_defaultSettings(true)
{
}
@ -1308,8 +1454,6 @@ void EntityItemProperties::debugDump() const {
qDebug() << " _idSet=" << _idSet;
qDebug() << " _position=" << _position.x << "," << _position.y << "," << _position.z;
qDebug() << " _radius=" << _radius;
qDebug() << " _modelURL=" << _modelURL;
qDebug() << " _animationURL=" << _animationURL;
}
@ -1323,20 +1467,21 @@ uint16_t EntityItemProperties::getChangedBits() const {
changedBits += ENTITY_PACKET_CONTAINS_POSITION;
}
if (_colorChanged) {
changedBits += ENTITY_PACKET_CONTAINS_COLOR;
if (_rotationChanged) {
changedBits += ENTITY_PACKET_CONTAINS_ROTATION;
}
if (_shouldBeDeletedChanged) {
changedBits += ENTITY_PACKET_CONTAINS_SHOULDDIE;
}
if (_modelURLChanged) {
changedBits += ENTITY_PACKET_CONTAINS_MODEL_URL;
#if 0 //def HIDE_SUBCLASS_METHODS
if (_colorChanged) {
changedBits += ENTITY_PACKET_CONTAINS_COLOR;
}
if (_rotationChanged) {
changedBits += ENTITY_PACKET_CONTAINS_ROTATION;
if (_modelURLChanged) {
changedBits += ENTITY_PACKET_CONTAINS_MODEL_URL;
}
if (_animationURLChanged) {
@ -1354,6 +1499,7 @@ uint16_t EntityItemProperties::getChangedBits() const {
if (_animationFPSChanged) {
changedBits += ENTITY_PACKET_CONTAINS_ANIMATION_FPS;
}
#endif
return changedBits;
}
@ -1362,32 +1508,28 @@ uint16_t EntityItemProperties::getChangedBits() const {
QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine) const {
QScriptValue properties = engine->newObject();
if (_idSet) {
properties.setProperty("id", _id);
properties.setProperty("isKnownID", (_id != UNKNOWN_ENTITY_ID));
}
QScriptValue position = vec3toScriptValue(engine, _position);
properties.setProperty("position", position);
QScriptValue color = xColorToScriptValue(engine, _color);
properties.setProperty("color", color);
properties.setProperty("radius", _radius);
QScriptValue rotation = quatToScriptValue(engine, _rotation);
properties.setProperty("rotation", rotation);
properties.setProperty("shouldBeDeleted", _shouldBeDeleted);
#if 0 // def HIDE_SUBCLASS_METHODS
QScriptValue color = xColorToScriptValue(engine, _color);
properties.setProperty("color", color);
properties.setProperty("modelURL", _modelURL);
QScriptValue modelRotation = quatToScriptValue(engine, _rotation);
properties.setProperty("modelRotation", modelRotation);
properties.setProperty("animationURL", _animationURL);
properties.setProperty("animationIsPlaying", _animationIsPlaying);
properties.setProperty("animationFrameIndex", _animationFrameIndex);
properties.setProperty("animationFPS", _animationFPS);
properties.setProperty("glowLevel", _glowLevel);
if (_idSet) {
properties.setProperty("id", _id);
properties.setProperty("isKnownID", (_id != UNKNOWN_ENTITY_ID));
}
// Sitting properties support
QScriptValue sittingPoints = engine->newObject();
for (int i = 0; i < _sittingPoints.size(); ++i) {
@ -1399,11 +1541,12 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine) cons
}
sittingPoints.setProperty("length", _sittingPoints.size());
properties.setProperty("sittingPoints", sittingPoints);
#endif // HIDE_SUBCLASS_METHODS
return properties;
}
void EntityItemProperties::copyFromScriptValue(const QScriptValue &object) {
void EntityItemProperties::copyFromScriptValue(const QScriptValue& object) {
QScriptValue position = object.property("position");
if (position.isValid()) {
@ -1422,6 +1565,46 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue &object) {
}
}
QScriptValue radius = object.property("radius");
if (radius.isValid()) {
float newRadius;
newRadius = radius.toVariant().toFloat();
if (_defaultSettings || newRadius != _radius) {
_radius = newRadius;
_radiusChanged = true;
}
}
QScriptValue rotation = object.property("rotation");
if (rotation.isValid()) {
QScriptValue x = rotation.property("x");
QScriptValue y = rotation.property("y");
QScriptValue z = rotation.property("z");
QScriptValue w = rotation.property("w");
if (x.isValid() && y.isValid() && z.isValid() && w.isValid()) {
glm::quat newRotation;
newRotation.x = x.toVariant().toFloat();
newRotation.y = y.toVariant().toFloat();
newRotation.z = z.toVariant().toFloat();
newRotation.w = w.toVariant().toFloat();
if (_defaultSettings || newRotation != _rotation) {
_rotation = newRotation;
_rotationChanged = true;
}
}
}
QScriptValue shouldBeDeleted = object.property("shouldBeDeleted");
if (shouldBeDeleted.isValid()) {
bool newShouldBeDeleted;
newShouldBeDeleted = shouldBeDeleted.toVariant().toBool();
if (_defaultSettings || newShouldBeDeleted != _shouldBeDeleted) {
_shouldBeDeleted = newShouldBeDeleted;
_shouldBeDeletedChanged = true;
}
}
#if 0 //def HIDE_SUBCLASS_METHODS
QScriptValue color = object.property("color");
if (color.isValid()) {
QScriptValue red = color.property("red");
@ -1441,26 +1624,6 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue &object) {
}
}
QScriptValue radius = object.property("radius");
if (radius.isValid()) {
float newRadius;
newRadius = radius.toVariant().toFloat();
if (_defaultSettings || newRadius != _radius) {
_radius = newRadius;
_radiusChanged = true;
}
}
QScriptValue shouldBeDeleted = object.property("shouldBeDeleted");
if (shouldBeDeleted.isValid()) {
bool newShouldBeDeleted;
newShouldBeDeleted = shouldBeDeleted.toVariant().toBool();
if (_defaultSettings || newShouldBeDeleted != _shouldBeDeleted) {
_shouldBeDeleted = newShouldBeDeleted;
_shouldBeDeletedChanged = true;
}
}
QScriptValue modelURL = object.property("modelURL");
if (modelURL.isValid()) {
QString newModelURL;
@ -1471,25 +1634,6 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue &object) {
}
}
QScriptValue modelRotation = object.property("modelRotation");
if (modelRotation.isValid()) {
QScriptValue x = modelRotation.property("x");
QScriptValue y = modelRotation.property("y");
QScriptValue z = modelRotation.property("z");
QScriptValue w = modelRotation.property("w");
if (x.isValid() && y.isValid() && z.isValid() && w.isValid()) {
glm::quat newRotation;
newRotation.x = x.toVariant().toFloat();
newRotation.y = y.toVariant().toFloat();
newRotation.z = z.toVariant().toFloat();
newRotation.w = w.toVariant().toFloat();
if (_defaultSettings || newRotation != _rotation) {
_rotation = newRotation;
_rotationChanged = true;
}
}
}
QScriptValue animationURL = object.property("animationURL");
if (animationURL.isValid()) {
QString newAnimationURL;
@ -1539,111 +1683,11 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue &object) {
_glowLevelChanged = true;
}
}
#endif
_lastEdited = usecTimestampNow();
}
void EntityItemProperties::copyToEntityItem(EntityItem& entityItem, bool forceCopy) const {
bool somethingChanged = false;
if (_positionChanged || forceCopy) {
entityItem.setPosition(_position / (float) TREE_SCALE);
somethingChanged = true;
}
if (_colorChanged || forceCopy) {
entityItem.setColor(_color);
somethingChanged = true;
}
if (_radiusChanged || forceCopy) {
entityItem.setRadius(_radius / (float) TREE_SCALE);
somethingChanged = true;
}
if (_shouldBeDeletedChanged || forceCopy) {
entityItem.setShouldBeDeleted(_shouldBeDeleted);
somethingChanged = true;
}
if (_modelURLChanged || forceCopy) {
entityItem.setModelURL(_modelURL);
somethingChanged = true;
}
if (_rotationChanged || forceCopy) {
entityItem.setRotation(_rotation);
somethingChanged = true;
}
if (_animationURLChanged || forceCopy) {
entityItem.setAnimationURL(_animationURL);
somethingChanged = true;
}
if (_animationIsPlayingChanged || forceCopy) {
entityItem.setAnimationIsPlaying(_animationIsPlaying);
somethingChanged = true;
}
if (_animationFrameIndexChanged || forceCopy) {
entityItem.setAnimationFrameIndex(_animationFrameIndex);
somethingChanged = true;
}
if (_animationFPSChanged || forceCopy) {
entityItem.setAnimationFPS(_animationFPS);
somethingChanged = true;
}
if (_glowLevelChanged || forceCopy) {
entityItem.setGlowLevel(_glowLevel);
somethingChanged = true;
}
if (somethingChanged) {
bool wantDebug = false;
if (wantDebug) {
uint64_t now = usecTimestampNow();
int elapsed = now - _lastEdited;
qDebug() << "EntityItemProperties::copyToEntityItem() AFTER update... edited AGO=" << elapsed <<
"now=" << now << " _lastEdited=" << _lastEdited;
}
entityItem.setLastEdited(_lastEdited);
}
}
void EntityItemProperties::copyFromEntityItem(const EntityItem& entityItem) {
_position = entityItem.getPosition() * (float) TREE_SCALE;
_color = entityItem.getXColor();
_radius = entityItem.getRadius() * (float) TREE_SCALE;
_shouldBeDeleted = entityItem.getShouldBeDeleted();
_modelURL = entityItem.getModelURL();
_rotation = entityItem.getRotation();
_animationURL = entityItem.getAnimationURL();
_animationIsPlaying = entityItem.getAnimationIsPlaying();
_animationFrameIndex = entityItem.getAnimationFrameIndex();
_animationFPS = entityItem.getAnimationFPS();
_glowLevel = entityItem.getGlowLevel();
_sittingPoints = entityItem.getSittingPoints(); // sitting support
_id = entityItem.getID();
_idSet = true;
_positionChanged = false;
_colorChanged = false;
_radiusChanged = false;
_shouldBeDeletedChanged = false;
_modelURLChanged = false;
_rotationChanged = false;
_animationURLChanged = false;
_animationIsPlayingChanged = false;
_animationFrameIndexChanged = false;
_animationFPSChanged = false;
_glowLevelChanged = false;
_defaultSettings = false;
}
QScriptValue EntityItemPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties) {
return properties.copyToScriptValue(engine);
}

View file

@ -12,6 +12,8 @@
#ifndef hifi_EntityItem_h
#define hifi_EntityItem_h
#define HIDE_SUBCLASS_METHODS 1
#include <stdint.h>
#include <glm/glm.hpp>
@ -83,10 +85,10 @@ enum EntityPropertyList {
PROP_VISIBLE,
PROP_POSITION,
PROP_RADIUS,
PROP_MODEL_URL,
PROP_ROTATION,
PROP_COLOR,
PROP_SCRIPT,
PROP_MODEL_URL,
PROP_COLOR,
PROP_ANIMATION_URL,
PROP_ANIMATION_FPS,
PROP_ANIMATION_FRAME_INDEX,
@ -103,14 +105,13 @@ typedef PropertyFlags<EntityPropertyList> EntityPropertyFlags;
/// set of entity item properties via JavaScript hashes/QScriptValues
/// all units for position, radius, etc are in meter units
class EntityItemProperties {
friend class EntityItem; // TODO: consider removing this friend relationship and have EntityItem use public methods
public:
EntityItemProperties();
virtual ~EntityItemProperties() { };
QScriptValue copyToScriptValue(QScriptEngine* engine) const;
void copyFromScriptValue(const QScriptValue& object);
void copyToEntityItem(EntityItem& entityItem, bool forceCopy = false) const;
void copyFromEntityItem(const EntityItem& entityItem);
virtual QScriptValue copyToScriptValue(QScriptEngine* engine) const;
virtual void copyFromScriptValue(const QScriptValue& object);
// editing related features supported by all entities
quint64 getLastEdited() const { return _lastEdited; }
@ -134,6 +135,7 @@ public:
void setRadius(float value) { _radius = value; _radiusChanged = true; }
void setShouldBeDeleted(bool shouldBeDeleted) { _shouldBeDeleted = shouldBeDeleted; _shouldBeDeletedChanged = true; }
#if 0 // def HIDE_SUBCLASS_METHODS
// properties we want to move to just models and particles
xColor getColor() const { return _color; }
const QString& getModelURL() const { return _modelURL; }
@ -152,6 +154,7 @@ public:
void setAnimationIsPlaying(bool value) { _animationIsPlaying = value; _animationIsPlayingChanged = true; }
void setAnimationFPS(float value) { _animationFPS = value; _animationFPSChanged = true; }
void setGlowLevel(float value) { _glowLevel = value; _glowLevelChanged = true; }
#endif
private:
quint32 _id;
@ -160,11 +163,17 @@ private:
glm::vec3 _position;
float _radius;
bool _shouldBeDeleted; /// to delete it
glm::quat _rotation;
bool _shouldBeDeleted;
bool _positionChanged;
bool _radiusChanged;
bool _rotationChanged;
bool _shouldBeDeletedChanged;
#if 0 // def HIDE_SUBCLASS_METHODS
xColor _color;
QString _modelURL;
glm::quat _rotation;
QString _animationURL;
bool _animationIsPlaying;
float _animationFrameIndex;
@ -172,18 +181,15 @@ private:
float _glowLevel;
QVector<SittingPoint> _sittingPoints;
bool _positionChanged;
bool _radiusChanged;
bool _shouldBeDeletedChanged;
bool _colorChanged;
bool _modelURLChanged;
bool _rotationChanged;
bool _animationURLChanged;
bool _animationIsPlayingChanged;
bool _animationFrameIndexChanged;
bool _animationFPSChanged;
bool _glowLevelChanged;
#endif
bool _defaultSettings;
};
Q_DECLARE_METATYPE(EntityItemProperties);
@ -252,9 +258,11 @@ public:
EntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
/// creates an NEW model from an model add or edit message data buffer
static EntityItem fromEditPacket(const unsigned char* data, int length, int& processedBytes, EntityTree* tree, bool& valid);
static EntityItem* fromEditPacket(const unsigned char* data, int length, int& processedBytes, EntityTree* tree, bool& valid);
virtual ~EntityItem();
virtual void somePureVirtualFunction() = 0;
// ID and EntityItemID related methods
uint32_t getID() const { return _id; }
@ -324,6 +332,7 @@ public:
// TODO: Move these to subclasses, or other appropriate abstraction
// getters/setters applicable to models and particles
#ifdef HIDE_SUBCLASS_METHODS
const rgbColor& getColor() const { return _color; }
xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; }
bool hasModel() const { return !_modelURL.isEmpty(); }
@ -356,6 +365,7 @@ public:
bool getAnimationIsPlaying() const { return _animationIsPlaying; }
float getAnimationFrameIndex() const { return _animationFrameIndex; }
float getAnimationFPS() const { return _animationFPS; }
#endif
static void cleanupLoadedAnimations();
@ -363,46 +373,40 @@ protected:
void initFromEntityItemID(const EntityItemID& entityItemID);
virtual void init(glm::vec3 position, float radius, rgbColor color, uint32_t id = NEW_ENTITY);
glm::vec3 _position;
rgbColor _color;
float _radius;
quint32 _id;
static quint32 _nextID;
bool _shouldBeDeleted;
static uint32_t _nextCreatorTokenID; /// used by the static interfaces for creator token ids
static std::map<uint32_t,uint32_t> _tokenIDsToIDs;
quint32 _id;
quint32 _type;
// model related items
QString _modelURL;
glm::quat _rotation;
QVector<SittingPoint> _sittingPoints;
float _glowLevel;
uint32_t _creatorTokenID;
bool _newlyCreated;
quint64 _lastUpdated;
quint64 _lastEdited;
quint64 _lastAnimated;
glm::vec3 _position;
float _radius;
glm::quat _rotation;
bool _shouldBeDeleted;
#ifdef HIDE_SUBCLASS_METHODS
rgbColor _color;
QString _modelURL;
QVector<SittingPoint> _sittingPoints;
float _glowLevel;
quint64 _lastAnimated;
QString _animationURL;
float _animationFrameIndex; // we keep this as a float and round to int only when we need the exact index
bool _animationIsPlaying;
float _animationFPS;
bool _jointMappingCompleted;
QVector<int> _jointMapping;
// used by the static interfaces for creator token ids
static uint32_t _nextCreatorTokenID;
static std::map<uint32_t,uint32_t> _tokenIDsToIDs;
static Animation* getAnimation(const QString& url);
static QMap<QString, AnimationPointer> _loadedAnimations;
static AnimationCache _animationCache;
#endif
};

View file

@ -71,7 +71,7 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(EntityItemID
_entityTree->lockForRead();
const EntityItem* model = _entityTree->findEntityByID(identity.id, true);
if (model) {
results.copyFromEntityItem(*model);
results = model->getProperties();
} else {
results.setIsUnknownID();
}

View file

@ -76,7 +76,7 @@ StoreEntityOperator::StoreEntityOperator(EntityTree* tree, const EntityItem& sea
// If this containing element would be the best fit for our new model, then just do the new
// portion of the store pass, since the change path will be the same for both parts of the update
if (_containingElement->bestFitEntityBounds(_newEntity)) {
if (_containingElement->bestFitEntityBounds(&_newEntity)) {
_foundOld = true;
}
} else {
@ -132,7 +132,7 @@ bool StoreEntityOperator::PreRecursion(OctreeElement* element) {
// If the containgElement IS NOT the best fit for the new model properties
// then we need to remove it, and the updateEntity below will store it in the
// correct element.
if (!_containingElement->bestFitEntityBounds(_newEntity)) {
if (!_containingElement->bestFitEntityBounds(&_newEntity)) {
modelTreeElement->removeEntityWithEntityItemID(_newEntity.getEntityItemID());
// If we haven't yet found the new location, then we need to
@ -689,7 +689,7 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char
void EntityTree::notifyNewlyCreatedEntity(const EntityItem& newEntity, const SharedNodePointer& senderNode) {
_newlyCreatedHooksLock.lockForRead();
for (size_t i = 0; i < _newlyCreatedHooks.size(); i++) {
_newlyCreatedHooks[i]->modelCreated(newEntity, senderNode);
_newlyCreatedHooks[i]->entityCreated(newEntity, senderNode);
}
_newlyCreatedHooksLock.unlock();
}
@ -742,15 +742,15 @@ void EntityTree::update() {
int movingEntitys = args._movingEntities.size();
for (int i = 0; i < movingEntitys; i++) {
bool shouldDie = args._movingEntities[i].getShouldBeDeleted();
bool shouldDie = args._movingEntities[i]->getShouldBeDeleted();
// if the particle is still inside our total bounds, then re-add it
AACube treeBounds = getRoot()->getAACube();
if (!shouldDie && treeBounds.contains(args._movingEntities[i].getPosition())) {
storeEntity(args._movingEntities[i]);
if (!shouldDie && treeBounds.contains(args._movingEntities[i]->getPosition())) {
storeEntity(*args._movingEntities[i]);
} else {
uint32_t entityItemID = args._movingEntities[i].getID();
uint32_t entityItemID = args._movingEntities[i]->getID();
quint64 deletedAt = usecTimestampNow();
_recentlyDeletedEntitysLock.lockForWrite();
_recentlyDeletedEntityItemIDs.insert(deletedAt, entityItemID);

View file

@ -17,7 +17,7 @@
class NewlyCreatedEntityHook {
public:
virtual void modelCreated(const EntityItem& newEntity, const SharedNodePointer& senderNode) = 0;
virtual void entityCreated(const EntityItem& newEntity, const SharedNodePointer& senderNode) = 0;
};
class EntityItemFBXService {

View file

@ -40,7 +40,7 @@ OctreeElement* EntityTreeElement::createNewElement(unsigned char* octalCode) {
void EntityTreeElement::init(unsigned char* octalCode) {
OctreeElement::init(octalCode);
_entityItems = new QList<EntityItem>;
_entityItems = new QList<EntityItem*>;
_voxelMemoryUsage += sizeof(EntityTreeElement);
}
@ -80,15 +80,15 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
QVector<uint16_t> indexesOfEntitiesToInclude;
for (uint16_t i = 0; i < _entityItems->size(); i++) {
const EntityItem& entity = (*_entityItems)[i];
EntityItem* entity = (*_entityItems)[i];
bool includeThisEntity = true;
if (hadElementExtraData) {
includeThisEntity = entityTreeElementExtraEncodeData->includedItems.contains(entity.getEntityItemID());
includeThisEntity = entityTreeElementExtraEncodeData->includedItems.contains(entity->getEntityItemID());
}
if (includeThisEntity && params.viewFrustum) {
AACube entityCube = entity.getAACube();
AACube entityCube = entity->getAACube();
entityCube.scale(TREE_SCALE);
if (params.viewFrustum->cubeInFrustum(entityCube) == ViewFrustum::OUTSIDE) {
includeThisEntity = false; // out of view, don't include it
@ -106,11 +106,11 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
if (successAppendEntityCount) {
foreach (uint16_t i, indexesOfEntitiesToInclude) {
const EntityItem& entity = (*_entityItems)[i];
EntityItem* entity = (*_entityItems)[i];
LevelDetails entityLevel = packetData->startLevel();
OctreeElement::AppendState appendEntityState = entity.appendEntityData(packetData, params, entityTreeElementExtraEncodeData);
OctreeElement::AppendState appendEntityState = entity->appendEntityData(packetData, params, entityTreeElementExtraEncodeData);
// If none of this entity data was able to be appended, then discard it
// and don't include it in our entity count
@ -125,7 +125,7 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
// If the entity item got completely appended, then we can remove it from the extra encode data
if (appendEntityState == OctreeElement::COMPLETED) {
entityTreeElementExtraEncodeData->includedItems.remove(entity.getEntityItemID());
entityTreeElementExtraEncodeData->includedItems.remove(entity->getEntityItemID());
}
// If any part of the entity items didn't fit, then the element is considered partial
@ -174,15 +174,15 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
return appendElementState;
}
bool EntityTreeElement::containsEntityBounds(const EntityItem& entity) const {
glm::vec3 clampedMin = glm::clamp(entity.getMinimumPoint(), 0.0f, 1.0f);
glm::vec3 clampedMax = glm::clamp(entity.getMaximumPoint(), 0.0f, 1.0f);
bool EntityTreeElement::containsEntityBounds(const EntityItem* entity) const {
glm::vec3 clampedMin = glm::clamp(entity->getMinimumPoint(), 0.0f, 1.0f);
glm::vec3 clampedMax = glm::clamp(entity->getMaximumPoint(), 0.0f, 1.0f);
return _cube.contains(clampedMin) && _cube.contains(clampedMax);
}
bool EntityTreeElement::bestFitEntityBounds(const EntityItem& entity) const {
glm::vec3 clampedMin = glm::clamp(entity.getMinimumPoint(), 0.0f, 1.0f);
glm::vec3 clampedMax = glm::clamp(entity.getMaximumPoint(), 0.0f, 1.0f);
bool EntityTreeElement::bestFitEntityBounds(const EntityItem* entity) const {
glm::vec3 clampedMin = glm::clamp(entity->getMinimumPoint(), 0.0f, 1.0f);
glm::vec3 clampedMax = glm::clamp(entity->getMaximumPoint(), 0.0f, 1.0f);
if (_cube.contains(clampedMin) && _cube.contains(clampedMax)) {
int childForMinimumPoint = getMyChildContainingPoint(clampedMin);
int childForMaximumPoint = getMyChildContainingPoint(clampedMax);
@ -203,19 +203,19 @@ bool EntityTreeElement::bestFitEntityBounds(const EntityItem& entity) const {
void EntityTreeElement::update(EntityTreeUpdateArgs& args) {
args._totalElements++;
// update our contained entities
QList<EntityItem>::iterator entityItr = _entityItems->begin();
QList<EntityItem*>::iterator entityItr = _entityItems->begin();
while(entityItr != _entityItems->end()) {
EntityItem& entity = (*entityItr);
EntityItem* entity = (*entityItr);
args._totalItems++;
// TODO: this _lastChanged isn't actually changing because we're not marking this element as changed.
// how do we want to handle this??? We really only want to consider an element changed when it is
// edited... not just animated...
entity.update(_lastChanged);
entity->update(_lastChanged);
// If the entity wants to die, or if it's left our bounding box, then move it
// into the arguments moving entities. These will be added back or deleted completely
if (entity.getShouldBeDeleted() || !bestFitEntityBounds(entity)) {
if (entity->getShouldBeDeleted() || !bestFitEntityBounds(entity)) {
args._movingEntities.push_back(entity);
// erase this entity
@ -228,7 +228,7 @@ void EntityTreeElement::update(EntityTreeUpdateArgs& args) {
// TODO: is this a good place to change the containing element map???
qDebug() << "EntityTreeElement::update()... calling _myTree->setContainingElement(entity.getEntityItemID(), NULL); ********";
_myTree->setContainingElement(entity.getEntityItemID(), NULL);
_myTree->setContainingElement(entity->getEntityItemID(), NULL);
} else {
++entityItr;
@ -242,8 +242,8 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con
// only called if we do intersect our bounding cube, but find if we actually intersect with entities...
QList<EntityItem>::iterator entityItr = _entityItems->begin();
QList<EntityItem>::const_iterator entityEnd = _entityItems->end();
QList<EntityItem*>::iterator entityItr = _entityItems->begin();
QList<EntityItem*>::const_iterator entityEnd = _entityItems->end();
bool somethingIntersected = false;
while(entityItr != entityEnd) {
EntityItem& entity = (*entityItr);
@ -328,8 +328,8 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con
bool EntityTreeElement::findSpherePenetration(const glm::vec3& center, float radius,
glm::vec3& penetration, void** penetratedObject) const {
QList<EntityItem>::iterator entityItr = _entityItems->begin();
QList<EntityItem>::const_iterator entityEnd = _entityItems->end();
QList<EntityItem*>::iterator entityItr = _entityItems->begin();
QList<EntityItem*>::const_iterator entityEnd = _entityItems->end();
while(entityItr != entityEnd) {
EntityItem& entity = (*entityItr);
glm::vec3 entityCenter = entity.getPosition();
@ -484,11 +484,11 @@ void EntityTreeElement::getEntities(const glm::vec3& searchPosition, float searc
}
void EntityTreeElement::getEntities(const AACube& box, QVector<EntityItem*>& foundEntities) {
QList<EntityItem>::iterator entityItr = _entityItems->begin();
QList<EntityItem>::iterator entityEnd = _entityItems->end();
QList<EntityItem*>::iterator entityItr = _entityItems->begin();
QList<EntityItem*>::iterator entityEnd = _entityItems->end();
AACube entityCube;
while(entityItr != entityEnd) {
EntityItem* entity = &(*entityItr);
EntityItem* entity = (*entityItr);
float radius = entity->getRadius();
// NOTE: we actually do cube-cube collision queries here, which is sloppy but good enough for now
// TODO: decide whether to replace entityCube-cube query with sphere-cube (requires a square root

View file

@ -29,7 +29,7 @@ public:
_movingItems(0)
{ }
QList<EntityItem> _movingEntities;
QList<EntityItem*> _movingEntities;
int _totalElements;
int _totalItems;
int _movingItems;
@ -113,8 +113,8 @@ public:
virtual bool findSpherePenetration(const glm::vec3& center, float radius,
glm::vec3& penetration, void** penetratedObject) const;
const QList<EntityItem>& getEntities() const { return *_entityItems; }
QList<EntityItem>& getEntities() { return *_entityItems; }
const QList<EntityItem*>& getEntities() const { return *_entityItems; }
QList<EntityItem*>& getEntities() { return *_entityItems; }
bool hasEntities() const { return _entityItems ? _entityItems->size() > 0 : false; }
void update(EntityTreeUpdateArgs& args);
@ -142,13 +142,13 @@ public:
bool removeEntityWithID(uint32_t id);
bool removeEntityWithEntityItemID(const EntityItemID& id);
bool containsEntityBounds(const EntityItem& entity) const;
bool bestFitEntityBounds(const EntityItem& entity) const;
bool containsEntityBounds(const EntityItem* entity) const;
bool bestFitEntityBounds(const EntityItem* entity) const;
protected:
virtual void init(unsigned char * octalCode);
EntityTree* _myTree;
QList<EntityItem>* _entityItems;
QList<EntityItem*>* _entityItems;
};
#endif // hifi_EntityTreeElement_h

View file

@ -26,6 +26,7 @@
#include "ModelTests.h" // needs to be EntityTests.h soon
void EntityTests::modelTreeTests(bool verbose) {
#ifdef HIDE_SUBCLASS_METHODS
bool extraVerbose = false;
int testsTaken = 0;
int testsPassed = 0;
@ -60,7 +61,7 @@ void EntityTests::modelTreeTests(bool verbose) {
properties.setPosition(positionAtCenterInMeters);
properties.setRadius(halfMeter);
properties.setModelURL("https://s3-us-west-1.amazonaws.com/highfidelity-public/ozan/theater.fbx");
//properties.setModelURL("https://s3-us-west-1.amazonaws.com/highfidelity-public/ozan/theater.fbx");
tree.addEntity(modelID, properties);
@ -264,7 +265,7 @@ void EntityTests::modelTreeTests(bool verbose) {
properties.setPosition(randomPositionInMeters);
properties.setRadius(halfMeter);
properties.setModelURL("https://s3-us-west-1.amazonaws.com/highfidelity-public/ozan/theater.fbx");
//properties.setModelURL("https://s3-us-west-1.amazonaws.com/highfidelity-public/ozan/theater.fbx");
if (extraVerbose) {
qDebug() << "iteration:" << i
@ -508,6 +509,7 @@ void EntityTests::modelTreeTests(bool verbose) {
if (verbose) {
qDebug() << "******************************************************************************************";
}
#endif
}

View file

@ -1270,6 +1270,8 @@ void OctreeTests::byteCountCodingTests(bool verbose) {
}
void OctreeTests::modelItemTests(bool verbose) {
#ifdef HIDE_SUBCLASS_METHODS
//verbose = true;
EntityTreeElementExtraEncodeData modelTreeElementExtraEncodeData;
@ -1434,6 +1436,8 @@ void OctreeTests::modelItemTests(bool verbose) {
if (verbose) {
qDebug() << "******************************************************************************************";
}
#endif
}