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,43 +37,65 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
glm::quat rotation = getRotation();
/*
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);
const bool useGlutCube = false;
glPopMatrix();
*/
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 {
// 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);
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)
//glEnable(GL_BLEND);
// 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)
glColor3ub(getColor()[RED_INDEX], getColor()[GREEN_INDEX], getColor()[BLUE_INDEX]);
// 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
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glNormalPointer(GL_FLOAT, 0, normals);
glVertexPointer(3, GL_FLOAT, 0, vertices);
//glEnable(GL_BLEND);
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);
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);
// we need to do half the size because the geometry in the VBOs are from -1,-1,-1 to 1,1,1
float halfSize = size/2.0f;
// we need to do half the size because the geometry in the VBOs are from -1,-1,-1 to 1,1,1
float halfSize = size/2.0f;
glScalef(halfSize, halfSize, halfSize);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, indices);
glPopMatrix();
glScalef(halfSize, halfSize, halfSize);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, indices);
glPopMatrix();
glDisableClientState(GL_VERTEX_ARRAY); // disable vertex arrays
//glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY); // disable vertex arrays
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,15 +34,21 @@ 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...
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.
4) memory leaks???
7) memory leaks???
8) EntityTreeRenderer::clearModelsCache()
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