cleanup in prep for PR

This commit is contained in:
ZappoMan 2014-08-25 10:56:43 -07:00
parent 73d5e8c519
commit 58759d344f
23 changed files with 165 additions and 643 deletions

View file

@ -48,8 +48,6 @@ void EntityServer::beforeRun() {
void EntityServer::entityCreated(const EntityItem& newEntity, const SharedNodePointer& senderNode) {
qDebug() << "EntityServer::entityCreated() newEntity.getEntityItemID()=" << newEntity.getEntityItemID();
unsigned char outputBuffer[MAX_PACKET_SIZE];
unsigned char* copyAt = outputBuffer;
@ -70,8 +68,6 @@ qDebug() << "EntityServer::entityCreated() newEntity.getEntityItemID()=" << newE
copyAt += sizeof(entityID);
packetLength += sizeof(entityID);
qDebug() << "EntityServer::entityCreated() writeDatagram()";
NodeList::getInstance()->writeDatagram((char*) outputBuffer, packetLength, senderNode);
}
@ -110,8 +106,6 @@ int EntityServer::sendSpecialPacket(const SharedNodePointer& node, OctreeQueryNo
hasMoreToSend = tree->encodeEntitiesDeletedSince(queryNode->getSequenceNumber(), deletedEntitiesSentAt,
outputBuffer, MAX_PACKET_SIZE, packetLength);
//qDebug() << "sending PacketType_MODEL_ERASE packetLength:" << packetLength;
NodeList::getInstance()->writeDatagram((char*) outputBuffer, packetLength, SharedNodePointer(node));
queryNode->packetSent(outputBuffer, packetLength);
packetsSent++;
@ -128,7 +122,6 @@ void EntityServer::pruneDeletedEntities() {
EntityTree* tree = static_cast<EntityTree*>(_tree);
if (tree->hasAnyDeletedEntities()) {
//qDebug() << "there are some deleted entities to consider...";
quint64 earliestLastDeletedEntitiesSent = usecTimestampNow() + 1; // in the future
foreach (const SharedNodePointer& otherNode, NodeList::getInstance()->getNodeHash()) {
if (otherNode->getLinkedData()) {
@ -139,7 +132,6 @@ void EntityServer::pruneDeletedEntities() {
}
}
}
//qDebug() << "earliestLastDeletedEntitiesSent=" << earliestLastDeletedEntitiesSent;
tree->forgetEntitiesDeletedBefore(earliestLastDeletedEntitiesSent);
}
}

View file

@ -209,7 +209,7 @@ var ExportMenu = function(opts) {
self.setScale(self._scale *= 2);
}
this.exportModels = function() {
this.exportEntites = function() {
var x = self._position.x;
var y = self._position.y;
var z = self._position.z;
@ -217,7 +217,7 @@ var ExportMenu = function(opts) {
var filename = "models__" + Window.location.hostname + "__" + x + "_" + y + "_" + z + "_" + s + "__.svo";
filename = Window.save("Select where to save", filename, "*.svo")
if (filename) {
var success = Clipboard.exportModels(filename, x, y, z, s);
var success = Clipboard.exportEntites(filename, x, y, z, s);
if (!success) {
Window.alert("Export failed: no models found in selected area.");
}
@ -243,7 +243,7 @@ var ExportMenu = function(opts) {
if (clickedOverlay == locationButton) {
self.showPositionPrompt();
} else if (clickedOverlay == exportButton) {
self.exportModels();
self.exportEntites();
} else if (clickedOverlay == cancelButton) {
self.close();
} else if (clickedOverlay == scaleOverlay) {
@ -423,23 +423,23 @@ var ModelImporter = function(opts) {
}
} else {
if (Window.confirm(("Would you like to import back to the source location?"))) {
var success = Clipboard.importModels(filename);
var success = Clipboard.importEntities(filename);
if (success) {
Clipboard.pasteModels(x, y, z, 1);
Clipboard.pasteEntities(x, y, z, 1);
} else {
Window.alert("There was an error importing the model file.");
Window.alert("There was an error importing the entity file.");
}
return;
}
}
}
var success = Clipboard.importModels(filename);
var success = Clipboard.importEntities(filename);
if (success) {
self._importing = true;
self.setImportVisible(true);
Overlays.editOverlay(importBoundaries, { size: s });
} else {
Window.alert("There was an error importing the model file.");
Window.alert("There was an error importing the entity file.");
}
}
}
@ -449,7 +449,7 @@ var ModelImporter = function(opts) {
if (self._importing) {
// self._importing = false;
// self.setImportVisible(false);
Clipboard.pasteModels(importPosition.x, importPosition.y, importPosition.z, 1);
Clipboard.pasteEntities(importPosition.x, importPosition.y, importPosition.z, 1);
}
}
@ -912,7 +912,6 @@ function controller(wichSide) {
modelURL: attachments[attachmentIndex].modelURL
};
print(">>>>> CALLING >>>>> newModel = Entities.addEntity(newProperties);");
newModel = Entities.addEntity(newProperties);
@ -973,7 +972,7 @@ print(">>>>> CALLING >>>>> newModel = Entities.addEntity(newProperties);");
var leftController = new controller(LEFT);
var rightController = new controller(RIGHT);
function moveModels() {
function moveEntities() {
if (leftController.grabbing && rightController.grabbing && rightController.entityID.id == leftController.entityID.id) {
var newPosition = leftController.oldModelPosition;
var rotation = leftController.oldModelRotation;
@ -1070,7 +1069,7 @@ function checkController(deltaTime) {
leftController.update();
rightController.update();
moveModels();
moveEntities();
} else {
if (hydraConnected) {
hydraConnected = false;
@ -1113,7 +1112,7 @@ function initToolBar() {
alpha: 0.7
});
newBox = toolBar.addTool({
imageURL: toolIconUrl + "add-model-tool.svg",
imageURL: toolIconUrl + "models-tool.svg",
subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT },
width: toolWidth, height: toolHeight,
visible: true,
@ -1121,7 +1120,7 @@ function initToolBar() {
});
newSphere = toolBar.addTool({
imageURL: toolIconUrl + "add-model-tool.svg",
imageURL: toolIconUrl + "models-tool.svg",
subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT },
width: toolWidth, height: toolHeight,
visible: true,
@ -1617,19 +1616,19 @@ function handeMenuEvent(menuItem){
print("menuItemEvent() in JS... menuItem=" + menuItem);
if (menuItem == "Delete") {
if (leftController.grabbing) {
print(" Delete Model.... leftController.entityID="+ leftController.entityID);
print(" Delete Entity.... leftController.entityID="+ leftController.entityID);
Entities.deleteEntity(leftController.entityID);
leftController.grabbing = false;
} else if (rightController.grabbing) {
print(" Delete Model.... rightController.entityID="+ rightController.entityID);
print(" Delete Entity.... rightController.entityID="+ rightController.entityID);
Entities.deleteEntity(rightController.entityID);
rightController.grabbing = false;
} else if (entitySelected) {
print(" Delete Model.... selectedEntityID="+ selectedEntityID);
print(" Delete Entity.... selectedEntityID="+ selectedEntityID);
Entities.deleteEntity(selectedEntityID);
entitySelected = false;
} else {
print(" Delete Model.... not holding...");
print(" Delete Entity.... not holding...");
}
} else if (menuItem == "Edit Properties...") {
var editModelID = -1;

View file

@ -1,347 +0,0 @@
//
// placeModelsWithHands.js
// examples
//
// Created by Brad Hefta-Gaub on 1/20/14.
// Copyright 2014 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
//
// maybe we should make these constants...
var LEFT_PALM = 0;
var LEFT_TIP = 1;
var LEFT_BUTTON_FWD = 5;
var LEFT_BUTTON_3 = 3;
var RIGHT_PALM = 2;
var RIGHT_TIP = 3;
var RIGHT_BUTTON_FWD = 11;
var RIGHT_BUTTON_3 = 9;
var leftModelAlreadyInHand = false;
var rightModelAlreadyInHand = false;
var leftRecentlyDeleted = false;
var rightRecentlyDeleted = false;
var leftHandModel;
var rightHandModel;
//var throwSound = new Sound("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/throw.raw");
//var catchSound = new Sound("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/catch.raw");
var targetRadius = 0.5;
var radiusDefault = 0.25;
var modelRadius = radiusDefault;
var radiusMinimum = 0.05;
var radiusMaximum = 0.5;
var modelURLs = [
"http://www.fungibleinsight.com/faces/beta.fst",
"https://s3-us-west-1.amazonaws.com/highfidelity-public/models/attachments/topHat.fst",
"http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/Feisar_Ship.FBX",
"http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/birarda/birarda_head.fbx",
"http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/pug.fbx",
"http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/newInvader16x16-large-purple.svo",
"http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/minotaur/mino_full.fbx",
"http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/Combat_tank_V01.FBX",
"http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/orc.fbx",
"http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/slimer.fbx",
];
var animationURLs = [
"http://www.fungibleinsight.com/faces/gangnam_style_2.fbx",
"",
"",
"",
"",
"",
"",
"",
"",
"",
];
var currentModelURL = 1;
var numModels = modelURLs.length;
function getNewVoxelPosition() {
var camera = Camera.getPosition();
var forwardVector = Quat.getFront(MyAvatar.orientation);
var newPosition = Vec3.sum(camera, Vec3.multiply(forwardVector, 2.0));
return newPosition;
}
function keyPressEvent(event) {
debugPrint("event.text=" + event.text);
if (event.text == "ESC") {
if (leftRecentlyDeleted) {
leftRecentlyDeleted = false;
leftModelAlreadyInHand = false;
}
if (rightRecentlyDeleted) {
rightRecentlyDeleted = false;
rightModelAlreadyInHand = false;
}
} else if (event.text == "m") {
var URL = Window.prompt("Model URL", "Enter URL, e.g. http://foo.com/model.fbx");
var modelPosition = getNewVoxelPosition();
var properties = { position: { x: modelPosition.x,
y: modelPosition.y,
z: modelPosition.z },
radius: modelRadius,
modelURL: URL
};
newModel = Models.addModel(properties);
} else if (event.text == "DELETE" || event.text == "BACKSPACE") {
if (leftModelAlreadyInHand) {
print("want to delete leftHandModel=" + leftHandModel);
Models.deleteModel(leftHandModel);
leftHandModel = "";
//leftModelAlreadyInHand = false;
leftRecentlyDeleted = true;
}
if (rightModelAlreadyInHand) {
print("want to delete rightHandModel=" + rightHandModel);
Models.deleteModel(rightHandModel);
rightHandModel = "";
//rightModelAlreadyInHand = false;
rightRecentlyDeleted = true;
}
} else {
var nVal = parseInt(event.text);
if ((nVal >= 0) && (nVal < numModels)) {
currentModelURL = nVal;
print("Model = " + currentModelURL);
}
}
}
var wantDebugging = false;
function debugPrint(message) {
if (wantDebugging) {
print(message);
}
}
function getModelHoldPosition(whichSide) {
var normal;
var tipPosition;
if (whichSide == LEFT_PALM) {
normal = Controller.getSpatialControlNormal(LEFT_PALM);
tipPosition = Controller.getSpatialControlPosition(LEFT_TIP);
} else {
normal = Controller.getSpatialControlNormal(RIGHT_PALM);
tipPosition = Controller.getSpatialControlPosition(RIGHT_TIP);
}
var MODEL_FORWARD_OFFSET = 0.08; // put the model a bit forward of fingers
position = { x: MODEL_FORWARD_OFFSET * normal.x,
y: MODEL_FORWARD_OFFSET * normal.y,
z: MODEL_FORWARD_OFFSET * normal.z };
position.x += tipPosition.x;
position.y += tipPosition.y;
position.z += tipPosition.z;
return position;
}
function checkControllerSide(whichSide) {
var BUTTON_FWD;
var BUTTON_3;
var palmPosition;
var palmRotation;
var modelAlreadyInHand;
var handMessage;
if (whichSide == LEFT_PALM) {
BUTTON_FWD = LEFT_BUTTON_FWD;
BUTTON_3 = LEFT_BUTTON_3;
palmPosition = Controller.getSpatialControlPosition(LEFT_PALM);
palmRotation = Controller.getSpatialControlRawRotation(LEFT_PALM);
modelAlreadyInHand = leftModelAlreadyInHand;
handMessage = "LEFT";
} else {
BUTTON_FWD = RIGHT_BUTTON_FWD;
BUTTON_3 = RIGHT_BUTTON_3;
palmPosition = Controller.getSpatialControlPosition(RIGHT_PALM);
palmRotation = Controller.getSpatialControlRawRotation(RIGHT_PALM);
modelAlreadyInHand = rightModelAlreadyInHand;
handMessage = "RIGHT";
}
//print("checkControllerSide..." + handMessage);
var grabButtonPressed = (Controller.isButtonPressed(BUTTON_FWD) || Controller.isButtonPressed(BUTTON_3));
// If I don't currently have a model in my hand, then try to grab closest one
if (!modelAlreadyInHand && grabButtonPressed) {
var closestModel = Models.findClosestModel(palmPosition, targetRadius);
if (closestModel.isKnownID) {
debugPrint(handMessage + " HAND- CAUGHT SOMETHING!!");
if (whichSide == LEFT_PALM) {
leftModelAlreadyInHand = true;
leftHandModel = closestModel;
} else {
rightModelAlreadyInHand = true;
rightHandModel = closestModel;
}
var modelPosition = getModelHoldPosition(whichSide);
var properties = { position: { x: modelPosition.x,
y: modelPosition.y,
z: modelPosition.z },
radius: modelRadius,
rotation: palmRotation,
};
debugPrint(">>>>>>>>>>>> EDIT MODEL.... modelRadius=" +modelRadius);
Models.editModel(closestModel, properties);
/*
var options = new AudioInjectionOptions();
options.position = modelPosition;
options.volume = 1.0;
Audio.playSound(catchSound, options);
*/
return; // exit early
}
}
// If '3' is pressed, and not holding a model, make a new one
if (Controller.isButtonPressed(BUTTON_3) && !modelAlreadyInHand) {
var modelPosition = getModelHoldPosition(whichSide);
var properties = { position: { x: modelPosition.x,
y: modelPosition.y,
z: modelPosition.z },
radius: modelRadius,
rotation: palmRotation,
modelURL: modelURLs[currentModelURL]
};
if (animationURLs[currentModelURL] !== "") {
properties.animationURL = animationURLs[currentModelURL];
properties.animationIsPlaying = true;
}
debugPrint("modelRadius=" +modelRadius);
//newModel = Models.addModel(properties);
print("just added model... newModel=" + newModel.creatorTokenID);
print("properties.animationURL=" + properties.animationURL);
if (whichSide == LEFT_PALM) {
leftModelAlreadyInHand = true;
leftHandModel = newModel;
} else {
rightModelAlreadyInHand = true;
rightHandModel = newModel;
}
// Play a new model sound
/*
var options = new AudioInjectionOptions();
options.position = modelPosition;
options.volume = 1.0;
Audio.playSound(catchSound, options);
*/
return; // exit early
}
if (modelAlreadyInHand) {
if (whichSide == LEFT_PALM) {
handModel = leftHandModel;
whichTip = LEFT_TIP;
} else {
handModel = rightHandModel;
whichTip = RIGHT_TIP;
}
// If holding the model keep it in the palm
if (grabButtonPressed) {
debugPrint(">>>>> " + handMessage + "-MODEL IN HAND, grabbing, hold and move");
var modelPosition = getModelHoldPosition(whichSide);
var properties = { position: { x: modelPosition.x,
y: modelPosition.y,
z: modelPosition.z },
radius: modelRadius,
rotation: palmRotation,
};
debugPrint(">>>>>>>>>>>> EDIT MODEL.... modelRadius=" +modelRadius);
Models.editModel(handModel, properties);
} else {
debugPrint(">>>>> " + handMessage + "-MODEL IN HAND, not grabbing, RELEASE!!!");
if (whichSide == LEFT_PALM) {
leftModelAlreadyInHand = false;
leftHandModel = false;
} else {
rightModelAlreadyInHand = false;
rightHandModel = false;
}
/*
var options = new AudioInjectionOptions();
options.position = modelPosition;
options.volume = 1.0;
Audio.playSound(throwSound, options);
*/
}
}
}
function checkController(deltaTime) {
var numberOfButtons = Controller.getNumberOfButtons();
var numberOfTriggers = Controller.getNumberOfTriggers();
var numberOfSpatialControls = Controller.getNumberOfSpatialControls();
var controllersPerTrigger = numberOfSpatialControls / numberOfTriggers;
// this is expected for hydras
if (!(numberOfButtons==12 && numberOfTriggers == 2 && controllersPerTrigger == 2)) {
debugPrint("no hydra connected?");
return; // bail if no hydra
}
checkControllerSide(LEFT_PALM);
checkControllerSide(RIGHT_PALM);
if (rightModelAlreadyInHand) {
var rightTriggerValue = Controller.getTriggerValue(1);
if (rightTriggerValue > 0.0) {
var possibleRadius = ((1.0 - rightTriggerValue) * (radiusMaximum - radiusMinimum)) + radiusMinimum;
modelRadius = possibleRadius;
} else {
modelRadius = radiusDefault;
}
}
if (leftModelAlreadyInHand) {
var leftTriggerValue = Controller.getTriggerValue(0);
if (leftTriggerValue > 0.0) {
var possibleRadius = ((1.0 - leftTriggerValue) * (radiusMaximum - radiusMinimum)) + radiusMinimum;
modelRadius = possibleRadius;
} else {
modelRadius = radiusDefault;
}
}
}
// register the call back so it fires before each data send
Script.update.connect(checkController);
Controller.keyPressEvent.connect(keyPressEvent);

View file

@ -1523,8 +1523,7 @@ struct SendVoxelsOperationArgs {
const unsigned char* newBaseOctCode;
};
// TODO: change names to entities...
bool Application::exportModels(const QString& filename, float x, float y, float z, float scale) {
bool Application::exportEntities(const QString& filename, float x, float y, float z, float scale) {
QVector<EntityItem*> entities;
_entities.getTree()->findEntities(AACube(glm::vec3(x / (float)TREE_SCALE,
y / (float)TREE_SCALE, z / (float)TREE_SCALE), scale / (float)TREE_SCALE), entities);
@ -1632,7 +1631,7 @@ void Application::importVoxels() {
emit importDone();
}
bool Application::importModels(const QString& filename) {
bool Application::importEntities(const QString& filename) {
_entityClipboard.eraseAllOctreeElements();
bool success = _entityClipboard.readFromSVOFile(filename.toLocal8Bit().constData());
if (success) {
@ -1641,7 +1640,7 @@ bool Application::importModels(const QString& filename) {
return success;
}
void Application::pasteModels(float x, float y, float z) {
void Application::pasteEntities(float x, float y, float z) {
_entityClipboard.sendEntities(&_entityEditSender, x, y, z);
}

View file

@ -321,9 +321,9 @@ public slots:
void nodeKilled(SharedNodePointer node);
void packetSent(quint64 length);
void pasteModels(float x, float y, float z);
bool exportModels(const QString& filename, float x, float y, float z, float scale);
bool importModels(const QString& filename);
void pasteEntities(float x, float y, float z);
bool exportEntities(const QString& filename, float x, float y, float z, float scale);
bool importEntities(const QString& filename);
void importVoxels(); // doesn't include source voxel because it goes to clipboard
void cutVoxels(const VoxelDetail& sourceVoxel);

View file

@ -61,7 +61,6 @@ void DatagramProcessor::processDatagrams() {
application->getParticles()->getTree()->handleAddParticleResponse(incomingPacket);
break;
case PacketTypeEntityAddResponse:
qDebug() << "DatagramProcessor::processDatagrams() PacketTypeEntityAddResponse...";
// this will keep creatorTokenIDs to IDs mapped correctly
EntityItemID::handleAddEntityResponse(incomingPacket);
application->getEntities()->getTree()->handleAddEntityResponse(incomingPacket);
@ -89,7 +88,7 @@ qDebug() << "DatagramProcessor::processDatagrams() PacketTypeEntityAddResponse..
OCTREE_PACKET_SENT_TIME arrivedAt = usecTimestampNow();
int flightTime = arrivedAt - sentAt;
qDebug("got PacketType_VOXEL_DATA, sequence:%d flightTime:%d", sequence, flightTime);
qDebug("got an Octree data or erase message, sequence:%d flightTime:%d", sequence, flightTime);
}
SharedNodePointer matchedNode = NodeList::getInstance()->sendingNodeForPacket(incomingPacket);

View file

@ -36,13 +36,9 @@ QThread* EntityTreeRenderer::getMainThread() {
EntityTreeRenderer::EntityTreeRenderer() :
OctreeRenderer() {
qDebug() << "--- Overriding Entity Factories NOW ---";
REGISTER_ENTITY_TYPE_WITH_FACTORY(Model, RenderableModelEntityItem::factory)
REGISTER_ENTITY_TYPE_WITH_FACTORY(Box, RenderableBoxEntityItem::factory)
REGISTER_ENTITY_TYPE_WITH_FACTORY(Sphere, RenderableSphereEntityItem::factory)
qDebug() << "--- DONE Overriding Entity Factories ---";
}
EntityTreeRenderer::~EntityTreeRenderer() {
@ -77,11 +73,7 @@ void EntityTreeRenderer::update() {
}
void EntityTreeRenderer::render(RenderMode renderMode) {
//qDebug() << "EntityTreeRenderer::render() ************";
OctreeRenderer::render(renderMode);
//qDebug() << "-------------------- EntityTreeRenderer::render() ------------";
//static_cast<EntityTree*>(_tree)->debugDumpMap();
//qDebug() << "******* DONE ******* EntityTreeRenderer::render() ************";
}
const FBXGeometry* EntityTreeRenderer::getGeometryForEntity(const EntityItem* entityItem) {
@ -123,8 +115,6 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
uint16_t numberOfEntities = entityItems.size();
//qDebug() << "EntityTreeRenderer::renderElement() element=" << element << "numberOfEntities=" << numberOfEntities;
bool isShadowMode = args->_renderMode == OctreeRenderer::SHADOW_RENDER_MODE;
bool displayElementProxy = Menu::getInstance()->isOptionChecked(MenuOption::DisplayModelElementProxy);
bool displayElementChildProxies = Menu::getInstance()->isOptionChecked(MenuOption::DisplayModelElementChildProxies);

View file

@ -66,9 +66,6 @@ public:
protected:
void clearModelsCache();
//QMap<QUuid, Model*> _knownEntityItemModels;
//QMap<uint32_t, Model*> _unknownEntityItemModels;
//QMap<const ModelEntityItem*, Model*> _entityItemModels;
};
#endif // hifi_EntityTreeRenderer_h

View file

@ -1,9 +1,9 @@
//
// EntityTreeRenderer.cpp
// RenderableBoxEntityItem.cpp
// interface/src
//
// Created by Brad Hefta-Gaub on 12/6/13.
// Copyright 2013 High Fidelity, Inc.
// Created by Brad Hefta-Gaub on 8/6/14.
// Copyright 2014 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
@ -25,45 +25,6 @@
#include "RenderableBoxEntityItem.h"
// vertex array for glDrawElements() and glDrawRangeElement() =================
// Notice that the sizes of these arrays become samller than the arrays for
// glDrawArrays() because glDrawElements() uses an additional index array to
// choose designated vertices with the indices. The size of vertex array is now
// 24 instead of 36, but the index array size is 36, same as the number of
// vertices required to draw a cube.
GLfloat vertices2[] = { 1, 1, 1, -1, 1, 1, -1,-1, 1, 1,-1, 1, // v0,v1,v2,v3 (front)
1, 1, 1, 1,-1, 1, 1,-1,-1, 1, 1,-1, // v0,v3,v4,v5 (right)
1, 1, 1, 1, 1,-1, -1, 1,-1, -1, 1, 1, // v0,v5,v6,v1 (top)
-1, 1, 1, -1, 1,-1, -1,-1,-1, -1,-1, 1, // v1,v6,v7,v2 (left)
-1,-1,-1, 1,-1,-1, 1,-1, 1, -1,-1, 1, // v7,v4,v3,v2 (bottom)
1,-1,-1, -1,-1,-1, -1, 1,-1, 1, 1,-1 }; // v4,v7,v6,v5 (back)
// normal array
GLfloat normals2[] = { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0,v1,v2,v3 (front)
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0,v3,v4,v5 (right)
0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // v0,v5,v6,v1 (top)
-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, // v1,v6,v7,v2 (left)
0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, // v7,v4,v3,v2 (bottom)
0, 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1 }; // v4,v7,v6,v5 (back)
// color array
GLfloat colors2[] = { 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, // v0,v1,v2,v3 (front)
1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, // v0,v3,v4,v5 (right)
1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, // v0,v5,v6,v1 (top)
1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, // v1,v6,v7,v2 (left)
0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, // v7,v4,v3,v2 (bottom)
0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1 }; // v4,v7,v6,v5 (back)
// index array of vertex array for glDrawElements() & glDrawRangeElement()
GLubyte indices[] = { 0, 1, 2, 2, 3, 0, // front
4, 5, 6, 6, 7, 4, // right
8, 9,10, 10,11, 8, // top
12,13,14, 14,15,12, // left
16,17,18, 18,19,16, // bottom
20,21,22, 22,23,20 }; // back
EntityItem* RenderableBoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
return new RenderableBoxEntityItem(entityID, properties);
}
@ -76,24 +37,47 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
glm::quat rotation = getRotation();
/*
const bool useGlutCube = false;
if (useGlutCube) {
glColor3ub(getColor()[RED_INDEX], getColor()[GREEN_INDEX], getColor()[BLUE_INDEX]);
glPushMatrix();
glTranslatef(position.x, position.y, position.z);
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glutSolidCube(size);
glPopMatrix();
*/
} else {
static GLfloat vertices[] = { 1, 1, 1, -1, 1, 1, -1,-1, 1, 1,-1, 1, // v0,v1,v2,v3 (front)
1, 1, 1, 1,-1, 1, 1,-1,-1, 1, 1,-1, // v0,v3,v4,v5 (right)
1, 1, 1, 1, 1,-1, -1, 1,-1, -1, 1, 1, // v0,v5,v6,v1 (top)
-1, 1, 1, -1, 1,-1, -1,-1,-1, -1,-1, 1, // v1,v6,v7,v2 (left)
-1,-1,-1, 1,-1,-1, 1,-1, 1, -1,-1, 1, // v7,v4,v3,v2 (bottom)
1,-1,-1, -1,-1,-1, -1, 1,-1, 1, 1,-1 }; // v4,v7,v6,v5 (back)
// normal array
static GLfloat normals[] = { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0,v1,v2,v3 (front)
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0,v3,v4,v5 (right)
0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // v0,v5,v6,v1 (top)
-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, // v1,v6,v7,v2 (left)
0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, // v7,v4,v3,v2 (bottom)
0, 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1 }; // v4,v7,v6,v5 (back)
// index array of vertex array for glDrawElements() & glDrawRangeElement()
static GLubyte indices[] = { 0, 1, 2, 2, 3, 0, // front
4, 5, 6, 6, 7, 4, // right
8, 9,10, 10,11, 8, // top
12,13,14, 14,15,12, // left
16,17,18, 18,19,16, // bottom
20,21,22, 22,23,20 }; // back
// enable and specify pointers to vertex arrays
glEnableClientState(GL_NORMAL_ARRAY);
//glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glNormalPointer(GL_FLOAT, 0, normals2);
//glColorPointer(3, GL_FLOAT, 0, colors2);
glVertexPointer(3, GL_FLOAT, 0, vertices2);
glNormalPointer(GL_FLOAT, 0, normals);
glVertexPointer(3, GL_FLOAT, 0, vertices);
//glEnable(GL_BLEND);
@ -112,7 +96,6 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
glPopMatrix();
glDisableClientState(GL_VERTEX_ARRAY); // disable vertex arrays
//glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}
};

View file

@ -2,8 +2,8 @@
// RenderableBoxEntityItem.h
// interface/src/entities
//
// Created by Brad Hefta-Gaub on 12/6/13.
// Copyright 2013 High Fidelity, Inc.
// Created by Brad Hefta-Gaub on 8/6/14.
// Copyright 2014 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

View file

@ -1,9 +1,9 @@
//
// EntityTreeRenderer.cpp
// RenderableModelEntityItem.cpp
// interface/src
//
// Created by Brad Hefta-Gaub on 12/6/13.
// Copyright 2013 High Fidelity, Inc.
// Created by Brad Hefta-Gaub on 8/6/14.
// Copyright 2014 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
@ -74,15 +74,12 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
if (_model) {
// handle animations..
if (hasAnimation()) {
//qDebug() << "hasAnimation()...";
if (!jointsMapped()) {
QStringList modelJointNames = _model->getJointNames();
mapJoints(modelJointNames);
//qDebug() << "mapJoints()...";
}
if (jointsMapped()) {
//qDebug() << "_model->setJointState()...";
QVector<glm::quat> frameData = getAnimationFrame();
for (int i = 0; i < frameData.size(); i++) {
_model->setJointState(i, true, frameData[i]);
@ -99,9 +96,6 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
// make sure to simulate so everything gets set up correctly for rendering
{
// TODO: _model->simulate() appears to be about 28% of model render time.
// do we really need to call this every frame? I think not. Look into how to
// reduce calls to this.
PerformanceTimer perfTimer("_model->simulate");
_model->simulate(0.0f);
}
@ -113,9 +107,8 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
? Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE;
if (_model->isActive()) {
// TODO: this appears to be about 62% of model render time. Is there a way to call this that doesn't
// cost us as much? For example if the same model is used but rendered multiple places is it less
// expensive?
// TODO: this is the majority of model render time. And rendering of a cube model vs the basic Box render
// is significantly more expensive. Is there a way to call this that doesn't cost us as much?
PerformanceTimer perfTimer("model->render");
_model->render(alpha, modelRenderMode);
} else {
@ -212,7 +205,7 @@ Model* RenderableModelEntityItem::getModel() {
// EntityTreeRenderer is a Q_OBJECT it can call invokeMethod()
qDebug() << "can't call getModel() on thread other than rendering thread...";
//qDebug() << "about to call QMetaObject::invokeMethod(this, 'getModel', Qt::BlockingQueuedConnection,...";
//QMetaObject::invokeMethod(this, "getModel", Qt::BlockingQueuedConnection, Q_RETURN_ARG(Model*, _model));
//qDebug() << "got it... _model=" << _model;
return _model;

View file

@ -2,8 +2,8 @@
// RenderableModelEntityItem.h
// interface/src/entities
//
// Created by Brad Hefta-Gaub on 12/6/13.
// Copyright 2013 High Fidelity, Inc.
// Created by Brad Hefta-Gaub on 8/6/14.
// Copyright 2014 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

View file

@ -2,8 +2,8 @@
// RenderableSphereEntityItem.cpp
// interface/src
//
// Created by Brad Hefta-Gaub on 12/6/13.
// Copyright 2013 High Fidelity, Inc.
// Created by Brad Hefta-Gaub on 8/6/14.
// Copyright 2014 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
@ -33,17 +33,10 @@ void RenderableSphereEntityItem::render(RenderArgs* args) {
assert(getType() == EntityTypes::Sphere);
glm::vec3 position = getPosition() * (float)TREE_SCALE;
float radius = getRadius() * (float)TREE_SCALE;
glm::quat rotation = getRotation();
glColor3ub(getColor()[RED_INDEX], getColor()[GREEN_INDEX], getColor()[BLUE_INDEX]);
glPushMatrix();
glTranslatef(position.x, position.y, position.z);
// TODO: we can probably get rid of this rotation until we support different radius dimensions
//glm::vec3 axis = glm::axis(rotation);
//glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glutSolidSphere(radius, 15, 15);
glPopMatrix();
};

View file

@ -2,8 +2,8 @@
// RenderableSphereEntityItem.h
// interface/src/entities
//
// Created by Brad Hefta-Gaub on 12/6/13.
// Copyright 2013 High Fidelity, Inc.
// Created by Brad Hefta-Gaub on 8/6/14.
// Copyright 2014 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

View file

@ -133,14 +133,14 @@ void ClipboardScriptingInterface::nudgeVoxel(float x, float y, float z, float s,
}
bool ClipboardScriptingInterface::exportModels(const QString& filename, float x, float y, float z, float s) {
return Application::getInstance()->exportModels(filename, x, y, z, s);
bool ClipboardScriptingInterface::exportEntities(const QString& filename, float x, float y, float z, float s) {
return Application::getInstance()->exportEntities(filename, x, y, z, s);
}
bool ClipboardScriptingInterface::importModels(const QString& filename) {
return Application::getInstance()->importModels(filename);
bool ClipboardScriptingInterface::importEntities(const QString& filename) {
return Application::getInstance()->importEntities(filename);
}
void ClipboardScriptingInterface::pasteModels(float x, float y, float z, float s) {
Application::getInstance()->pasteModels(x, y, z);
void ClipboardScriptingInterface::pasteEntities(float x, float y, float z, float s) {
Application::getInstance()->pasteEntities(x, y, z);
}

View file

@ -46,9 +46,9 @@ public slots:
void nudgeVoxel(const VoxelDetail& sourceVoxel, const glm::vec3& nudgeVec);
void nudgeVoxel(float x, float y, float z, float s, const glm::vec3& nudgeVec);
bool importModels(const QString& filename);
bool exportModels(const QString& filename, float x, float y, float z, float s);
void pasteModels(float x, float y, float z, float s);
bool importEntities(const QString& filename);
bool exportEntities(const QString& filename, float x, float y, float z, float s);
void pasteEntities(float x, float y, float z, float s);
};
#endif // hifi_ClipboardScriptingInterface_h

View file

@ -23,14 +23,11 @@ EntityItem* BoxEntityItem::factory(const EntityItemID& entityID, const EntityIte
return new BoxEntityItem(entityID, properties);
}
// our non-pure virtual subclass for now...
BoxEntityItem::BoxEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
EntityItem(entityItemID, properties)
{
_type = EntityTypes::Box;
setProperties(properties);
}
EntityItemProperties BoxEntityItem::getProperties() const {

View file

@ -19,13 +19,6 @@
#include <VoxelsScriptingInterface.h>
#include <VoxelDetail.h>
// This is not ideal, but adding script-engine as a linked library, will cause a circular reference
// I'm open to other potential solutions. Could we change cmake to allow libraries to reference each others
// headers, but not link to each other, this is essentially what this construct is doing, but would be
// better to add includes to the include path, but not link
//#include "../../script-engine/src/ScriptEngine.h"
#include "EntityScriptingInterface.h"
#include "EntityItem.h"
#include "EntityTree.h"
@ -370,18 +363,20 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
return appendState;
}
// TODO: correct this to reflect changes...
// TODO: My goal is to get rid of this concept completely. The old code (and some of the current code) used this
// result to calculate if a packet being sent to it was potentially bad or corrupt. I've adjusted this to now
// only consider the minimum header bytes as being required. But it would be preferable to completely eliminate
// this logic from the callers.
int EntityItem::expectedBytes() {
int expectedBytes = sizeof(uint32_t) // id
+ sizeof(float) // age
+ sizeof(quint64) // last updated
+ sizeof(quint64) // lasted edited
+ sizeof(float) // radius
+ sizeof(glm::vec3) // position
+ sizeof(rgbColor); // color
// potentially more...
return expectedBytes;
// Header bytes
// object ID [16 bytes]
// ByteCountCoded(type code) [~1 byte]
// last edited [8 bytes]
// ByteCountCoded(last_edited to last_updated delta) [~1-8 bytes]
// PropertyFlags<>( everything ) [1-2 bytes]
// ~27-35 bytes...
const int MINIMUM_HEADER_BYTES = 27;
return MINIMUM_HEADER_BYTES;
}
@ -404,7 +399,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
// ByteCountCoded(last_edited to last_updated delta) [~1-8 bytes]
// PropertyFlags<>( everything ) [1-2 bytes]
// ~27-35 bytes...
const int MINIMUM_HEADER_BYTES = 27; // TODO: this is not correct, we don't yet have 16 byte IDs
const int MINIMUM_HEADER_BYTES = 27;
int bytesRead = 0;
if (bytesLeftToRead >= MINIMUM_HEADER_BYTES) {

View file

@ -16,20 +16,15 @@
#include "EntityItemID.h"
//uint32_t EntityItemID::_nextID = 0; // TODO: should be changed to UUID
// for locally created models
QHash<uint32_t, QUuid> EntityItemID::_tokenIDsToIDs;
uint32_t EntityItemID::_nextCreatorTokenID = 0;
EntityItemID::EntityItemID() :
id(NEW_ENTITY),
creatorTokenID(UNKNOWN_ENTITY_TOKEN),
isKnownID(false)
{
//qDebug() << "EntityItemID::EntityItemID()... isKnownID="
// << isKnownID << "id=" << id << "creatorTokenID=" << creatorTokenID;
};
EntityItemID::EntityItemID(const EntityItemID& other) :
@ -37,8 +32,6 @@ EntityItemID::EntityItemID(const EntityItemID& other) :
creatorTokenID(other.creatorTokenID),
isKnownID(other.isKnownID)
{
//qDebug() << "EntityItemID::EntityItemID(const EntityItemID& other)... isKnownID="
// << isKnownID << "id=" << id << "creatorTokenID=" << creatorTokenID;
}
@ -47,8 +40,6 @@ EntityItemID::EntityItemID(const QUuid& id, uint32_t creatorTokenID, bool isKnow
creatorTokenID(creatorTokenID),
isKnownID(isKnownID)
{
//qDebug() << "EntityItemID::EntityItemID(uint32_t id, uint32_t creatorTokenID, bool isKnownID)... isKnownID="
// << isKnownID << "id=" << id << "creatorTokenID=" << creatorTokenID;
};
EntityItemID::EntityItemID(const QUuid& id) :
@ -56,8 +47,6 @@ EntityItemID::EntityItemID(const QUuid& id) :
creatorTokenID(UNKNOWN_ENTITY_TOKEN),
isKnownID(true)
{
//qDebug() << "EntityItemID::EntityItemID(uint32_t id)... isKnownID="
// << isKnownID << "id=" << id << "creatorTokenID=" << creatorTokenID;
};
EntityItemID EntityItemID::getIDfromCreatorTokenID(uint32_t creatorTokenID) {
@ -79,7 +68,6 @@ EntityItemID EntityItemID::assignActualIDForToken() const {
newlyAssignedEntityID.creatorTokenID = creatorTokenID;
newlyAssignedEntityID.isKnownID = true;
newlyAssignedEntityID.id = QUuid::createUuid();
//_nextID++;
return newlyAssignedEntityID;
}
@ -119,9 +107,6 @@ EntityItemID EntityItemID::readEntityItemIDFromBuffer(const unsigned char* data,
void EntityItemID::handleAddEntityResponse(const QByteArray& packet) {
qDebug() << "EntityItemID::handleAddEntityResponse()...";
const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(packet.data());
int numBytesPacketHeader = numBytesForPacketHeader(packet);
int bytesRead = numBytesPacketHeader;
@ -135,8 +120,6 @@ qDebug() << "EntityItemID::handleAddEntityResponse()...";
QUuid entityID = QUuid::fromRfc4122(packet.mid(bytesRead, NUM_BYTES_RFC4122_UUID));
dataAt += NUM_BYTES_RFC4122_UUID;
qDebug() << "EntityItemID::handleAddEntityResponse()... entityID=" << entityID << "creatorTokenID=" << creatorTokenID;
// add our token to id mapping
_tokenIDsToIDs[creatorTokenID] = entityID;
}
@ -154,8 +137,3 @@ void EntityItemIDfromScriptValue(const QScriptValue &object, EntityItemID& id) {
id.creatorTokenID = object.property("creatorTokenID").toVariant().toUInt();
id.isKnownID = object.property("isKnownID").toVariant().toBool();
}

View file

@ -408,17 +408,21 @@ void EntityItemPropertiesFromScriptValue(const QScriptValue &object, EntityItemP
properties.copyFromScriptValue(object);
}
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//Change this to use property flags...
//How do we also change this to support spanning multiple MTUs...
//Need to output the encode structure like handling packets over the wire...
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
// TODO: Implement support for edit packets that can span an MTU sized buffer. We need to implement a mechanism for the
// encodeEntityEditPacket() method to communicate the the caller which properties couldn't fit in the buffer. Similar
// to how we handle this in the Octree streaming case.
//
// TODO: Right now, all possible properties for all subclasses are handled here. Ideally we'd prefer
// to handle this in a more generic way. Allowing subclasses of EntityItem to register their properties
//
// TODO: There's a lot of repeated patterns in the code below to handle each property. It would be nice if the property
// registration mechanism allowed us to collapse these repeated sections of code into a single implementation that
// utilized the registration table to shorten up and simplify this code.
//
// TODO: Implement support for paged properties, spanning MTU, and custom properties
//
// TODO: Implement support for script and visible properties.
//
bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItemID id, const EntityItemProperties& properties,
unsigned char* bufferOut, int sizeIn, int& sizeOut) {
@ -482,9 +486,6 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
// requestedProperties = modelTreeElementExtraEncodeData->includedItems.value(getEntityItemID());
//}
//qDebug() << "requestedProperties=";
//requestedProperties.debugDumpBits();
LevelDetails entityLevel = packetData.startLevel();
// Last Edited quint64 always first, before any other details, which allows us easy access to adjusting this
@ -525,7 +526,6 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
// PROP_POSITION
if (requestedProperties.getHasProperty(PROP_POSITION)) {
//qDebug() << "PROP_POSITION requested...";
LevelDetails propertyLevel = packetData.startLevel();
successPropertyFits = packetData.appendPosition(properties.getPosition());
if (successPropertyFits) {
@ -534,18 +534,15 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
propertyCount++;
packetData.endLevel(propertyLevel);
} else {
//qDebug() << "PROP_POSITION didn't fit...";
packetData.discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else {
//qDebug() << "PROP_POSITION NOT requested...";
propertiesDidntFit -= PROP_POSITION;
}
// PROP_RADIUS
if (requestedProperties.getHasProperty(PROP_RADIUS)) {
//qDebug() << "PROP_RADIUS requested...";
LevelDetails propertyLevel = packetData.startLevel();
successPropertyFits = packetData.appendValue(properties.getRadius());
if (successPropertyFits) {
@ -554,18 +551,15 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
propertyCount++;
packetData.endLevel(propertyLevel);
} else {
//qDebug() << "PROP_RADIUS didn't fit...";
packetData.discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else {
//qDebug() << "PROP_RADIUS NOT requested...";
propertiesDidntFit -= PROP_RADIUS;
}
// PROP_ROTATION
if (requestedProperties.getHasProperty(PROP_ROTATION)) {
//qDebug() << "PROP_ROTATION requested...";
LevelDetails propertyLevel = packetData.startLevel();
successPropertyFits = packetData.appendValue(properties.getRotation());
if (successPropertyFits) {
@ -574,12 +568,10 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
propertyCount++;
packetData.endLevel(propertyLevel);
} else {
//qDebug() << "PROP_ROTATION didn't fit...";
packetData.discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else {
//qDebug() << "PROP_ROTATION NOT requested...";
propertiesDidntFit -= PROP_ROTATION;
}
@ -673,12 +665,8 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
// script would go here...
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TODO: move these??? how to handle this for subclass properties???
// PROP_COLOR
if (requestedProperties.getHasProperty(PROP_COLOR)) {
//qDebug() << "PROP_COLOR requested...";
LevelDetails propertyLevel = packetData.startLevel();
successPropertyFits = packetData.appendColor(properties.getColor());
if (successPropertyFits) {
@ -687,18 +675,15 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
propertyCount++;
packetData.endLevel(propertyLevel);
} else {
//qDebug() << "PROP_COLOR didn't fit...";
packetData.discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else {
//qDebug() << "PROP_COLOR NOT requested...";
propertiesDidntFit -= PROP_COLOR;
}
// PROP_MODEL_URL
if (requestedProperties.getHasProperty(PROP_MODEL_URL)) {
//qDebug() << "PROP_MODEL_URL requested...";
LevelDetails propertyLevel = packetData.startLevel();
successPropertyFits = packetData.appendValue(properties.getModelURL());
if (successPropertyFits) {
@ -707,18 +692,15 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
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...";
LevelDetails propertyLevel = packetData.startLevel();
successPropertyFits = packetData.appendValue(properties.getAnimationURL());
if (successPropertyFits) {
@ -727,18 +709,15 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
propertyCount++;
packetData.endLevel(propertyLevel);
} else {
//qDebug() << "PROP_ANIMATION_URL didn't fit...";
packetData.discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else {
//qDebug() << "PROP_ANIMATION_URL NOT requested...";
propertiesDidntFit -= PROP_ANIMATION_URL;
}
// PROP_ANIMATION_FPS
if (requestedProperties.getHasProperty(PROP_ANIMATION_FPS)) {
//qDebug() << "PROP_ANIMATION_FPS requested...";
LevelDetails propertyLevel = packetData.startLevel();
successPropertyFits = packetData.appendValue(properties.getAnimationFPS());
if (successPropertyFits) {
@ -747,18 +726,15 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
propertyCount++;
packetData.endLevel(propertyLevel);
} else {
//qDebug() << "PROP_ANIMATION_FPS didn't fit...";
packetData.discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else {
//qDebug() << "PROP_ANIMATION_FPS NOT requested...";
propertiesDidntFit -= PROP_ANIMATION_FPS;
}
// PROP_ANIMATION_FRAME_INDEX
if (requestedProperties.getHasProperty(PROP_ANIMATION_FRAME_INDEX)) {
//qDebug() << "PROP_ANIMATION_FRAME_INDEX requested...";
LevelDetails propertyLevel = packetData.startLevel();
successPropertyFits = packetData.appendValue(properties.getAnimationFrameIndex());
if (successPropertyFits) {
@ -767,18 +743,15 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
propertyCount++;
packetData.endLevel(propertyLevel);
} else {
//qDebug() << "PROP_ANIMATION_FRAME_INDEX didn't fit...";
packetData.discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else {
//qDebug() << "PROP_ANIMATION_FRAME_INDEX NOT requested...";
propertiesDidntFit -= PROP_ANIMATION_FRAME_INDEX;
}
// PROP_ANIMATION_PLAYING
if (requestedProperties.getHasProperty(PROP_ANIMATION_PLAYING)) {
//qDebug() << "PROP_ANIMATION_PLAYING requested...";
LevelDetails propertyLevel = packetData.startLevel();
successPropertyFits = packetData.appendValue(properties.getAnimationIsPlaying());
if (successPropertyFits) {
@ -787,17 +760,12 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
propertyCount++;
packetData.endLevel(propertyLevel);
} else {
//qDebug() << "PROP_ANIMATION_PLAYING didn't fit...";
packetData.discardLevel(propertyLevel);
appendState = OctreeElement::PARTIAL;
}
} else {
//qDebug() << "PROP_ANIMATION_PLAYING NOT requested...";
propertiesDidntFit -= PROP_ANIMATION_PLAYING;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
if (propertyCount > 0) {
int endOfEntityItemData = packetData.getUncompressedByteOffset();
@ -829,16 +797,9 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
appendState = OctreeElement::NONE; // if we got here, then we didn't include the item
}
//qDebug() << "propertyFlags=";
//propertyFlags.debugDumpBits();
//qDebug() << "propertiesDidntFit=";
//propertiesDidntFit.debugDumpBits();
// If any part of the model items didn't fit, then the element is considered partial
if (appendState != OctreeElement::COMPLETED) {
// TODO: handle mechanism for handling partial fitting data!
// add this item into our list for the next appendElementData() pass
//modelTreeElementExtraEncodeData->includedItems.insert(getEntityItemID(), propertiesDidntFit);
@ -872,6 +833,18 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
// how to handle lastEdited?
// how to handle lastUpdated?
// consider handling case where no properties are included... we should just ignore this packet...
//
// TODO: Right now, all possible properties for all subclasses are handled here. Ideally we'd prefer
// to handle this in a more generic way. Allowing subclasses of EntityItem to register their properties
//
// TODO: There's a lot of repeated patterns in the code below to handle each property. It would be nice if the property
// registration mechanism allowed us to collapse these repeated sections of code into a single implementation that
// utilized the registration table to shorten up and simplify this code.
//
// TODO: Implement support for paged properties, spanning MTU, and custom properties
//
// TODO: Implement support for script and visible properties.
//
bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int bytesToRead, int& processedBytes,
EntityItemID& entityID, EntityItemProperties& properties) {
bool valid = false;
@ -904,7 +877,6 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
memcpy(&lastEdited, dataAt, sizeof(lastEdited));
dataAt += sizeof(lastEdited);
processedBytes += sizeof(lastEdited);
//qDebug() << "EntityItemProperties::decodeEntityEditPacket() ... lastEdited=" << lastEdited;
properties.setLastEdited(lastEdited);
// encoded id
@ -957,7 +929,6 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
dataAt += encodedType.size();
processedBytes += encodedType.size();
// Update Delta - when was this item updated relative to last edit... this really should be 0
// TODO: Should we get rid of this in this in edit packets, since this has to always be 0?
// TODO: do properties need to handle lastupdated???
@ -1057,10 +1028,6 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
// script would go here...
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TODO: this needs to be reconciled...
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// PROP_COLOR
if (propertyFlags.getHasProperty(PROP_COLOR)) {
xColor color;

View file

@ -75,9 +75,10 @@ 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
friend class ModelEntityItem; // TODO: consider removing this friend relationship and have EntityItem use public methods
friend class BoxEntityItem; // TODO: consider removing this friend relationship and have EntityItem use public methods
friend class EntityItem; // TODO: consider removing this friend relationship and use public methods
friend class ModelEntityItem; // TODO: consider removing this friend relationship and use public methods
friend class BoxEntityItem; // TODO: consider removing this friend relationship and use public methods
friend class SphereEntityItem; // TODO: consider removing this friend relationship and use public methods
public:
EntityItemProperties();
virtual ~EntityItemProperties() { };
@ -100,19 +101,9 @@ public:
glm::vec3 getMaximumPointTreeUnits() const { return getMaximumPointMeters() / (float)TREE_SCALE; }
/// AACube in domain scale units (0.0 - 1.0)
AACube getAACubeTreeUnits() const {
glm::vec3 cornerInTreeUnits = getMinimumPointMeters()/(float)TREE_SCALE;
float dimensionInTreeUnits = getMaxDimension()/(float)TREE_SCALE;
/*
qDebug() << " getAACubeTreeUnits()";
qDebug() << " corner in meters=" << getMinimumPointMeters().x << "," << getMinimumPointMeters().y << "," << getMinimumPointMeters().z;
qDebug() << " dimension in meters=" << getMaxDimension();
qDebug() << " corner in tree units=" << cornerInTreeUnits.x << "," << cornerInTreeUnits.y << "," << cornerInTreeUnits.z;
qDebug() << " dimension in tree units=" << dimensionInTreeUnits;
*/
return AACube(cornerInTreeUnits, dimensionInTreeUnits);
return AACube(getMinimumPointMeters() / (float)TREE_SCALE, getMaxDimension() / (float)TREE_SCALE);
}
void debugDump() const;
// properties of all entities
@ -132,11 +123,15 @@ public:
float getMass() const { return _mass; }
void setMass(float value) { _mass = value; _massChanged = true; }
const glm::vec3& getVelocity() const { return _velocity; } /// velocity in domain scale units (0.0-1.0) per second
void setVelocity(const glm::vec3& value) { _velocity = value; _velocityChanged = true; } /// velocity in domain scale units (0.0-1.0) per second
/// velocity in domain scale units (0.0-1.0) per second
const glm::vec3& getVelocity() const { return _velocity; }
/// velocity in domain scale units (0.0-1.0) per second
void setVelocity(const glm::vec3& value) { _velocity = value; _velocityChanged = true; }
const glm::vec3& getGravity() const { return _gravity; } /// gravity in domain scale units (0.0-1.0) per second squared
void setGravity(const glm::vec3& value) { _gravity = value; _gravityChanged = true; } /// gravity in domain scale units (0.0-1.0) per second squared
/// gravity in domain scale units (0.0-1.0) per second squared
const glm::vec3& getGravity() const { return _gravity; }
/// gravity in domain scale units (0.0-1.0) per second squared
void setGravity(const glm::vec3& value) { _gravity = value; _gravityChanged = true; }
float getDamping() const { return _damping; }
void setDamping(float value) { _damping = value; _dampingChanged = true; }

View file

@ -90,8 +90,6 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(EntityItemID
return results;
}
EntityItemID EntityScriptingInterface::editEntity(EntityItemID entityID, const EntityItemProperties& properties) {
EntityItemID actualID = entityID;
@ -104,7 +102,6 @@ EntityItemID EntityScriptingInterface::editEntity(EntityItemID entityID, const E
if (actualID.id != UNKNOWN_ENTITY_ID) {
entityID.id = actualID.id;
entityID.isKnownID = true;
//qDebug() << "EntityScriptingInterface::editEntity()... isKnownID=" << entityID.isKnownID << "id=" << entityID.id << "creatorTokenID=" << entityID.creatorTokenID;
queueEntityMessage(PacketTypeEntityAddOrEdit, entityID, properties);
}
@ -112,19 +109,12 @@ EntityItemID EntityScriptingInterface::editEntity(EntityItemID entityID, const E
// the actual id, because we can edit out local models just with creatorTokenID
if (_entityTree) {
_entityTree->lockForWrite();
//qDebug() << "EntityScriptingInterface::editEntity() ******* START _entityTree->updateEntity()...";
_entityTree->updateEntity(entityID, properties);
//qDebug() << "EntityScriptingInterface::editEntity() ******* DONE _entityTree->updateEntity()...";
_entityTree->unlock();
}
return entityID;
}
// TODO: This deleteEntity() method uses the PacketTypeEntityAddOrEdit message to send
// a changed model with a shouldDie() property set to true. This works and is currently the only
// way to tell the model server to delete a model. But we should change this to use the PacketTypeEntityErase
// message which takes a list of model id's to delete.
void EntityScriptingInterface::deleteEntity(EntityItemID entityID) {
EntityItemID actualID = entityID;
@ -220,10 +210,6 @@ RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionWorke
result.intersects = _entityTree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face,
(void**)&intersectedEntity, lockType, &result.accurate);
if (result.intersects && intersectedEntity) {
//qDebug() << "findRayIntersectionWorker().... intersectedEntity=" << intersectedEntity;
//intersectedEntity->debugDump();
result.entityID = intersectedEntity->getEntityItemID();
result.properties = intersectedEntity->getProperties();
result.intersection = ray.origin + (ray.direction * result.distance);

View file

@ -34,6 +34,7 @@ Model properties:
// REQUIRED TO DO:
1) random crashes on moving (I think things going out of bounds???)
2) some jutter with moving entities
3) test animation again...
@ -41,8 +42,13 @@ Model properties:
4) clear all entities when changing domains?
5) what to do with entities
6) Test file save load for case where two siblings have more than MTU amount of data. I wonder if the fact that file save
doesn't include the extra exists bits will break something.
7) memory leaks???
8) EntityTreeRenderer::clearModelsCache()
4) memory leaks???
5) Import/Export Models - verify it works. /copy/paste??
22a) void ModelItemProperties::copyFromNewModelItem(const ModelItem& modelItem); // XXX ??? Do we need this????
22b) Local Entities Overlay - from Local Models Overlay