From 709ad849338bb764a8909b91b20c403c629d68ca Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 5 Nov 2014 23:44:59 +0100 Subject: [PATCH 01/94] added clone functionality to Overlays: Overlays.cloneOverlay(OverlayID) --- interface/src/ui/overlays/Base3DOverlay.cpp | 11 +++++++++-- interface/src/ui/overlays/Base3DOverlay.h | 1 + interface/src/ui/overlays/BillboardOverlay.cpp | 14 ++++++++++++++ interface/src/ui/overlays/BillboardOverlay.h | 4 ++++ interface/src/ui/overlays/Circle3DOverlay.cpp | 13 ++++++++----- interface/src/ui/overlays/Circle3DOverlay.h | 4 ++++ interface/src/ui/overlays/Cube3DOverlay.cpp | 6 ++++++ interface/src/ui/overlays/Cube3DOverlay.h | 2 ++ interface/src/ui/overlays/ImageOverlay.cpp | 11 +++++++++++ interface/src/ui/overlays/ImageOverlay.h | 3 +++ interface/src/ui/overlays/Line3DOverlay.cpp | 11 +++++++++++ interface/src/ui/overlays/Line3DOverlay.h | 4 ++++ interface/src/ui/overlays/LocalModelsOverlay.cpp | 6 ++++++ interface/src/ui/overlays/LocalModelsOverlay.h | 2 ++ interface/src/ui/overlays/LocalVoxelsOverlay.cpp | 5 +++++ interface/src/ui/overlays/LocalVoxelsOverlay.h | 1 + interface/src/ui/overlays/ModelOverlay.cpp | 6 +++++- interface/src/ui/overlays/ModelOverlay.h | 2 ++ interface/src/ui/overlays/Overlay.cpp | 16 ++++++++++++++++ interface/src/ui/overlays/Overlay.h | 2 ++ interface/src/ui/overlays/Overlay2D.cpp | 5 +++++ interface/src/ui/overlays/Overlay2D.h | 1 + interface/src/ui/overlays/Overlays.cpp | 10 ++++++++++ interface/src/ui/overlays/Overlays.h | 3 +++ interface/src/ui/overlays/Planar3DOverlay.cpp | 4 ++++ interface/src/ui/overlays/Planar3DOverlay.h | 1 + interface/src/ui/overlays/Rectangle3DOverlay.cpp | 11 +++++------ interface/src/ui/overlays/Rectangle3DOverlay.h | 2 ++ interface/src/ui/overlays/Sphere3DOverlay.cpp | 6 ++++++ interface/src/ui/overlays/Sphere3DOverlay.h | 2 ++ interface/src/ui/overlays/Text3DOverlay.cpp | 8 ++++++++ interface/src/ui/overlays/Text3DOverlay.h | 3 +++ interface/src/ui/overlays/TextOverlay.cpp | 8 ++++++++ interface/src/ui/overlays/TextOverlay.h | 2 ++ interface/src/ui/overlays/Volume3DOverlay.cpp | 4 ++++ interface/src/ui/overlays/Volume3DOverlay.h | 1 + 36 files changed, 181 insertions(+), 14 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 89dd4d4b01..23634ac88c 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -155,5 +155,12 @@ void Base3DOverlay::drawDashedLine(const glm::vec3& start, const glm::vec3& end) } - - +void Base3DOverlay::writeToClone(Base3DOverlay* clone) { + Overlay::writeToClone(clone); + clone->setPosition(getPosition()); + clone->setLineWidth(getLineWidth()); + clone->setIsSolid(getIsSolid()); + clone->setIsDashedLine(getIsDashedLine()); + clone->setRotation(getRotation()); + clone->setIgnoreRayIntersection(getIgnoreRayIntersection()); +} diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index 75ce6b303d..430b235381 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -54,6 +54,7 @@ public: } protected: + virtual void writeToClone(Base3DOverlay* clone); void drawDashedLine(const glm::vec3& start, const glm::vec3& end); glm::vec3 _position; diff --git a/interface/src/ui/overlays/BillboardOverlay.cpp b/interface/src/ui/overlays/BillboardOverlay.cpp index c8d4877bb5..aec5e993dd 100644 --- a/interface/src/ui/overlays/BillboardOverlay.cpp +++ b/interface/src/ui/overlays/BillboardOverlay.cpp @@ -198,3 +198,17 @@ bool BillboardOverlay::findRayIntersection(const glm::vec3& origin, const glm::v return false; } +BillboardOverlay* BillboardOverlay::createClone() { + BillboardOverlay* clone = new BillboardOverlay(); + writeToClone(clone); + return clone; +} + +void BillboardOverlay::writeToClone(BillboardOverlay* clone) { + Base3DOverlay::writeToClone(clone); + clone->setScale(_scale); + clone->setIsFacingAvatar(_isFacingAvatar); + clone->setClipFromSource(_fromImage); + clone->_url = _url; + clone->_billboard = QByteArray::QByteArray(_billboard); +} diff --git a/interface/src/ui/overlays/BillboardOverlay.h b/interface/src/ui/overlays/BillboardOverlay.h index 018ca5f5cf..e71234c1c2 100644 --- a/interface/src/ui/overlays/BillboardOverlay.h +++ b/interface/src/ui/overlays/BillboardOverlay.h @@ -35,10 +35,14 @@ public: virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const; + virtual BillboardOverlay* createClone(); + private slots: void replyFinished(); private: + virtual void writeToClone(BillboardOverlay* clone); + void setBillboardURL(const QString& url); QString _url; diff --git a/interface/src/ui/overlays/Circle3DOverlay.cpp b/interface/src/ui/overlays/Circle3DOverlay.cpp index 144119c450..1a025e5a6f 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.cpp +++ b/interface/src/ui/overlays/Circle3DOverlay.cpp @@ -319,9 +319,12 @@ bool Circle3DOverlay::findRayIntersection(const glm::vec3& origin, return intersects; } +Circle3DOverlay* Circle3DOverlay::createClone() { + Circle3DOverlay* clone = new Circle3DOverlay(); + writeToClone(clone); + return clone; +} - - - - - +void Circle3DOverlay::writeToClone(Circle3DOverlay* clone) { + Planar3DOverlay::writeToClone(clone); +} diff --git a/interface/src/ui/overlays/Circle3DOverlay.h b/interface/src/ui/overlays/Circle3DOverlay.h index 191a0d3100..8437bb0850 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.h +++ b/interface/src/ui/overlays/Circle3DOverlay.h @@ -47,8 +47,12 @@ public: void setMinorTickMarksColor(const xColor& value) { _minorTickMarksColor = value; } virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const; + + virtual Circle3DOverlay* createClone(); protected: + virtual void writeToClone(Circle3DOverlay* clone); + float _startAt; float _endAt; float _outerRadius; diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 81a2dfd498..9bf3de90c0 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -102,3 +102,9 @@ void Cube3DOverlay::render(RenderArgs* args) { delete glower; } } + +Cube3DOverlay* Cube3DOverlay::createClone() { + Cube3DOverlay* clone = new Cube3DOverlay(); + writeToClone(clone); + return clone; +} diff --git a/interface/src/ui/overlays/Cube3DOverlay.h b/interface/src/ui/overlays/Cube3DOverlay.h index 272d68bb5e..0b7b9e14a3 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.h +++ b/interface/src/ui/overlays/Cube3DOverlay.h @@ -20,6 +20,8 @@ public: Cube3DOverlay(); ~Cube3DOverlay(); virtual void render(RenderArgs* args); + + virtual Cube3DOverlay* createClone(); }; diff --git a/interface/src/ui/overlays/ImageOverlay.cpp b/interface/src/ui/overlays/ImageOverlay.cpp index 3b9d95af2e..04038834c2 100644 --- a/interface/src/ui/overlays/ImageOverlay.cpp +++ b/interface/src/ui/overlays/ImageOverlay.cpp @@ -151,4 +151,15 @@ void ImageOverlay::setProperties(const QScriptValue& properties) { } } +ImageOverlay* ImageOverlay::createClone() { + ImageOverlay* clone = new ImageOverlay(); + writeToClone(clone); + return clone; +} +void ImageOverlay::writeToClone(ImageOverlay* clone) { + Overlay2D::writeToClone(clone); + clone->_imageURL = _imageURL; + clone->_textureImage = _textureImage; + clone->_renderImage = _renderImage; +} diff --git a/interface/src/ui/overlays/ImageOverlay.h b/interface/src/ui/overlays/ImageOverlay.h index ef1ead8c02..a3b88893ae 100644 --- a/interface/src/ui/overlays/ImageOverlay.h +++ b/interface/src/ui/overlays/ImageOverlay.h @@ -45,10 +45,13 @@ public: void setImageURL(const QUrl& url); virtual void setProperties(const QScriptValue& properties); + virtual ImageOverlay* createClone(); + private slots: void replyFinished(); // we actually want to hide this... private: + virtual void writeToClone(ImageOverlay* clone); QUrl _imageURL; QImage _textureImage; diff --git a/interface/src/ui/overlays/Line3DOverlay.cpp b/interface/src/ui/overlays/Line3DOverlay.cpp index 18671ea074..4f40d07b5f 100644 --- a/interface/src/ui/overlays/Line3DOverlay.cpp +++ b/interface/src/ui/overlays/Line3DOverlay.cpp @@ -79,3 +79,14 @@ void Line3DOverlay::setProperties(const QScriptValue& properties) { } } } + +Line3DOverlay* Line3DOverlay::createClone() { + Line3DOverlay* clone = new Line3DOverlay(); + writeToClone(clone); + return clone; +} + + +void Line3DOverlay::writeToClone(Line3DOverlay* clone) { + Base3DOverlay::writeToClone(clone); +} diff --git a/interface/src/ui/overlays/Line3DOverlay.h b/interface/src/ui/overlays/Line3DOverlay.h index f9c4e0d6d6..ce7320ff80 100644 --- a/interface/src/ui/overlays/Line3DOverlay.h +++ b/interface/src/ui/overlays/Line3DOverlay.h @@ -29,7 +29,11 @@ public: virtual void setProperties(const QScriptValue& properties); + virtual Line3DOverlay* createClone(); + protected: + virtual void writeToClone(Line3DOverlay* clone); + glm::vec3 _end; }; diff --git a/interface/src/ui/overlays/LocalModelsOverlay.cpp b/interface/src/ui/overlays/LocalModelsOverlay.cpp index c1f16bf13e..7f1faf3a39 100644 --- a/interface/src/ui/overlays/LocalModelsOverlay.cpp +++ b/interface/src/ui/overlays/LocalModelsOverlay.cpp @@ -48,3 +48,9 @@ void LocalModelsOverlay::render(RenderArgs* args) { } } + +LocalModelsOverlay* LocalModelsOverlay::createClone() { + LocalModelsOverlay* clone = new LocalModelsOverlay(Application::getInstance()->getEntityClipboardRenderer()); + writeToClone(clone); + return clone; +} diff --git a/interface/src/ui/overlays/LocalModelsOverlay.h b/interface/src/ui/overlays/LocalModelsOverlay.h index 60f09b8666..0659de0ab1 100644 --- a/interface/src/ui/overlays/LocalModelsOverlay.h +++ b/interface/src/ui/overlays/LocalModelsOverlay.h @@ -25,6 +25,8 @@ public: virtual void update(float deltatime); virtual void render(RenderArgs* args); + virtual LocalModelsOverlay* createClone(); + private: EntityTreeRenderer* _entityTreeRenderer; }; diff --git a/interface/src/ui/overlays/LocalVoxelsOverlay.cpp b/interface/src/ui/overlays/LocalVoxelsOverlay.cpp index dcfc79f3b4..09b74916c3 100644 --- a/interface/src/ui/overlays/LocalVoxelsOverlay.cpp +++ b/interface/src/ui/overlays/LocalVoxelsOverlay.cpp @@ -103,3 +103,8 @@ void LocalVoxelsOverlay::setProperties(const QScriptValue &properties) { } } +LocalVoxelsOverlay* LocalVoxelsOverlay::createClone() { + LocalVoxelsOverlay* clone = new LocalVoxelsOverlay(); + writeToClone(clone); + return clone; +} diff --git a/interface/src/ui/overlays/LocalVoxelsOverlay.h b/interface/src/ui/overlays/LocalVoxelsOverlay.h index 46a88407af..9bd27e16bc 100644 --- a/interface/src/ui/overlays/LocalVoxelsOverlay.h +++ b/interface/src/ui/overlays/LocalVoxelsOverlay.h @@ -39,6 +39,7 @@ public: virtual void setProperties(const QScriptValue& properties); + virtual LocalVoxelsOverlay* createClone(); private: static QMap _voxelSystemMap; // treeName/voxelSystem diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 150d40f15a..dc7506cc9e 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -135,4 +135,8 @@ bool ModelOverlay::findRayIntersectionExtraInfo(const glm::vec3& origin, const g return _model.findRayIntersectionAgainstSubMeshes(origin, direction, distance, face, extraInfo); } - +ModelOverlay* ModelOverlay::createClone() { + ModelOverlay* clone = new ModelOverlay(); + writeToClone(clone); + return clone; +} diff --git a/interface/src/ui/overlays/ModelOverlay.h b/interface/src/ui/overlays/ModelOverlay.h index 26471a79e1..43f9acc004 100644 --- a/interface/src/ui/overlays/ModelOverlay.h +++ b/interface/src/ui/overlays/ModelOverlay.h @@ -28,6 +28,8 @@ public: virtual bool findRayIntersectionExtraInfo(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face, QString& extraInfo) const; + virtual ModelOverlay* createClone(); + private: Model _model; diff --git a/interface/src/ui/overlays/Overlay.cpp b/interface/src/ui/overlays/Overlay.cpp index 215119374e..1e4bce02d0 100644 --- a/interface/src/ui/overlays/Overlay.cpp +++ b/interface/src/ui/overlays/Overlay.cpp @@ -173,3 +173,19 @@ float Overlay::updatePulse() { return _pulse; } + +void Overlay::writeToClone(Overlay* clone) { + clone->setAlpha(getAlpha()); + clone->setAlphaPulse(getAlphaPulse()); + clone->setAnchor(getAnchor()); + clone->setColor(getColor()); + clone->setColorPulse(getColorPulse()); + clone->setGlowLevel(getGlowLevel()); + clone->setGlowLevelPulse(getGlowLevelPulse()); + clone->setPulseDirection(getPulseDirection()); + clone->setPulseMax(getPulseMax()); + clone->setPulseMin(getPulseMin()); + clone->setPulsePeriod(getPulsePeriod()); + clone->setVisible(getVisible()); + clone->_isLoaded = _isLoaded; +} diff --git a/interface/src/ui/overlays/Overlay.h b/interface/src/ui/overlays/Overlay.h index 81ddaf1a91..3a4322bd1d 100644 --- a/interface/src/ui/overlays/Overlay.h +++ b/interface/src/ui/overlays/Overlay.h @@ -77,8 +77,10 @@ public: void setAlphaPulse(float value) { _alphaPulse = value; } virtual void setProperties(const QScriptValue& properties); + virtual Overlay* createClone() = 0; protected: + virtual void writeToClone(Overlay* clone); float updatePulse(); QGLWidget* _parent; diff --git a/interface/src/ui/overlays/Overlay2D.cpp b/interface/src/ui/overlays/Overlay2D.cpp index 0bdb8790cc..f8ff2ad2fc 100644 --- a/interface/src/ui/overlays/Overlay2D.cpp +++ b/interface/src/ui/overlays/Overlay2D.cpp @@ -64,3 +64,8 @@ void Overlay2D::setProperties(const QScriptValue& properties) { //qDebug() << "set bounds to " << getBounds(); } } + +void Overlay2D::writeToClone(Overlay2D* clone) { + Overlay::writeToClone(clone); + clone->setBounds(getBounds()); +} diff --git a/interface/src/ui/overlays/Overlay2D.h b/interface/src/ui/overlays/Overlay2D.h index 283e7b7b23..49f22f1c4f 100644 --- a/interface/src/ui/overlays/Overlay2D.h +++ b/interface/src/ui/overlays/Overlay2D.h @@ -49,6 +49,7 @@ public: virtual void setProperties(const QScriptValue& properties); protected: + virtual void writeToClone(Overlay2D* clone); QRect _bounds; // where on the screen to draw }; diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index df7a5fbcea..85a28057a8 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -190,6 +190,16 @@ unsigned int Overlays::addOverlay(Overlay* overlay) { return thisID; } +unsigned int Overlays::cloneOverlay(unsigned int id) { + Overlay* thisOverlay = NULL; + if (_overlays2D.contains(id)) { + thisOverlay = _overlays2D[id]; + } else if (_overlays3D.contains(id)) { + thisOverlay = _overlays3D[id]; + } + return addOverlay(thisOverlay->createClone()); +} + bool Overlays::editOverlay(unsigned int id, const QScriptValue& properties) { Overlay* thisOverlay = NULL; QWriteLocker lock(&_lock); diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 686b998267..c5db1dfc7e 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -49,6 +49,9 @@ public slots: /// adds an overlay that's already been created unsigned int addOverlay(Overlay* overlay); + /// clones an existing overlay + unsigned int cloneOverlay(unsigned int id); + /// edits an overlay updating only the included properties, will return the identified OverlayID in case of /// successful edit, if the input id is for an unknown overlay this function will have no effect bool editOverlay(unsigned int id, const QScriptValue& properties); diff --git a/interface/src/ui/overlays/Planar3DOverlay.cpp b/interface/src/ui/overlays/Planar3DOverlay.cpp index 91a3a023f7..d2222f9051 100644 --- a/interface/src/ui/overlays/Planar3DOverlay.cpp +++ b/interface/src/ui/overlays/Planar3DOverlay.cpp @@ -102,3 +102,7 @@ bool Planar3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::ve } return intersects; } + +void Planar3DOverlay::writeToClone(Planar3DOverlay* clone) { + Base3DOverlay::writeToClone(clone); +} diff --git a/interface/src/ui/overlays/Planar3DOverlay.h b/interface/src/ui/overlays/Planar3DOverlay.h index ee4bb3e05a..a938d6a4e5 100644 --- a/interface/src/ui/overlays/Planar3DOverlay.h +++ b/interface/src/ui/overlays/Planar3DOverlay.h @@ -40,6 +40,7 @@ public: virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const; protected: + virtual void writeToClone(Planar3DOverlay* clone); glm::vec2 _dimensions; }; diff --git a/interface/src/ui/overlays/Rectangle3DOverlay.cpp b/interface/src/ui/overlays/Rectangle3DOverlay.cpp index c131a139ac..728accfad6 100644 --- a/interface/src/ui/overlays/Rectangle3DOverlay.cpp +++ b/interface/src/ui/overlays/Rectangle3DOverlay.cpp @@ -106,9 +106,8 @@ void Rectangle3DOverlay::setProperties(const QScriptValue &properties) { Planar3DOverlay::setProperties(properties); } - - - - - - +Rectangle3DOverlay* Rectangle3DOverlay::createClone() { + Rectangle3DOverlay* clone = new Rectangle3DOverlay(); + writeToClone(clone); + return clone; +} diff --git a/interface/src/ui/overlays/Rectangle3DOverlay.h b/interface/src/ui/overlays/Rectangle3DOverlay.h index 9cec6da7e7..0bb805200c 100644 --- a/interface/src/ui/overlays/Rectangle3DOverlay.h +++ b/interface/src/ui/overlays/Rectangle3DOverlay.h @@ -21,6 +21,8 @@ public: ~Rectangle3DOverlay(); virtual void render(RenderArgs* args); virtual void setProperties(const QScriptValue& properties); + + virtual Rectangle3DOverlay* createClone(); }; diff --git a/interface/src/ui/overlays/Sphere3DOverlay.cpp b/interface/src/ui/overlays/Sphere3DOverlay.cpp index 63ed3e8d7e..ef4e2ba51b 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.cpp +++ b/interface/src/ui/overlays/Sphere3DOverlay.cpp @@ -70,3 +70,9 @@ void Sphere3DOverlay::render(RenderArgs* args) { } } + +Sphere3DOverlay* Sphere3DOverlay::createClone() { + Sphere3DOverlay* clone = new Sphere3DOverlay(); + writeToClone(clone); + return clone; +} diff --git a/interface/src/ui/overlays/Sphere3DOverlay.h b/interface/src/ui/overlays/Sphere3DOverlay.h index 98776a3f57..f9db6b99af 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.h +++ b/interface/src/ui/overlays/Sphere3DOverlay.h @@ -20,6 +20,8 @@ public: Sphere3DOverlay(); ~Sphere3DOverlay(); virtual void render(RenderArgs* args); + + virtual Sphere3DOverlay* createClone(); }; diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index d8febbf0eb..a19bd097a4 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -179,4 +179,12 @@ void Text3DOverlay::setProperties(const QScriptValue& properties) { } +Text3DOverlay* Text3DOverlay::createClone() { + Text3DOverlay* clone = new Text3DOverlay(); + writeToClone(clone); + return clone; +} +void Text3DOverlay::writeToClone(Text3DOverlay* clone) { + Planar3DOverlay::writeToClone(clone); +} diff --git a/interface/src/ui/overlays/Text3DOverlay.h b/interface/src/ui/overlays/Text3DOverlay.h index 45e311c554..00b7f0ebb6 100644 --- a/interface/src/ui/overlays/Text3DOverlay.h +++ b/interface/src/ui/overlays/Text3DOverlay.h @@ -48,7 +48,10 @@ public: virtual void setProperties(const QScriptValue& properties); + virtual Text3DOverlay* createClone(); + private: + virtual void writeToClone(Text3DOverlay* clone); void enableClipPlane(GLenum plane, float x, float y, float z, float w); QString _text; diff --git a/interface/src/ui/overlays/TextOverlay.cpp b/interface/src/ui/overlays/TextOverlay.cpp index 530b30a856..f09306c4fa 100644 --- a/interface/src/ui/overlays/TextOverlay.cpp +++ b/interface/src/ui/overlays/TextOverlay.cpp @@ -125,4 +125,12 @@ void TextOverlay::setProperties(const QScriptValue& properties) { } } +TextOverlay* TextOverlay::createClone() { + TextOverlay* clone = new TextOverlay(); + writeToClone(clone); + return clone; +} +void TextOverlay::writeToClone(TextOverlay* clone) { + Overlay2D::writeToClone(clone); +} diff --git a/interface/src/ui/overlays/TextOverlay.h b/interface/src/ui/overlays/TextOverlay.h index f7ff83e542..cb519e3ffc 100644 --- a/interface/src/ui/overlays/TextOverlay.h +++ b/interface/src/ui/overlays/TextOverlay.h @@ -52,8 +52,10 @@ public: void setFontSize(int fontSize) { _fontSize = fontSize; } virtual void setProperties(const QScriptValue& properties); + virtual TextOverlay* createClone(); private: + virtual void writeToClone(TextOverlay* clone); QString _text; xColor _backgroundColor; diff --git a/interface/src/ui/overlays/Volume3DOverlay.cpp b/interface/src/ui/overlays/Volume3DOverlay.cpp index cc12d41e2e..24696c8017 100644 --- a/interface/src/ui/overlays/Volume3DOverlay.cpp +++ b/interface/src/ui/overlays/Volume3DOverlay.cpp @@ -108,3 +108,7 @@ bool Volume3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::ve } return false; } + +void Volume3DOverlay::writeToClone(Volume3DOverlay* clone) { + Base3DOverlay::writeToClone(clone); +} diff --git a/interface/src/ui/overlays/Volume3DOverlay.h b/interface/src/ui/overlays/Volume3DOverlay.h index 7cde169c30..94dd463bdf 100644 --- a/interface/src/ui/overlays/Volume3DOverlay.h +++ b/interface/src/ui/overlays/Volume3DOverlay.h @@ -42,6 +42,7 @@ public: virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const; protected: + virtual void writeToClone(Volume3DOverlay* clone); glm::vec3 _dimensions; }; From d3d80d3fe20759f2563b730ff9067bb9b259dce5 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Thu, 6 Nov 2014 00:34:59 +0100 Subject: [PATCH 02/94] filled in the rest of the properties --- interface/src/ui/overlays/Circle3DOverlay.cpp | 11 +++++++++++ interface/src/ui/overlays/ImageOverlay.cpp | 2 +- interface/src/ui/overlays/Line3DOverlay.cpp | 1 + interface/src/ui/overlays/ModelOverlay.cpp | 12 ++++++++++++ interface/src/ui/overlays/ModelOverlay.h | 3 ++- interface/src/ui/overlays/Planar3DOverlay.cpp | 1 + interface/src/ui/overlays/Text3DOverlay.cpp | 8 ++++++++ interface/src/ui/overlays/TextOverlay.cpp | 5 +++++ 8 files changed, 41 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/overlays/Circle3DOverlay.cpp b/interface/src/ui/overlays/Circle3DOverlay.cpp index 1a025e5a6f..378c59a00e 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.cpp +++ b/interface/src/ui/overlays/Circle3DOverlay.cpp @@ -327,4 +327,15 @@ Circle3DOverlay* Circle3DOverlay::createClone() { void Circle3DOverlay::writeToClone(Circle3DOverlay* clone) { Planar3DOverlay::writeToClone(clone); + clone->setStartAt(getStartAt()); + clone->setEndAt(getEndAt()); + clone->setOuterRadius(getOuterRadius()); + clone->setInnerRadius(getInnerRadius()); + clone->setHasTickMarks(getHasTickMarks()); + clone->setMajorTickMarksAngle(getMajorTickMarksAngle()); + clone->setMinorTickMarksAngle(getMinorTickMarksAngle()); + clone->setMajorTickMarksLength(getMajorTickMarksLength()); + clone->setMinorTickMarksLength(getMinorTickMarksLength()); + clone->setMajorTickMarksColor(getMajorTickMarksColor()); + clone->setMinorTickMarksColor(getMinorTickMarksColor()); } diff --git a/interface/src/ui/overlays/ImageOverlay.cpp b/interface/src/ui/overlays/ImageOverlay.cpp index 04038834c2..6c2b09018e 100644 --- a/interface/src/ui/overlays/ImageOverlay.cpp +++ b/interface/src/ui/overlays/ImageOverlay.cpp @@ -160,6 +160,6 @@ ImageOverlay* ImageOverlay::createClone() { void ImageOverlay::writeToClone(ImageOverlay* clone) { Overlay2D::writeToClone(clone); clone->_imageURL = _imageURL; - clone->_textureImage = _textureImage; + clone->_textureImage = QImage::QImage(_textureImage); clone->_renderImage = _renderImage; } diff --git a/interface/src/ui/overlays/Line3DOverlay.cpp b/interface/src/ui/overlays/Line3DOverlay.cpp index 4f40d07b5f..d4c48fbc3e 100644 --- a/interface/src/ui/overlays/Line3DOverlay.cpp +++ b/interface/src/ui/overlays/Line3DOverlay.cpp @@ -89,4 +89,5 @@ Line3DOverlay* Line3DOverlay::createClone() { void Line3DOverlay::writeToClone(Line3DOverlay* clone) { Base3DOverlay::writeToClone(clone); + clone->setEnd(getEnd()); } diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index dc7506cc9e..6d49bf3df9 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -140,3 +140,15 @@ ModelOverlay* ModelOverlay::createClone() { writeToClone(clone); return clone; } + +void ModelOverlay::writeToClone(ModelOverlay* clone) { + Base3DOverlay::writeToClone(clone); + clone->_url = _url; + if (clone->_url.isValid()) { + clone->_updateModel = true; + clone->_isLoaded = false; + } + clone->_rotation = _rotation; + clone->_scale = _scale; + clone->_updateModel = _updateModel; +} diff --git a/interface/src/ui/overlays/ModelOverlay.h b/interface/src/ui/overlays/ModelOverlay.h index 43f9acc004..50b14a8ff7 100644 --- a/interface/src/ui/overlays/ModelOverlay.h +++ b/interface/src/ui/overlays/ModelOverlay.h @@ -31,7 +31,8 @@ public: virtual ModelOverlay* createClone(); private: - + virtual void writeToClone(ModelOverlay* clone); + Model _model; QUrl _url; diff --git a/interface/src/ui/overlays/Planar3DOverlay.cpp b/interface/src/ui/overlays/Planar3DOverlay.cpp index d2222f9051..e14d45773c 100644 --- a/interface/src/ui/overlays/Planar3DOverlay.cpp +++ b/interface/src/ui/overlays/Planar3DOverlay.cpp @@ -105,4 +105,5 @@ bool Planar3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::ve void Planar3DOverlay::writeToClone(Planar3DOverlay* clone) { Base3DOverlay::writeToClone(clone); + clone->setDimensions(getDimensions()); } diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index a19bd097a4..9ab8e0f82d 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -187,4 +187,12 @@ Text3DOverlay* Text3DOverlay::createClone() { void Text3DOverlay::writeToClone(Text3DOverlay* clone) { Planar3DOverlay::writeToClone(clone); + clone->setText(getText()); + clone->setLineHeight(getLineHeight()); + clone->setLeftMargin(getLeftMargin()); + clone->setTopMargin(getTopMargin()); + clone->setRightMargin(getRightMargin()); + clone->setBottomMargin(getBottomMargin()); + clone->setIsFacingAvatar(getIsFacingAvatar()); + clone->_backgroundColor = getBackgroundColor(); } diff --git a/interface/src/ui/overlays/TextOverlay.cpp b/interface/src/ui/overlays/TextOverlay.cpp index f09306c4fa..29dc06ab64 100644 --- a/interface/src/ui/overlays/TextOverlay.cpp +++ b/interface/src/ui/overlays/TextOverlay.cpp @@ -133,4 +133,9 @@ TextOverlay* TextOverlay::createClone() { void TextOverlay::writeToClone(TextOverlay* clone) { Overlay2D::writeToClone(clone); + clone->_text = QString::QString(_text); + clone->_backgroundColor = _backgroundColor; + clone->_leftMargin = _leftMargin; + clone->_topMargin = _topMargin; + clone->_fontSize = _fontSize; } From 06da1bd5665e69aa5442945da03fc14340fcf2f5 Mon Sep 17 00:00:00 2001 From: Stojce Slavkovski Date: Thu, 6 Nov 2014 20:41:08 +0100 Subject: [PATCH 03/94] add checkbox support in scripting interface --- examples/libraries/entityPropertyDialogBox.js | 17 ++++++------ examples/newEditEntities.js | 4 +-- .../scripting/WindowScriptingInterface.cpp | 26 +++++++++++++++++++ .../src/scripting/WindowScriptingInterface.h | 1 + 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/examples/libraries/entityPropertyDialogBox.js b/examples/libraries/entityPropertyDialogBox.js index 01e0c76e0d..4315089e50 100644 --- a/examples/libraries/entityPropertyDialogBox.js +++ b/examples/libraries/entityPropertyDialogBox.js @@ -38,15 +38,15 @@ EntityPropertyDialogBox = (function () { array.push({ label: "Entity Type:" + properties.type, type: "header" }); index++; - array.push({ label: "Locked:", value: properties.locked }); + array.push({ label: "Locked:", type: "checkbox", value: properties.locked }); index++; - + if (properties.type == "Model") { array.push({ label: "Model URL:", value: properties.modelURL }); index++; array.push({ label: "Animation URL:", value: properties.animationURL }); index++; - array.push({ label: "Animation is playing:", value: properties.animationIsPlaying }); + array.push({ label: "Animation is playing:", type: "checkbox", value: properties.animationIsPlaying }); index++; array.push({ label: "Animation FPS:", value: properties.animationFPS }); index++; @@ -130,20 +130,20 @@ EntityPropertyDialogBox = (function () { index++; array.push({ label: "Mass:", value: properties.mass.toFixed(decimals) }); index++; - array.push({ label: "Ignore for Collisions:", value: properties.ignoreForCollisions }); + array.push({ label: "Ignore for Collisions:", type: "checkbox", value: properties.ignoreForCollisions }); index++; - array.push({ label: "Collisions Will Move:", value: properties.collisionsWillMove }); + array.push({ label: "Collisions Will Move:", type: "checkbox", value: properties.collisionsWillMove }); index++; array.push({ label: "Lifetime:", value: properties.lifetime.toFixed(decimals) }); index++; - array.push({ label: "Visible:", value: properties.visible }); + array.push({ label: "Visible:", type: "checkbox", value: properties.visible }); index++; array.push({ label: "Script:", value: properties.script }); index++; - + if (properties.type == "Box" || properties.type == "Sphere") { array.push({ label: "Color:", type: "header" }); index++; @@ -215,7 +215,7 @@ EntityPropertyDialogBox = (function () { var rescaledX = peekX * peekRescale / 100.0; var rescaledY = peekY * peekRescale / 100.0; var rescaledZ = peekZ * peekRescale / 100.0; - + Window.reloadNonBlockingForm([ { value: rescaledX.toFixed(decimals), oldIndex: dimensionX }, { value: rescaledY.toFixed(decimals), oldIndex: dimensionY }, @@ -323,4 +323,3 @@ EntityPropertyDialogBox = (function () { return that; }()); - diff --git a/examples/newEditEntities.js b/examples/newEditEntities.js index 57f3f29670..0d896cfa69 100644 --- a/examples/newEditEntities.js +++ b/examples/newEditEntities.js @@ -344,7 +344,7 @@ var toolBar = (function () { var position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), SPAWN_DISTANCE)); if (position.x > 0 && position.y > 0 && position.z > 0) { - Entities.addEntity({ + Entities.addEntity({ type: "Light", position: position, dimensions: { x: DEFAULT_DIMENSION, y: DEFAULT_DIMENSION, z: DEFAULT_DIMENSION }, @@ -699,7 +699,7 @@ function handeMenuEvent(menuItem) { var selectedModel = form[0].value; if (form[1].value == "Properties") { editModelID = selectedModel; - showPropertiesForm(editModelID); + entityPropertyDialogBox.openDialog(editModelID); } else if (form[1].value == "Delete") { Entities.deleteEntity(selectedModel); } else if (form[1].value == "Teleport") { diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index ed6f0cf600..9390a83358 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -248,6 +248,7 @@ QScriptValue WindowScriptingInterface::doPeekNonBlockingFormResult(QScriptValue int e = -1; int d = -1; int c = -1; + int h = -1; for (int i = 0; i < _form.property("length").toInt32(); ++i) { QScriptValue item = _form.property(i); QScriptValue value = item.property("value"); @@ -271,6 +272,11 @@ QScriptValue WindowScriptingInterface::doPeekNonBlockingFormResult(QScriptValue array.engine()->undefinedValue() ); _form.setProperty(i, item); + } else if (item.property("type").toString() == "checkbox") { + h++; + value = _checks.at(h)->checkState() == Qt::Checked; + item.setProperty("value", value); + _form.setProperty(i, item); } else { e += 1; bool ok = true; @@ -305,6 +311,7 @@ QScriptValue WindowScriptingInterface::doGetNonBlockingFormResult(QScriptValue a int e = -1; int d = -1; int c = -1; + int h = -1; for (int i = 0; i < _form.property("length").toInt32(); ++i) { QScriptValue item = _form.property(i); QScriptValue value = item.property("value"); @@ -328,6 +335,11 @@ QScriptValue WindowScriptingInterface::doGetNonBlockingFormResult(QScriptValue a array.engine()->undefinedValue() ); _form.setProperty(i, item); + } else if (item.property("type").toString() == "checkbox") { + h++; + value = _checks.at(h)->checkState() == Qt::Checked; + item.setProperty("value", value); + _form.setProperty(i, item); } else { e += 1; bool ok = true; @@ -358,6 +370,7 @@ QScriptValue WindowScriptingInterface::doGetNonBlockingFormResult(QScriptValue a _edits.clear(); _directories.clear(); _combos.clear(); + _checks.clear(); array = _form; return (_formResult == QDialog::Accepted); @@ -383,6 +396,7 @@ QScriptValue WindowScriptingInterface::showForm(const QString& title, QScriptVal int e = -1; int d = -1; int c = -1; + int h = -1; for (int i = 0; i < form.property("length").toInt32(); ++i) { QScriptValue item = form.property(i); QScriptValue value = item.property("value"); @@ -406,6 +420,11 @@ QScriptValue WindowScriptingInterface::showForm(const QString& title, QScriptVal form.engine()->undefinedValue() ); form.setProperty(i, item); + } else if (item.property("type").toString() == "checkbox") { + h++; + value = _checks.at(h)->checkState() == Qt::Checked; + item.setProperty("value", value); + form.setProperty(i, item); } else { e += 1; bool ok = true; @@ -432,6 +451,7 @@ QScriptValue WindowScriptingInterface::showForm(const QString& title, QScriptVal delete editDialog; _combos.clear(); + _checks.clear(); _edits.clear(); _directories.clear(); return (result == QDialog::Accepted); @@ -518,6 +538,12 @@ QDialog* WindowScriptingInterface::createForm(const QString& title, QScriptValue } _combos.push_back(combo); formLayout->addRow(new QLabel(item.property("label").toString()), combo); + } else if (item.property("type").toString() == "checkbox") { + QCheckBox* check = new QCheckBox(); + check->setTristate(false); + check->setCheckState(item.property("value").toString() == "true" ? Qt::Checked : Qt::Unchecked); + _checks.push_back(check); + formLayout->addRow(new QLabel(item.property("label").toString()), check); } else { QLineEdit* edit = new QLineEdit(item.property("value").toString()); edit->setMinimumWidth(200); diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index 24c21765b5..7c21e75795 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -83,6 +83,7 @@ private: bool _nonBlockingFormActive; int _formResult; QVector _combos; + QVector _checks; QVector _edits; QVector _directories; }; From 450e89df21fd5c56565342089d087694a6413420 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 10 Nov 2014 08:23:42 -0800 Subject: [PATCH 04/94] playChess script --- examples/playChess.js | 169 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 examples/playChess.js diff --git a/examples/playChess.js b/examples/playChess.js new file mode 100644 index 0000000000..660280c8f2 --- /dev/null +++ b/examples/playChess.js @@ -0,0 +1,169 @@ +// +// playChess.js +// examples +// +// Created by Clement Brisset on 11/08/2014 +// 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 + +// Script namespace +var extraDebug = extraDebug || true; +var ChessGame = ChessGame || { + BOARD_SIZE: 8, + MAX_PLAYERS: 2, + ROWS: ['1', '2', '3', '4', '5', '6', '7', '8'], + COLUMNS: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], + + whitesTileColor: {red: 250, green: 195, blue: 135}, + blacksTileColor: {red: 190, green: 115, blue: 50}, + whiteKingURL: "http://public.highfidelity.io/models/attachments/King Piece.fst", + whiteKingDimensions: { x: 0.46, y: 1.0, z: 0.46 }, + blackKingURL: "http://public.highfidelity.io/models/attachments/King Piece.fst", + blackKingDimensions: { x: 0.46, y: 1.0, z: 0.46 }, + + board: null, + pieces: null +}; + + +// Board class +ChessGame.Board = (function(position, size) { + this.position = position; + this.size = size; + this.tileSize = this.size / ChessGame.BOARD_SIZE; + this.height = this.tileSize * 0.2; + this.tiles = new Array(); + + this.spawn(); +}); +// Applies operation to each tile where operation = function(i, j) +ChessGame.Board.prototype.apply = function(operation) { + for (var i = 0; i < ChessGame.BOARD_SIZE; i++) { + for (var j = 0; j < ChessGame.BOARD_SIZE; j++) { + operation.call(this, i, j); + } + } +} +// Returns tile position +ChessGame.Board.prototype.tilePosition = function(i, j) { + return { x: this.position.x + i * this.tileSize, + y: this.position.y, + z: this.position.z + j * this.tileSize }; +} +// Checks the color of the tile +ChessGame.Board.prototype.isWhite = function(x, y) { + return (x + y) % 2 != 0; +} +// Spawns the board using entities +ChessGame.Board.prototype.spawn = function() { + if (extraDebug) { + print("Spawning board..."); + } + + this.apply(function(i, j) { + var tile = Entities.addEntity({ + type: "Box", + position: this.tilePosition(i, j), + dimensions: { x: this.tileSize, y: this.height, z: this.tileSize }, + color: (this.isWhite(i, j)) ? ChessGame.whitesTileColor : ChessGame.blacksTileColor + }); + + if (j === 0) { + // Create new row if needed + this.tiles.push(new Array()); + } + this.tiles[i].push(tile); // Store tile + }); + print("Board spawned"); +} +// Cleans up the entities of the board +ChessGame.Board.prototype.cleanup = function() { + if (extraDebug) { + print("Cleaning up board..."); + } + + this.apply(function(i, j) { + Entities.deleteEntity(this.tiles[i][j]); + }); + print("Board cleaned up"); +} + +// Piece class +ChessGame.Piece = (function(position, size, url) { + this.position = position; + this.size = size; + this.entityProperties = { + type: "Model", + position: this.position, + dimensions: this.size, + modelURL: url + } + this.entity = null; +}); +// Spawns the piece +ChessGame.Piece.prototype.spawn = function() { + this.entity = Entities.addEntity(this.entityProperties); +} +// Cleans up the piece +ChessGame.Piece.prototype.cleanup = function() { + Entities.deleteEntity(this.entity); +} + + + + +// Player class +ChessGame.Player = (function() { + +}); + +ChessGame.update = function() { + +} + +ChessGame.scriptStarting = function() { + print("playChess.js started"); + ChessGame.board = new ChessGame.Board({ x: 1, y: 1, z: 1 }, 1); + ChessGame.pieces = new Array(); + + var url = "http://public.highfidelity.io/models/attachments/King Piece.fst"; + var dimensions = { x: 0.46, y: 1.0, z: 0.46 }; + + var rowsIndex = [0, 1, 6, 7]; + for(var i in rowsIndex) { + for(var j = 0; j < ChessGame.BOARD_SIZE; j++) { + var size = Vec3.multiply(dimensions, ChessGame.board.tileSize); + if (rowsIndex[i] == 1 || rowsIndex[i] == 6) { + size = Vec3.multiply(size, 0.7); + } + var position = Vec3.sum(ChessGame.board.tilePosition(rowsIndex[i], j), + { x: 0, y: (size.y + ChessGame.board.height) / 2.0, z: 0}); + var color = (rowsIndex[i] < 4) ? ChessGame.whitesTileColor : ChessGame.blacksTileColor; + + var piece = new ChessGame.Piece(position, size, url); + piece.spawn(); + ChessGame.pieces.push(piece); + } + } +} + +ChessGame.scriptEnding = function() { + // Cleaning up board + ChessGame.board.cleanup(); + delete ChessGame.board; + + // Cleaning up pieces + for(var i in ChessGame.pieces) { + ChessGame.pieces[i].cleanup(); + } + delete ChessGame.pieces; + + print("playChess.js finished"); +} + + +Script.update.connect(ChessGame.update) +Script.scriptEnding.connect(ChessGame.scriptEnding); +ChessGame.scriptStarting(); \ No newline at end of file From ba67b042793fe55b14e44dbcd9e901a2b15eff2d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 10 Nov 2014 10:18:37 -0800 Subject: [PATCH 05/94] Switch members in EntityItemProperties to hack around corruption bug --- libraries/entities/src/EntityItemProperties.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 3ae2aa9c7a..6b22e8cba9 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -383,8 +383,8 @@ private: // NOTE: The following are pseudo client only properties. They are only used in clients which can access // properties of model geometry. But these properties are not serialized like other properties. QVector _sittingPoints; - glm::vec3 _naturalDimensions; QStringList _textureNames; + glm::vec3 _naturalDimensions; }; Q_DECLARE_METATYPE(EntityItemProperties); QScriptValue EntityItemPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties); From e4975c0e2bae6f72152727988421e1b1df1f94ba Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 11 Nov 2014 17:08:35 -0800 Subject: [PATCH 06/94] chessPiece script with sound --- examples/entityScripts/chessPiece.js | 77 ++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 examples/entityScripts/chessPiece.js diff --git a/examples/entityScripts/chessPiece.js b/examples/entityScripts/chessPiece.js new file mode 100644 index 0000000000..5342e9cd4f --- /dev/null +++ b/examples/entityScripts/chessPiece.js @@ -0,0 +1,77 @@ +(function(){ + this.sound = null; + this.entityID = null; + this.properties = null; + this.updateProperties = function(entityID) { + if (this.entityID === null) { + this.entityID = entityID; + print("entityID=" + JSON.stringify(this.entityID)); + } + if (!entityID.isKnownID || this.entityID.id !== entityID.id) { + print("Something is very wrong: Bailing!"); + return; + } + this.properties = Entities.getEntityProperties(this.entityID); + if (!this.properties.isKnownID) { + print("Unknown entityID " + this.entityID.id + " should be self.") + } + } + this.updatePosition = function(mouseEvent) { + var pickRay = Camera.computePickRay(mouseEvent.x, mouseEvent.y) + var upVector = { x: 0, y: 1, z: 0 }; + var intersection = this.rayPlaneIntersection(pickRay.origin, pickRay.direction, + this.properties.position, upVector); + Entities.editEntity(this.entityID, { position: intersection }); + } + this.snapToGrid = function() { + var position = { x: 1, y: 1, z: 1 }; + var size = 1.0; + var tileSize = size / 8.0; + var height = tileSize * 0.2; + + + var relative = Vec3.subtract(this.properties.position, position); + var i = Math.floor(relative.x / tileSize); + var j = Math.floor(relative.z / tileSize); + + relative.x = (i + 0.5) * tileSize; + relative.z = (j + 0.5) * tileSize; + var finalPos = Vec3.sum(position, relative); + Entities.editEntity(this.entityID, { position: finalPos }); + } + // Pr, Vr are respectively the Ray's Point of origin and Vector director + // Pp, Np are respectively the Plane's Point of origin and Normal vector + this.rayPlaneIntersection = function(Pr, Vr, Pp, Np) { + var d = -Vec3.dot(Pp, Np); + var t = -(Vec3.dot(Pr, Np) + d) / Vec3.dot(Vr, Np); + return Vec3.sum(Pr, Vec3.multiply(t, Vr)); + } + this.maybeDownloadSound = function() { + if (this.sound === null) { + this.sound = new Sound("http://public.highfidelity.io/sounds/Footsteps/FootstepW3Left-12db.wav"); + } + } + this.playSound = function() { + var options = new AudioInjectionOptions(); + options.position = this.properties.position; + options.volume = 0.5; + Audio.playSound(this.sound, options); + } + + + this.clickDownOnEntity = function(entityID, mouseEvent){ + this.maybeDownloadSound(); + this.updateProperties(entityID); + this.updatePosition(mouseEvent); + }; + this.holdingClickOnEntity = function(entityID, mouseEvent){ + this.updateProperties(entityID); + this.updatePosition(mouseEvent); + }; + this.clickReleaseOnEntity = function(entityID, mouseEvent){ + this.updateProperties(entityID); + this.updatePosition(mouseEvent); + this.snapToGrid(); + this.playSound(); + }; +}) \ No newline at end of file From f80068798f014aeef345bde3fca3f5e63fc2cada Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 11 Nov 2014 17:09:08 -0800 Subject: [PATCH 07/94] playChess script with autonomous pieces --- examples/playChess.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/examples/playChess.js b/examples/playChess.js index 660280c8f2..deb9cb4501 100644 --- a/examples/playChess.js +++ b/examples/playChess.js @@ -30,13 +30,16 @@ var ChessGame = ChessGame || { // Board class ChessGame.Board = (function(position, size) { - this.position = position; this.size = size; this.tileSize = this.size / ChessGame.BOARD_SIZE; this.height = this.tileSize * 0.2; + + this.position = position; + this.position.x += this.tileSize / 2.0; + this.position.y += this.height / 2.0; + this.position.z += this.tileSize / 2.0; + this.tiles = new Array(); - - this.spawn(); }); // Applies operation to each tile where operation = function(i, j) ChessGame.Board.prototype.apply = function(operation) { @@ -98,7 +101,8 @@ ChessGame.Piece = (function(position, size, url) { type: "Model", position: this.position, dimensions: this.size, - modelURL: url + modelURL: url, + script: "file:/Users/clement/hifi/examples/entityScripts/chessPiece.js" } this.entity = null; }); @@ -113,7 +117,6 @@ ChessGame.Piece.prototype.cleanup = function() { - // Player class ChessGame.Player = (function() { @@ -147,6 +150,8 @@ ChessGame.scriptStarting = function() { ChessGame.pieces.push(piece); } } + + ChessGame.board.spawn(); } ChessGame.scriptEnding = function() { From b4585163dbb0c7c5d39fc7f2df207580cbee7974 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 12 Nov 2014 14:14:37 -0800 Subject: [PATCH 08/94] Global board position / piece boundaries --- examples/entityScripts/chessPiece.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/entityScripts/chessPiece.js b/examples/entityScripts/chessPiece.js index 5342e9cd4f..fe68e2a13b 100644 --- a/examples/entityScripts/chessPiece.js +++ b/examples/entityScripts/chessPiece.js @@ -1,4 +1,6 @@ (function(){ + this.GRID_POSITION = { x: 1, y: 1, z: 1 }; + this.GRID_SIZE = 1.0; this.sound = null; this.entityID = null; this.properties = null; @@ -24,15 +26,16 @@ Entities.editEntity(this.entityID, { position: intersection }); } this.snapToGrid = function() { - var position = { x: 1, y: 1, z: 1 }; - var size = 1.0; + var position = this.GRID_POSITION; + var size = this.GRID_SIZE; var tileSize = size / 8.0; var height = tileSize * 0.2; - var relative = Vec3.subtract(this.properties.position, position); var i = Math.floor(relative.x / tileSize); var j = Math.floor(relative.z / tileSize); + i = Math.min(Math.max(0, i), 7); + j = Math.min(Math.max(-1, j), 8); relative.x = (i + 0.5) * tileSize; relative.z = (j + 0.5) * tileSize; @@ -58,7 +61,6 @@ Audio.playSound(this.sound, options); } - this.clickDownOnEntity = function(entityID, mouseEvent){ this.maybeDownloadSound(); this.updateProperties(entityID); From d25af3b4c9428c96ee0c7ec45f8a2dd4daa37088 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 12 Nov 2014 14:15:18 -0800 Subject: [PATCH 09/94] Actual piece meshes --- examples/playChess.js | 183 +++++++++++++++++++++++++++++++++--------- 1 file changed, 147 insertions(+), 36 deletions(-) diff --git a/examples/playChess.js b/examples/playChess.js index deb9cb4501..0ffaca5bb2 100644 --- a/examples/playChess.js +++ b/examples/playChess.js @@ -16,15 +16,57 @@ var ChessGame = ChessGame || { ROWS: ['1', '2', '3', '4', '5', '6', '7', '8'], COLUMNS: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], - whitesTileColor: {red: 250, green: 195, blue: 135}, - blacksTileColor: {red: 190, green: 115, blue: 50}, - whiteKingURL: "http://public.highfidelity.io/models/attachments/King Piece.fst", - whiteKingDimensions: { x: 0.46, y: 1.0, z: 0.46 }, - blackKingURL: "http://public.highfidelity.io/models/attachments/King Piece.fst", - blackKingDimensions: { x: 0.46, y: 1.0, z: 0.46 }, - + whitesTileColor: { red: 250, green: 195, blue: 135 }, + blacksTileColor: { red: 190, green: 115, blue: 50 }, + board: null, - pieces: null + pieces: { + all: new Array(), + king: { + whiteURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/King_White.fbx", + blackURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/King_Black.fbx", + dimensions: { x: 110.496, y: 306.713, z: 110.496 }, + rotation: Quat.fromPitchYawRollDegrees(0, 90, 0) + }, + queen: { + whiteURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Queen_White.fbx", + blackURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Queen_Black.fbx", + dimensions: { x: 110.496, y: 257.459, z: 110.496 }, + rotation: Quat.fromPitchYawRollDegrees(0, 0, 0) + }, + bishop: { + whiteURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Bishop_White.fbx", + blackURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Bishop_Black.fbx", + dimensions: { x: 102.002, y: 213.941, z: 102.002 }, + rotation: Quat.fromPitchYawRollDegrees(0, 0, 0), + white: [], + black: [] + }, + knight: { + whiteURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Knight_White.fbx", + blackURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Knight_Black.fbx", + dimensions: { x: 95.602, y: 186.939, z: 95.602 }, + rotation: Quat.fromPitchYawRollDegrees(0, 180, 0), + white: [], + black: [] + }, + rook: { + whiteURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Rook_White.fbx", + blackURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Rook_Black.fbx", + dimensions: { x: 101.024, y: 167.523, z: 101.024 }, + rotation: Quat.fromPitchYawRollDegrees(0, 0, 0), + white: [], + black: [] + }, + pawn: { + whiteURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Pawn_White.fbx", + blackURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Pawn_Black.fbx", + dimensions: { x: 93.317, y: 138.747, z: 93.317 }, + rotation: Quat.fromPitchYawRollDegrees(0, 0, 0), + white: [], + black: [] + } + } }; @@ -94,14 +136,16 @@ ChessGame.Board.prototype.cleanup = function() { } // Piece class -ChessGame.Piece = (function(position, size, url) { +ChessGame.Piece = (function(position, size, url, rotation) { this.position = position; this.size = size; this.entityProperties = { type: "Model", position: this.position, + rotation: rotation, dimensions: this.size, modelURL: url, + //script: "https://s3-us-west-1.amazonaws.com/highfidelity-dev/scripts/chessPiece.js" script: "file:/Users/clement/hifi/examples/entityScripts/chessPiece.js" } this.entity = null; @@ -110,11 +154,30 @@ ChessGame.Piece = (function(position, size, url) { ChessGame.Piece.prototype.spawn = function() { this.entity = Entities.addEntity(this.entityProperties); } +// Updates the metadata stored by the piece +ChessGame.Piece.prototype.updateMetaData = function(metaDataString) { + Entities.editEntity(this.entity, { animationURL: metaDataString }); +} // Cleans up the piece ChessGame.Piece.prototype.cleanup = function() { Entities.deleteEntity(this.entity); } - +ChessGame.makePiece = function(properties, i, j, isWhite) { + var url = (isWhite) ? properties.whiteURL : properties.blackURL; + var size = Vec3.multiply(1.0 / ChessGame.pieces.king.dimensions.y, + properties.dimensions); + size = Vec3.multiply(1.5 * ChessGame.board.tileSize, size); + var rotation = (isWhite) ? properties.rotation + : Quat.multiply(Quat.fromPitchYawRollDegrees(0, 180, 0), + properties.rotation); + var position = Vec3.sum(ChessGame.board.tilePosition(i, j), + { x: 0, y: (size.y + ChessGame.board.height) / 2.0, z: 0}); + + var piece = new ChessGame.Piece(position, size, url, rotation); + piece.spawn(); + ChessGame.pieces.all.push(piece); + return piece; +} // Player class @@ -125,33 +188,81 @@ ChessGame.Player = (function() { ChessGame.update = function() { } +ChessGame.buildMetaDataString = function() { + var metadataObject = { + board: { + position: ChessGame.board.position, + size: ChessGame.board.size + } + }; + + return JSON.stringify(metadataObject); +} + +ChessGame.buildBoard = function() { + // Setup board + ChessGame.board = new ChessGame.Board({ x: 1, y: 1, z: 1 }, 1); + ChessGame.board.spawn(); + + // Setup white pieces + // King + var piece = ChessGame.makePiece(ChessGame.pieces.king, 0, 3, true); + ChessGame.pieces.king.white = piece; + // Queen + piece = ChessGame.makePiece(ChessGame.pieces.queen, 0, 4, true); + ChessGame.pieces.queen.white = piece; + // Bishop + piece = ChessGame.makePiece(ChessGame.pieces.bishop, 0, 2, true); + ChessGame.pieces.bishop.white.push(piece); + piece = ChessGame.makePiece(ChessGame.pieces.bishop, 0, 5, true); + ChessGame.pieces.bishop.white.push(piece); + // Knight + piece = ChessGame.makePiece(ChessGame.pieces.knight, 0, 1, true); + ChessGame.pieces.knight.white.push(piece); + piece = ChessGame.makePiece(ChessGame.pieces.knight, 0, 6, true); + ChessGame.pieces.knight.white.push(piece); + // Rook + piece = ChessGame.makePiece(ChessGame.pieces.rook, 0, 0, true); + ChessGame.pieces.rook.white.push(piece); + piece = ChessGame.makePiece(ChessGame.pieces.rook, 0, 7, true); + ChessGame.pieces.rook.white.push(piece); + for(var j = 0; j < ChessGame.BOARD_SIZE; j++) { + piece = ChessGame.makePiece(ChessGame.pieces.pawn, 1, j, true); + ChessGame.pieces.pawn.white.push(piece); + } + + // Setup black pieces + // King + var piece = ChessGame.makePiece(ChessGame.pieces.king, 7, 3, false); + ChessGame.pieces.king.white = piece; + // Queen + piece = ChessGame.makePiece(ChessGame.pieces.queen, 7, 4, false); + ChessGame.pieces.queen.white = piece; + // Bishop + piece = ChessGame.makePiece(ChessGame.pieces.bishop, 7, 2, false); + ChessGame.pieces.bishop.white.push(piece); + piece = ChessGame.makePiece(ChessGame.pieces.bishop, 7, 5, false); + ChessGame.pieces.bishop.white.push(piece); + // Knight + piece = ChessGame.makePiece(ChessGame.pieces.knight, 7, 1, false); + ChessGame.pieces.knight.white.push(piece); + piece = ChessGame.makePiece(ChessGame.pieces.knight, 7, 6, false); + ChessGame.pieces.knight.white.push(piece); + // Rook + piece = ChessGame.makePiece(ChessGame.pieces.rook, 7, 0, false); + ChessGame.pieces.rook.white.push(piece); + piece = ChessGame.makePiece(ChessGame.pieces.rook, 7, 7, false); + ChessGame.pieces.rook.white.push(piece); + for(var j = 0; j < ChessGame.BOARD_SIZE; j++) { + piece = ChessGame.makePiece(ChessGame.pieces.pawn, 6, j, false); + ChessGame.pieces.pawn.black.push(piece); + } +} + ChessGame.scriptStarting = function() { print("playChess.js started"); - ChessGame.board = new ChessGame.Board({ x: 1, y: 1, z: 1 }, 1); - ChessGame.pieces = new Array(); - - var url = "http://public.highfidelity.io/models/attachments/King Piece.fst"; - var dimensions = { x: 0.46, y: 1.0, z: 0.46 }; - - var rowsIndex = [0, 1, 6, 7]; - for(var i in rowsIndex) { - for(var j = 0; j < ChessGame.BOARD_SIZE; j++) { - var size = Vec3.multiply(dimensions, ChessGame.board.tileSize); - if (rowsIndex[i] == 1 || rowsIndex[i] == 6) { - size = Vec3.multiply(size, 0.7); - } - var position = Vec3.sum(ChessGame.board.tilePosition(rowsIndex[i], j), - { x: 0, y: (size.y + ChessGame.board.height) / 2.0, z: 0}); - var color = (rowsIndex[i] < 4) ? ChessGame.whitesTileColor : ChessGame.blacksTileColor; - - var piece = new ChessGame.Piece(position, size, url); - piece.spawn(); - ChessGame.pieces.push(piece); - } - } - - ChessGame.board.spawn(); + ChessGame.buildBoard(); } ChessGame.scriptEnding = function() { @@ -160,8 +271,8 @@ ChessGame.scriptEnding = function() { delete ChessGame.board; // Cleaning up pieces - for(var i in ChessGame.pieces) { - ChessGame.pieces[i].cleanup(); + for(var i in ChessGame.pieces.all) { + ChessGame.pieces.all[i].cleanup(); } delete ChessGame.pieces; From 76d45953fd24c0ff8a54c01b2e91be525103b4a1 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 12 Nov 2014 15:34:14 -0800 Subject: [PATCH 10/94] switch to mesh board --- examples/playChess.js | 107 +++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 64 deletions(-) diff --git a/examples/playChess.js b/examples/playChess.js index 0ffaca5bb2..35676af21b 100644 --- a/examples/playChess.js +++ b/examples/playChess.js @@ -20,6 +20,9 @@ var ChessGame = ChessGame || { blacksTileColor: { red: 190, green: 115, blue: 50 }, board: null, + boardURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Board.fbx", + boardDimensions: { x: 773.191, y: 20.010, z: 773.191 }, + sizeFactor: 1.0 / 773.191, pieces: { all: new Array(), king: { @@ -38,7 +41,7 @@ var ChessGame = ChessGame || { whiteURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Bishop_White.fbx", blackURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Bishop_Black.fbx", dimensions: { x: 102.002, y: 213.941, z: 102.002 }, - rotation: Quat.fromPitchYawRollDegrees(0, 0, 0), + rotation: Quat.fromPitchYawRollDegrees(0, 90, 0), white: [], black: [] }, @@ -72,30 +75,18 @@ var ChessGame = ChessGame || { // Board class ChessGame.Board = (function(position, size) { - this.size = size; - this.tileSize = this.size / ChessGame.BOARD_SIZE; - this.height = this.tileSize * 0.2; + this.tileSize = size / 10.0; + this.dimensions = Vec3.multiply(ChessGame.sizeFactor * size, + ChessGame.boardDimensions); + this.position = Vec3.sum(position, Vec3.multiply(0.5, this.dimensions)); - this.position = position; - this.position.x += this.tileSize / 2.0; - this.position.y += this.height / 2.0; - this.position.z += this.tileSize / 2.0; - - this.tiles = new Array(); + this.entity = null; }); -// Applies operation to each tile where operation = function(i, j) -ChessGame.Board.prototype.apply = function(operation) { - for (var i = 0; i < ChessGame.BOARD_SIZE; i++) { - for (var j = 0; j < ChessGame.BOARD_SIZE; j++) { - operation.call(this, i, j); - } - } -} // Returns tile position ChessGame.Board.prototype.tilePosition = function(i, j) { - return { x: this.position.x + i * this.tileSize, - y: this.position.y, - z: this.position.z + j * this.tileSize }; + return { x: this.position.x + (i - 5.0 + 0.5) * this.tileSize, + y: this.position.y + this.dimensions.y / 2.0, + z: this.position.z + (j - 5.0 + 0.5) * this.tileSize }; } // Checks the color of the tile ChessGame.Board.prototype.isWhite = function(x, y) { @@ -107,20 +98,13 @@ ChessGame.Board.prototype.spawn = function() { print("Spawning board..."); } - this.apply(function(i, j) { - var tile = Entities.addEntity({ - type: "Box", - position: this.tilePosition(i, j), - dimensions: { x: this.tileSize, y: this.height, z: this.tileSize }, - color: (this.isWhite(i, j)) ? ChessGame.whitesTileColor : ChessGame.blacksTileColor - }); - - if (j === 0) { - // Create new row if needed - this.tiles.push(new Array()); - } - this.tiles[i].push(tile); // Store tile + this.entity = Entities.addEntity({ + type: "Model", + modelURL: ChessGame.boardURL, + position: this.position, + dimensions: this.dimensions }); + print("Board spawned"); } // Cleans up the entities of the board @@ -128,17 +112,15 @@ ChessGame.Board.prototype.cleanup = function() { if (extraDebug) { print("Cleaning up board..."); } - - this.apply(function(i, j) { - Entities.deleteEntity(this.tiles[i][j]); - }); + Entities.deleteEntity(this.entity); print("Board cleaned up"); } // Piece class ChessGame.Piece = (function(position, size, url, rotation) { - this.position = position; this.size = size; + this.position = position; + this.position.y += this.size.y / 2.0; this.entityProperties = { type: "Model", position: this.position, @@ -164,14 +146,11 @@ ChessGame.Piece.prototype.cleanup = function() { } ChessGame.makePiece = function(properties, i, j, isWhite) { var url = (isWhite) ? properties.whiteURL : properties.blackURL; - var size = Vec3.multiply(1.0 / ChessGame.pieces.king.dimensions.y, - properties.dimensions); - size = Vec3.multiply(1.5 * ChessGame.board.tileSize, size); + var size = Vec3.multiply(0.5 * ChessGame.sizeFactor, properties.dimensions); var rotation = (isWhite) ? properties.rotation : Quat.multiply(Quat.fromPitchYawRollDegrees(0, 180, 0), properties.rotation); - var position = Vec3.sum(ChessGame.board.tilePosition(i, j), - { x: 0, y: (size.y + ChessGame.board.height) / 2.0, z: 0}); + var position = ChessGame.board.tilePosition(i, j); var piece = new ChessGame.Piece(position, size, url, rotation); piece.spawn(); @@ -206,55 +185,55 @@ ChessGame.buildBoard = function() { // Setup white pieces // King - var piece = ChessGame.makePiece(ChessGame.pieces.king, 0, 3, true); + var piece = ChessGame.makePiece(ChessGame.pieces.king, 1, 4, true); ChessGame.pieces.king.white = piece; // Queen - piece = ChessGame.makePiece(ChessGame.pieces.queen, 0, 4, true); + piece = ChessGame.makePiece(ChessGame.pieces.queen, 1, 5, true); ChessGame.pieces.queen.white = piece; // Bishop - piece = ChessGame.makePiece(ChessGame.pieces.bishop, 0, 2, true); + piece = ChessGame.makePiece(ChessGame.pieces.bishop, 1, 3, true); ChessGame.pieces.bishop.white.push(piece); - piece = ChessGame.makePiece(ChessGame.pieces.bishop, 0, 5, true); + piece = ChessGame.makePiece(ChessGame.pieces.bishop, 1, 6, true); ChessGame.pieces.bishop.white.push(piece); // Knight - piece = ChessGame.makePiece(ChessGame.pieces.knight, 0, 1, true); + piece = ChessGame.makePiece(ChessGame.pieces.knight, 1, 2, true); ChessGame.pieces.knight.white.push(piece); - piece = ChessGame.makePiece(ChessGame.pieces.knight, 0, 6, true); + piece = ChessGame.makePiece(ChessGame.pieces.knight, 1, 7, true); ChessGame.pieces.knight.white.push(piece); // Rook - piece = ChessGame.makePiece(ChessGame.pieces.rook, 0, 0, true); + piece = ChessGame.makePiece(ChessGame.pieces.rook, 1, 1, true); ChessGame.pieces.rook.white.push(piece); - piece = ChessGame.makePiece(ChessGame.pieces.rook, 0, 7, true); + piece = ChessGame.makePiece(ChessGame.pieces.rook, 1, 8, true); ChessGame.pieces.rook.white.push(piece); - for(var j = 0; j < ChessGame.BOARD_SIZE; j++) { - piece = ChessGame.makePiece(ChessGame.pieces.pawn, 1, j, true); + for(var j = 1; j <= ChessGame.BOARD_SIZE; j++) { + piece = ChessGame.makePiece(ChessGame.pieces.pawn, 2, j, true); ChessGame.pieces.pawn.white.push(piece); } // Setup black pieces // King - var piece = ChessGame.makePiece(ChessGame.pieces.king, 7, 3, false); + var piece = ChessGame.makePiece(ChessGame.pieces.king, 8, 4, false); ChessGame.pieces.king.white = piece; // Queen - piece = ChessGame.makePiece(ChessGame.pieces.queen, 7, 4, false); + piece = ChessGame.makePiece(ChessGame.pieces.queen, 8, 5, false); ChessGame.pieces.queen.white = piece; // Bishop - piece = ChessGame.makePiece(ChessGame.pieces.bishop, 7, 2, false); + piece = ChessGame.makePiece(ChessGame.pieces.bishop, 8, 3, false); ChessGame.pieces.bishop.white.push(piece); - piece = ChessGame.makePiece(ChessGame.pieces.bishop, 7, 5, false); + piece = ChessGame.makePiece(ChessGame.pieces.bishop, 8, 6, false); ChessGame.pieces.bishop.white.push(piece); // Knight - piece = ChessGame.makePiece(ChessGame.pieces.knight, 7, 1, false); + piece = ChessGame.makePiece(ChessGame.pieces.knight, 8, 2, false); ChessGame.pieces.knight.white.push(piece); - piece = ChessGame.makePiece(ChessGame.pieces.knight, 7, 6, false); + piece = ChessGame.makePiece(ChessGame.pieces.knight, 8, 7, false); ChessGame.pieces.knight.white.push(piece); // Rook - piece = ChessGame.makePiece(ChessGame.pieces.rook, 7, 0, false); + piece = ChessGame.makePiece(ChessGame.pieces.rook, 8, 1, false); ChessGame.pieces.rook.white.push(piece); - piece = ChessGame.makePiece(ChessGame.pieces.rook, 7, 7, false); + piece = ChessGame.makePiece(ChessGame.pieces.rook, 8, 8, false); ChessGame.pieces.rook.white.push(piece); - for(var j = 0; j < ChessGame.BOARD_SIZE; j++) { - piece = ChessGame.makePiece(ChessGame.pieces.pawn, 6, j, false); + for(var j = 1; j <= ChessGame.BOARD_SIZE; j++) { + piece = ChessGame.makePiece(ChessGame.pieces.pawn, 7, j, false); ChessGame.pieces.pawn.black.push(piece); } } From 6f8b702334bde740a3b905d383200bdc6e5ed981 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 12 Nov 2014 15:34:39 -0800 Subject: [PATCH 11/94] New grid --- examples/entityScripts/chessPiece.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/entityScripts/chessPiece.js b/examples/entityScripts/chessPiece.js index fe68e2a13b..70a4a82c3b 100644 --- a/examples/entityScripts/chessPiece.js +++ b/examples/entityScripts/chessPiece.js @@ -28,14 +28,13 @@ this.snapToGrid = function() { var position = this.GRID_POSITION; var size = this.GRID_SIZE; - var tileSize = size / 8.0; - var height = tileSize * 0.2; + var tileSize = size / 10.0; var relative = Vec3.subtract(this.properties.position, position); var i = Math.floor(relative.x / tileSize); var j = Math.floor(relative.z / tileSize); - i = Math.min(Math.max(0, i), 7); - j = Math.min(Math.max(-1, j), 8); + i = Math.min(Math.max(1, i), 8); + j = Math.min(Math.max(0, j), 10); relative.x = (i + 0.5) * tileSize; relative.z = (j + 0.5) * tileSize; From 7193fcc89dfc523a62a8be5a56306382ae0c6638 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 12 Nov 2014 17:12:27 -0800 Subject: [PATCH 12/94] Metadata for pieces --- examples/entityScripts/chessPiece.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/examples/entityScripts/chessPiece.js b/examples/entityScripts/chessPiece.js index 70a4a82c3b..13d36d28fb 100644 --- a/examples/entityScripts/chessPiece.js +++ b/examples/entityScripts/chessPiece.js @@ -34,7 +34,7 @@ var i = Math.floor(relative.x / tileSize); var j = Math.floor(relative.z / tileSize); i = Math.min(Math.max(1, i), 8); - j = Math.min(Math.max(0, j), 10); + j = Math.min(Math.max(0, j), 9); relative.x = (i + 0.5) * tileSize; relative.z = (j + 0.5) * tileSize; @@ -59,10 +59,20 @@ options.volume = 0.5; Audio.playSound(this.sound, options); } + this.getMetadata = function() { + var metadataObject = JSON.parse(this.properties.animationURL); + if (metadataObject.gamePosition) { + this.GRID_POSITION = metadataObject.gamePosition; + } + if (metadataObject.gameSize) { + this.GRID_SIZE = metadataObject.gameSize; + } + } this.clickDownOnEntity = function(entityID, mouseEvent){ this.maybeDownloadSound(); this.updateProperties(entityID); + this.getMetadata(); this.updatePosition(mouseEvent); }; this.holdingClickOnEntity = function(entityID, mouseEvent){ From bada1d8e38d29d9099666557b30287627b2148e2 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 12 Nov 2014 17:13:29 -0800 Subject: [PATCH 13/94] Cleaner code + metadata --- examples/playChess.js | 250 +++++++++++++++++++----------------------- 1 file changed, 114 insertions(+), 136 deletions(-) diff --git a/examples/playChess.js b/examples/playChess.js index 35676af21b..ecfe1d12ae 100644 --- a/examples/playChess.js +++ b/examples/playChess.js @@ -8,89 +8,86 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +var gamePosition = { x: 1.0, y: 1.0, z: 1.0 }; +var gameSize = 1.0; + // Script namespace var extraDebug = extraDebug || true; var ChessGame = ChessGame || { - BOARD_SIZE: 8, - MAX_PLAYERS: 2, - ROWS: ['1', '2', '3', '4', '5', '6', '7', '8'], - COLUMNS: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'], + BOARD: { + modelURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Board.fbx", + dimensions: { x: 773.191, y: 20.010, z: 773.191 }, + rotation: Quat.fromPitchYawRollDegrees(0, 90, 0), + numTiles: 10.0 + }, + KING: 0, QUEEN: 1, BISHOP: 2, KNIGHT: 3, ROOK: 4, PAWN: 5, - whitesTileColor: { red: 250, green: 195, blue: 135 }, - blacksTileColor: { red: 190, green: 115, blue: 50 }, - board: null, - boardURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Board.fbx", - boardDimensions: { x: 773.191, y: 20.010, z: 773.191 }, - sizeFactor: 1.0 / 773.191, - pieces: { - all: new Array(), - king: { - whiteURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/King_White.fbx", - blackURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/King_Black.fbx", - dimensions: { x: 110.496, y: 306.713, z: 110.496 }, - rotation: Quat.fromPitchYawRollDegrees(0, 90, 0) - }, - queen: { - whiteURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Queen_White.fbx", - blackURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Queen_Black.fbx", - dimensions: { x: 110.496, y: 257.459, z: 110.496 }, - rotation: Quat.fromPitchYawRollDegrees(0, 0, 0) - }, - bishop: { - whiteURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Bishop_White.fbx", - blackURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Bishop_Black.fbx", - dimensions: { x: 102.002, y: 213.941, z: 102.002 }, - rotation: Quat.fromPitchYawRollDegrees(0, 90, 0), - white: [], - black: [] - }, - knight: { - whiteURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Knight_White.fbx", - blackURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Knight_Black.fbx", - dimensions: { x: 95.602, y: 186.939, z: 95.602 }, - rotation: Quat.fromPitchYawRollDegrees(0, 180, 0), - white: [], - black: [] - }, - rook: { - whiteURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Rook_White.fbx", - blackURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Rook_Black.fbx", - dimensions: { x: 101.024, y: 167.523, z: 101.024 }, - rotation: Quat.fromPitchYawRollDegrees(0, 0, 0), - white: [], - black: [] - }, - pawn: { - whiteURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Pawn_White.fbx", - blackURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Pawn_Black.fbx", - dimensions: { x: 93.317, y: 138.747, z: 93.317 }, - rotation: Quat.fromPitchYawRollDegrees(0, 0, 0), - white: [], - black: [] - } - } + pieces: new Array() }; +ChessGame.getPieceInfo = function(type, isWhite) { + var info = { + modelURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/", + dimensions: { x: 1.0, y: 1.0, z: 1.0 }, + rotation: Quat.fromPitchYawRollDegrees(0, 0, 0) + } + + switch(type) { + case ChessGame.KING: + info.modelURL += "King"; + info.dimensions = { x: 110.496, y: 306.713, z: 110.496 }; + info.rotation = Quat.fromPitchYawRollDegrees(0, 90, 0); + break; + case ChessGame.QUEEN: + info.modelURL += "Queen"; + info.dimensions = { x: 110.496, y: 257.459, z: 110.496 }; + break; + case ChessGame.BISHOP: + info.modelURL += "Bishop"; + info.dimensions = { x: 102.002, y: 213.941, z: 102.002 }; + info.rotation = Quat.fromPitchYawRollDegrees(0, 90, 0); + break; + case ChessGame.KNIGHT: + info.modelURL += "Knight"; + info.dimensions = { x: 95.602, y: 186.939, z: 95.602 }; + info.rotation = Quat.fromPitchYawRollDegrees(0, 180, 0); + break; + case ChessGame.ROOK: + info.modelURL += "Rook"; + info.dimensions = { x: 101.024, y: 167.523, z: 101.024 }; + break; + case ChessGame.PAWN: + info.modelURL += "Pawn"; + info.dimensions = { x: 93.317, y: 138.747, z: 93.317 }; + break; + } + info.modelURL += ((isWhite) ? "_White" : "_Black") + ".fbx" + + return info; +} + // Board class ChessGame.Board = (function(position, size) { - this.tileSize = size / 10.0; - this.dimensions = Vec3.multiply(ChessGame.sizeFactor * size, - ChessGame.boardDimensions); + this.dimensions = Vec3.multiply(1.0 / ChessGame.BOARD.dimensions.x, ChessGame.BOARD.dimensions); // 1 by 1 + this.dimensions = Vec3.multiply(size, this.dimensions); // size by size this.position = Vec3.sum(position, Vec3.multiply(0.5, this.dimensions)); + this.tileSize = size / ChessGame.BOARD.numTiles; this.entity = null; }); -// Returns tile position +// Returns the top center point of tile i,j ChessGame.Board.prototype.tilePosition = function(i, j) { - return { x: this.position.x + (i - 5.0 + 0.5) * this.tileSize, - y: this.position.y + this.dimensions.y / 2.0, - z: this.position.z + (j - 5.0 + 0.5) * this.tileSize }; + return { + x: this.position.x + (i - ChessGame.BOARD.numTiles / 2.0 + 0.5) * this.tileSize, + y: this.position.y + this.dimensions.y / 2.0, + z: this.position.z + (j - ChessGame.BOARD.numTiles / 2.0 + 0.5) * this.tileSize + }; } // Checks the color of the tile -ChessGame.Board.prototype.isWhite = function(x, y) { - return (x + y) % 2 != 0; +ChessGame.Board.prototype.isWhite = function(i, j) { + return (i + j) % 2 != 0; } // Spawns the board using entities ChessGame.Board.prototype.spawn = function() { @@ -100,7 +97,7 @@ ChessGame.Board.prototype.spawn = function() { this.entity = Entities.addEntity({ type: "Model", - modelURL: ChessGame.boardURL, + modelURL: ChessGame.BOARD.modelURL, position: this.position, dimensions: this.dimensions }); @@ -117,15 +114,15 @@ ChessGame.Board.prototype.cleanup = function() { } // Piece class -ChessGame.Piece = (function(position, size, url, rotation) { - this.size = size; +ChessGame.Piece = (function(position, dimensions, url, rotation) { + this.dimensions = dimensions; this.position = position; - this.position.y += this.size.y / 2.0; + this.position.y += this.dimensions.y / 2.0; this.entityProperties = { type: "Model", position: this.position, rotation: rotation, - dimensions: this.size, + dimensions: this.dimensions, modelURL: url, //script: "https://s3-us-west-1.amazonaws.com/highfidelity-dev/scripts/chessPiece.js" script: "file:/Users/clement/hifi/examples/entityScripts/chessPiece.js" @@ -137,110 +134,93 @@ ChessGame.Piece.prototype.spawn = function() { this.entity = Entities.addEntity(this.entityProperties); } // Updates the metadata stored by the piece -ChessGame.Piece.prototype.updateMetaData = function(metaDataString) { - Entities.editEntity(this.entity, { animationURL: metaDataString }); +ChessGame.Piece.prototype.updateMetadata = function(metadataString) { + Entities.editEntity(this.entity, { animationURL: metadataString }); } // Cleans up the piece ChessGame.Piece.prototype.cleanup = function() { Entities.deleteEntity(this.entity); } -ChessGame.makePiece = function(properties, i, j, isWhite) { - var url = (isWhite) ? properties.whiteURL : properties.blackURL; - var size = Vec3.multiply(0.5 * ChessGame.sizeFactor, properties.dimensions); - var rotation = (isWhite) ? properties.rotation +ChessGame.makePiece = function(piece, i, j, isWhite) { + var info = ChessGame.getPieceInfo(piece, isWhite); + var url = info.modelURL; + var size = Vec3.multiply(0.5 * (1.0 / ChessGame.BOARD.dimensions.x), info.dimensions); + var rotation = (isWhite) ? info.rotation : Quat.multiply(Quat.fromPitchYawRollDegrees(0, 180, 0), - properties.rotation); + info.rotation); var position = ChessGame.board.tilePosition(i, j); var piece = new ChessGame.Piece(position, size, url, rotation); piece.spawn(); - ChessGame.pieces.all.push(piece); + ChessGame.pieces.push(piece); return piece; } - -// Player class -ChessGame.Player = (function() { - -}); - -ChessGame.update = function() { - -} ChessGame.buildMetaDataString = function() { var metadataObject = { - board: { - position: ChessGame.board.position, - size: ChessGame.board.size - } + gamePosition: gamePosition, + gameSize: gameSize }; - return JSON.stringify(metadataObject); } ChessGame.buildBoard = function() { // Setup board - ChessGame.board = new ChessGame.Board({ x: 1, y: 1, z: 1 }, 1); + ChessGame.board = new ChessGame.Board(gamePosition, gameSize); ChessGame.board.spawn(); // Setup white pieces + var isWhite = true; + var row = 1; // King - var piece = ChessGame.makePiece(ChessGame.pieces.king, 1, 4, true); - ChessGame.pieces.king.white = piece; + var piece =ChessGame.makePiece(ChessGame.KING, row, 5, isWhite); // Queen - piece = ChessGame.makePiece(ChessGame.pieces.queen, 1, 5, true); - ChessGame.pieces.queen.white = piece; + piece = ChessGame.makePiece(ChessGame.QUEEN, row, 4, isWhite); // Bishop - piece = ChessGame.makePiece(ChessGame.pieces.bishop, 1, 3, true); - ChessGame.pieces.bishop.white.push(piece); - piece = ChessGame.makePiece(ChessGame.pieces.bishop, 1, 6, true); - ChessGame.pieces.bishop.white.push(piece); + piece = ChessGame.makePiece(ChessGame.BISHOP, row, 3, isWhite); + piece = ChessGame.makePiece(ChessGame.BISHOP, row, 6, isWhite); // Knight - piece = ChessGame.makePiece(ChessGame.pieces.knight, 1, 2, true); - ChessGame.pieces.knight.white.push(piece); - piece = ChessGame.makePiece(ChessGame.pieces.knight, 1, 7, true); - ChessGame.pieces.knight.white.push(piece); + piece = ChessGame.makePiece(ChessGame.KNIGHT, row, 2, isWhite); + piece = ChessGame.makePiece(ChessGame.KNIGHT, row, 7, isWhite); // Rook - piece = ChessGame.makePiece(ChessGame.pieces.rook, 1, 1, true); - ChessGame.pieces.rook.white.push(piece); - piece = ChessGame.makePiece(ChessGame.pieces.rook, 1, 8, true); - ChessGame.pieces.rook.white.push(piece); - for(var j = 1; j <= ChessGame.BOARD_SIZE; j++) { - piece = ChessGame.makePiece(ChessGame.pieces.pawn, 2, j, true); - ChessGame.pieces.pawn.white.push(piece); + piece = ChessGame.makePiece(ChessGame.ROOK, row, 1, isWhite); + piece = ChessGame.makePiece(ChessGame.ROOK, row, 8, isWhite); + for(var j = 1; j <= 8; j++) { + piece = ChessGame.makePiece(ChessGame.PAWN, row + 1, j, isWhite); } // Setup black pieces + isWhite = false; + row = 8; // King - var piece = ChessGame.makePiece(ChessGame.pieces.king, 8, 4, false); - ChessGame.pieces.king.white = piece; + piece = ChessGame.makePiece(ChessGame.KING, row, 5, isWhite); // Queen - piece = ChessGame.makePiece(ChessGame.pieces.queen, 8, 5, false); - ChessGame.pieces.queen.white = piece; + piece = ChessGame.makePiece(ChessGame.QUEEN, row, 4, isWhite); // Bishop - piece = ChessGame.makePiece(ChessGame.pieces.bishop, 8, 3, false); - ChessGame.pieces.bishop.white.push(piece); - piece = ChessGame.makePiece(ChessGame.pieces.bishop, 8, 6, false); - ChessGame.pieces.bishop.white.push(piece); + piece = ChessGame.makePiece(ChessGame.BISHOP, row, 3, isWhite); + piece = ChessGame.makePiece(ChessGame.BISHOP, row, 6, isWhite); // Knight - piece = ChessGame.makePiece(ChessGame.pieces.knight, 8, 2, false); - ChessGame.pieces.knight.white.push(piece); - piece = ChessGame.makePiece(ChessGame.pieces.knight, 8, 7, false); - ChessGame.pieces.knight.white.push(piece); + piece = ChessGame.makePiece(ChessGame.KNIGHT, row, 2, isWhite); + piece = ChessGame.makePiece(ChessGame.KNIGHT, row, 7, isWhite); // Rook - piece = ChessGame.makePiece(ChessGame.pieces.rook, 8, 1, false); - ChessGame.pieces.rook.white.push(piece); - piece = ChessGame.makePiece(ChessGame.pieces.rook, 8, 8, false); - ChessGame.pieces.rook.white.push(piece); - for(var j = 1; j <= ChessGame.BOARD_SIZE; j++) { - piece = ChessGame.makePiece(ChessGame.pieces.pawn, 7, j, false); - ChessGame.pieces.pawn.black.push(piece); + piece = ChessGame.makePiece(ChessGame.ROOK, row, 1, isWhite); + piece = ChessGame.makePiece(ChessGame.ROOK, row, 8, isWhite); + for(var j = 1; j <= 8; j++) { + piece = ChessGame.makePiece(ChessGame.PAWN, row - 1, j, isWhite); + } + + var metadataString = ChessGame.buildMetadataString(); + for (i in ChessGame.pieces) { + ChessGame.pieces[i].updateMetadata(metadataString); } } ChessGame.scriptStarting = function() { print("playChess.js started"); + gamePosition = Vec3.sum(MyAvatar.position, + Vec3.multiplyQbyV(MyAvatar.orientation, + { x: 0, y: 0, z: -1 })); ChessGame.buildBoard(); } @@ -250,15 +230,13 @@ ChessGame.scriptEnding = function() { delete ChessGame.board; // Cleaning up pieces - for(var i in ChessGame.pieces.all) { - ChessGame.pieces.all[i].cleanup(); + for(var i in ChessGame.pieces) { + ChessGame.pieces[i].cleanup(); } delete ChessGame.pieces; print("playChess.js finished"); } - -Script.update.connect(ChessGame.update) Script.scriptEnding.connect(ChessGame.scriptEnding); ChessGame.scriptStarting(); \ No newline at end of file From 16e243aec5bb9d13647beba6d7a79a7e87193ed6 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 12 Nov 2014 17:19:16 -0800 Subject: [PATCH 14/94] typo --- examples/playChess.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/playChess.js b/examples/playChess.js index ecfe1d12ae..cb60467492 100644 --- a/examples/playChess.js +++ b/examples/playChess.js @@ -124,8 +124,9 @@ ChessGame.Piece = (function(position, dimensions, url, rotation) { rotation: rotation, dimensions: this.dimensions, modelURL: url, + script: "https://s3.amazonaws.com/hifi-public/scripts/entityScripts/chessPiece.js" //script: "https://s3-us-west-1.amazonaws.com/highfidelity-dev/scripts/chessPiece.js" - script: "file:/Users/clement/hifi/examples/entityScripts/chessPiece.js" + //script: "file:/Users/clement/hifi/examples/entityScripts/chessPiece.js" } this.entity = null; }); @@ -156,7 +157,7 @@ ChessGame.makePiece = function(piece, i, j, isWhite) { return piece; } -ChessGame.buildMetaDataString = function() { +ChessGame.buildMetadataString = function() { var metadataObject = { gamePosition: gamePosition, gameSize: gameSize From 2498fd11a3017a1591c274abef03a2c8a201e672 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 13 Nov 2014 10:22:45 -0800 Subject: [PATCH 15/94] Preload sounds / use hash injector options --- examples/entityScripts/chessPiece.js | 33 ++++++++++++++++------------ 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/examples/entityScripts/chessPiece.js b/examples/entityScripts/chessPiece.js index 13d36d28fb..39b4784849 100644 --- a/examples/entityScripts/chessPiece.js +++ b/examples/entityScripts/chessPiece.js @@ -1,6 +1,7 @@ (function(){ this.GRID_POSITION = { x: 1, y: 1, z: 1 }; this.GRID_SIZE = 1.0; + this.metadata = null; this.sound = null; this.entityID = null; this.properties = null; @@ -34,7 +35,7 @@ var i = Math.floor(relative.x / tileSize); var j = Math.floor(relative.z / tileSize); i = Math.min(Math.max(1, i), 8); - j = Math.min(Math.max(0, j), 9); + j = Math.min(Math.max(1, j), 8); relative.x = (i + 0.5) * tileSize; relative.z = (j + 0.5) * tileSize; @@ -53,33 +54,37 @@ this.sound = new Sound("http://public.highfidelity.io/sounds/Footsteps/FootstepW3Left-12db.wav"); } } + this.playSound = function() { - var options = new AudioInjectionOptions(); - options.position = this.properties.position; - options.volume = 0.5; - Audio.playSound(this.sound, options); + if (this.sound.downloaded) { + Audio.playSound(this.sound, { position: this.properties.position }); + } } this.getMetadata = function() { - var metadataObject = JSON.parse(this.properties.animationURL); - if (metadataObject.gamePosition) { - this.GRID_POSITION = metadataObject.gamePosition; - } - if (metadataObject.gameSize) { - this.GRID_SIZE = metadataObject.gameSize; + if (this.properties.animationURL !== "") { + var metadataObject = JSON.parse(this.properties.animationURL); + if (metadataObject.gamePosition) { + this.GRID_POSITION = metadataObject.gamePosition; + } + if (metadataObject.gameSize) { + this.GRID_SIZE = metadataObject.gameSize; + } } } - this.clickDownOnEntity = function(entityID, mouseEvent){ + this.preload = function() { this.maybeDownloadSound(); + } + this.clickDownOnEntity = function(entityID, mouseEvent) { this.updateProperties(entityID); this.getMetadata(); this.updatePosition(mouseEvent); }; - this.holdingClickOnEntity = function(entityID, mouseEvent){ + this.holdingClickOnEntity = function(entityID, mouseEvent) { this.updateProperties(entityID); this.updatePosition(mouseEvent); }; - this.clickReleaseOnEntity = function(entityID, mouseEvent){ + this.clickReleaseOnEntity = function(entityID, mouseEvent) { this.updateProperties(entityID); this.updatePosition(mouseEvent); this.snapToGrid(); From ce0cb9fdc7e7e0c3823ea4f6dba4fd84ada4e428 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 13 Nov 2014 11:34:38 -0800 Subject: [PATCH 16/94] Better move / start of auto move dead piece --- examples/entityScripts/chessPiece.js | 85 +++++++++++++++++++++------- 1 file changed, 65 insertions(+), 20 deletions(-) diff --git a/examples/entityScripts/chessPiece.js b/examples/entityScripts/chessPiece.js index 39b4784849..17b186d396 100644 --- a/examples/entityScripts/chessPiece.js +++ b/examples/entityScripts/chessPiece.js @@ -5,10 +5,12 @@ this.sound = null; this.entityID = null; this.properties = null; + this.startingTile = null; + this.pieces = new Array(); + this.updateProperties = function(entityID) { if (this.entityID === null) { this.entityID = entityID; - print("entityID=" + JSON.stringify(this.entityID)); } if (!entityID.isKnownID || this.entityID.id !== entityID.id) { print("Something is very wrong: Bailing!"); @@ -19,27 +21,40 @@ print("Unknown entityID " + this.entityID.id + " should be self.") } } + this.updatePosition = function(mouseEvent) { var pickRay = Camera.computePickRay(mouseEvent.x, mouseEvent.y) var upVector = { x: 0, y: 1, z: 0 }; var intersection = this.rayPlaneIntersection(pickRay.origin, pickRay.direction, this.properties.position, upVector); + if (this.isOutsideGrid(this.getIndexPosition(intersection))) { + intersection = this.getAbsolutePosition(this.startingTile); + } Entities.editEntity(this.entityID, { position: intersection }); + //this.moveDeadPiece(); + } + this.isOutsideGrid = function(pos) { + return !(pos.i >= 0 && pos.j >= 0 && pos.i <= 9 && pos.j <= 9); + } + this.getIndexPosition = function(position) { + var tileSize = this.GRID_SIZE / 10.0; + var relative = Vec3.subtract(position, this.GRID_POSITION); + return { + i: Math.floor(relative.x / tileSize), + j: Math.floor(relative.z / tileSize) + } + } + this.getAbsolutePosition = function(pos) { + var tileSize = this.GRID_SIZE / 10.0; + var relative = Vec3.subtract(this.properties.position, this.GRID_POSITION); + relative.x = (pos.i + 0.5) * tileSize; + relative.z = (pos.j + 0.5) * tileSize; + + return Vec3.sum(this.GRID_POSITION, relative); } this.snapToGrid = function() { - var position = this.GRID_POSITION; - var size = this.GRID_SIZE; - var tileSize = size / 10.0; - - var relative = Vec3.subtract(this.properties.position, position); - var i = Math.floor(relative.x / tileSize); - var j = Math.floor(relative.z / tileSize); - i = Math.min(Math.max(1, i), 8); - j = Math.min(Math.max(1, j), 8); - - relative.x = (i + 0.5) * tileSize; - relative.z = (j + 0.5) * tileSize; - var finalPos = Vec3.sum(position, relative); + var pos = this.getIndexPosition(this.properties.position); + var finalPos = this.getAbsolutePosition((this.isOutsideGrid(pos)) ? this.startingTile : pos); Entities.editEntity(this.entityID, { position: finalPos }); } // Pr, Vr are respectively the Ray's Point of origin and Vector director @@ -56,8 +71,9 @@ } this.playSound = function() { - if (this.sound.downloaded) { + if (this.sound !== null && this.sound.downloaded) { Audio.playSound(this.sound, { position: this.properties.position }); + print("playing sound"); } } this.getMetadata = function() { @@ -69,6 +85,36 @@ if (metadataObject.gameSize) { this.GRID_SIZE = metadataObject.gameSize; } + if (metadataObject.pieces) { + this.pieces = metadataObject.pieces; + } + } + } + + + this.grab = function(mouseEvent) { + this.startingTile = this.getIndexPosition(this.properties.position); + this.updatePosition(mouseEvent); + } + this.move = function(mouseEvent) { + this.updatePosition(mouseEvent); + } + this.release = function(mouseEvent) { + this.updatePosition(mouseEvent); + this.snapToGrid(); + + this.playSound(); + } + this.moveDeadPiece = function() { + var myPos = this.getIndexPosition(this.properties.position); + for (var i = 0; i < this.pieces.length; i++) { + if (this.pieces[i].id != this.entityID.id) { + var piecePos = this.getIndexPosition(Entities.getEntityProperties(this.pieces[i]).position); + if (myPos.i === piecePos.i && myPos.j === piecePos.j) { + Entities.editEntity(this.pieces[i], { position: this.getAbsolutePosition({ i: 0, j: 0 })}); + break; + } + } } } @@ -76,18 +122,17 @@ this.maybeDownloadSound(); } this.clickDownOnEntity = function(entityID, mouseEvent) { + this.maybeDownloadSound(); this.updateProperties(entityID); this.getMetadata(); - this.updatePosition(mouseEvent); + this.grab(mouseEvent); }; this.holdingClickOnEntity = function(entityID, mouseEvent) { this.updateProperties(entityID); - this.updatePosition(mouseEvent); + this.move(mouseEvent); }; this.clickReleaseOnEntity = function(entityID, mouseEvent) { this.updateProperties(entityID); - this.updatePosition(mouseEvent); - this.snapToGrid(); - this.playSound(); + this.release(mouseEvent); }; }) \ No newline at end of file From ac34db14aa2e530b8349e8f01f5e092197c1f527 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 13 Nov 2014 11:35:14 -0800 Subject: [PATCH 17/94] Send pieces ID --- examples/playChess.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/examples/playChess.js b/examples/playChess.js index cb60467492..1ed836b7ca 100644 --- a/examples/playChess.js +++ b/examples/playChess.js @@ -124,9 +124,9 @@ ChessGame.Piece = (function(position, dimensions, url, rotation) { rotation: rotation, dimensions: this.dimensions, modelURL: url, - script: "https://s3.amazonaws.com/hifi-public/scripts/entityScripts/chessPiece.js" + //script: "https://s3.amazonaws.com/hifi-public/scripts/entityScripts/chessPiece.js" //script: "https://s3-us-west-1.amazonaws.com/highfidelity-dev/scripts/chessPiece.js" - //script: "file:/Users/clement/hifi/examples/entityScripts/chessPiece.js" + script: "file:/Users/clement/hifi/examples/entityScripts/chessPiece.js" } this.entity = null; }); @@ -160,8 +160,12 @@ ChessGame.makePiece = function(piece, i, j, isWhite) { ChessGame.buildMetadataString = function() { var metadataObject = { gamePosition: gamePosition, - gameSize: gameSize + gameSize: gameSize, + pieces: new Array() }; + for (i in ChessGame.pieces) { + metadataObject.pieces.push(ChessGame.pieces[i].entity); + } return JSON.stringify(metadataObject); } From 388332966d6a11b49f50fc996da8b07df3be0c74 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Thu, 13 Nov 2014 22:22:46 +0100 Subject: [PATCH 18/94] Added cloning methods to Grid3DOverlay Added example script for cloning overlays (TODO: SpriteBillboard fix cloning of in example) --- examples/clonedOverlaysExample.js | 278 ++++++++++++++++++++ interface/src/ui/overlays/Grid3DOverlay.cpp | 12 + interface/src/ui/overlays/Grid3DOverlay.h | 4 + 3 files changed, 294 insertions(+) create mode 100644 examples/clonedOverlaysExample.js diff --git a/examples/clonedOverlaysExample.js b/examples/clonedOverlaysExample.js new file mode 100644 index 0000000000..aacca939f6 --- /dev/null +++ b/examples/clonedOverlaysExample.js @@ -0,0 +1,278 @@ +// +// clonedOverlaysExample.js +// examples +// +// Created by Thijs Wenker on 11/13/14. +// Copyright 2014 High Fidelity, Inc. +// +// Demonstrates the use of the overlay cloning function. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +// Image source: https://openclipart.org/detail/447/christmas-tree-by-theresaknott (heavily edited by Maximillian Merlin) +const CHRISTMAS_TREE_SPRITES_URL = "http://test.thoys.nl/hifi/images/santa/christmas-tree.svg"; + +// Image source: http://opengameart.org/content/santa-claus (CC-BY 3.0) +const SANTA_SPRITES_URL = "http://test.thoys.nl/hifi/images/santa/Santa.png"; + +Array.prototype.contains = function(obj) { + var i = this.length; + while (i--) { + if (this[i] === obj) { + return true; + } + } + return false; +}; + +function getRandomPosAroundMyAvatar(radius) { + return {x: MyAvatar.position.x + Math.floor(Math.random() * radius * 2) - radius, y: MyAvatar.position.y, z: MyAvatar.position.z + Math.floor(Math.random() * radius * 2) - radius}; +} + +function SpriteBillboard(sprite_properties) { + var _this = this; + // set properties + this.overlay_properties = {}; + this.sprite_properties = sprite_properties; + this.edited_overlay_properties = []; + this.defaultFPS = 30; + this.currentSequence = ""; + this.sequenceIndex = 0; + this.sequenceFPS = 0; + this.sequenceStepToNext = false; + this.sequenceTimer = null; + this.prevSequenceIndex = -1; + this.sequenceX = 0; + this.sequenceY = 0; + + this.spriteSize = {x: 0, y: 0, width: 32, height: 64}; + + this.editedProperty = function(prop_name) { + if (!_this.edited_overlay_properties.contains(prop_name)) { + _this.edited_overlay_properties.push(prop_name); + } + }; + + // function definitions + this.getPosition = function() { + return _this.overlay_properties.position ? + _this.overlay_properties.position : {x: 0, y: 0, z: 0}; + }; + + this.setPosition = function(newPosition) { + this.overlay_properties.position = newPosition; + this.editedProperty("position"); + return _this; + }; + + this.setURL = function(url) { + this.overlay_properties.url = url; + this.editedProperty("url"); + return _this; + } + + this.setAlpha = function(alpha) { + this.overlay_properties.alpha = alpha; + this.editedProperty("alpha"); + return _this; + } + + this.setScale = function(scale) { + this.overlay_properties.scale = scale; + this.editedProperty("scale"); + return _this; + } + + this.setSpriteSize = function(spriteSize) { + this.overlay_properties.subImage = spriteSize; + this.editedProperty("subImage"); + return _this; + }; + + this.setSpriteXIndex = function(x_index) { + _this.sequenceX = x_index; + _this.overlay_properties.subImage.x = x_index * _this.overlay_properties.subImage.width; + _this.editedProperty("subImage"); + return _this; + } + + this.setSpriteYIndex = function(y_index) { + _this.sequenceY = y_index; + _this.overlay_properties.subImage.y = y_index * _this.overlay_properties.subImage.height; + _this.editedProperty("subImage"); + return _this; + } + + this.editOverlay = function(properties) { + for (var key in properties) { + _this.overlay_properties[attrname] = properties[key]; + _this.editedProperty(key); + } + return _this; + }; + + this.commitChanges = function() { + var changed_properties = {}; + for (var i = 0; i < _this.edited_overlay_properties.length; i++) { + var key = _this.edited_overlay_properties[i]; + changed_properties[key] = _this.overlay_properties[key]; + } + if (Object.keys(changed_properties).length === 0) { + return; + } + Overlays.editOverlay(_this.overlay, changed_properties); + _this.edited_overlay_properties = []; + }; + + this._renderFrame = function() { + var currentSequence = _this.sprite_properties.sequences[_this.currentSequence]; + var currentItem = currentSequence[_this.sequenceIndex]; + var indexChanged = _this.sequenceIndex != _this.prevSequenceIndex; + var canMoveToNext = true; + _this.prevSequenceIndex = _this.sequenceIndex; + if (indexChanged) { + if (currentItem.loop != undefined) { + _this.loopSequence = currentItem.loop; + } + if (currentItem.fps !== undefined && currentItem.fps != _this.sequenceFPS) { + _this.startSequenceTimerFPS(currentItem.fps); + } + if (currentItem.step_to_next !== undefined) { + _this.sequenceStepToNext = currentItem.step_to_next; + } + if (currentItem.x !== undefined) { + _this.setSpriteXIndex(currentItem.x); + } + if (currentItem.y !== undefined) { + _this.setSpriteYIndex(currentItem.y); + } + + if (_this.sequenceStepToNext) { + canMoveToNext = false; + } + } + _this.prevSequenceIndex = _this.sequenceIndex; + var nextIndex = (_this.sequenceIndex + 1) % currentSequence.length; + var nextItem = currentSequence[nextIndex]; + var nextX = nextItem.x != undefined ? nextItem.x : _this.sequenceX; + var nextY = nextItem.Y != undefined ? nextItem.Y : _this.sequenceY; + + if (_this.sequenceStepToNext && !indexChanged) { + var XMoveNext = true; + var YMoveNext = true; + if (Math.abs(nextX - _this.sequenceX) > 1) { + _this.setSpriteXIndex(_this.sequenceX + (nextX > _this.sequenceX ? 1 : -1)); + XMoveNext = Math.abs(nextX - _this.sequenceX) == 1; + } + if (Math.abs(nextY - _this.sequenceY) > 1) { + _this.setSpriteYIndex(_this.sequenceY + (nextY > _this.sequenceY ? 1 : -1)); + YMoveNext = Math.abs(nextY - _this.sequenceY) == 1; + } + canMoveToNext = XMoveNext && YMoveNext; + + } + if (canMoveToNext) { + _this.sequenceIndex = nextIndex; + } + _this.commitChanges(); + + }; + + this.clone = function() { + var clone = {}; + clone.prototype = this.prototype; + for (property in this) { + clone[property] = this[property]; + } + return clone; + }; + + this.startSequenceTimerFPS = function(fps) { + _this.sequenceFPS = fps; + if (_this.sequenceTimer != null) { + Script.clearInterval(_this.sequenceTimer); + } + _this.sequenceTimer = Script.setInterval(_this._renderFrame, 1000 / fps); + } + + this.start = function(sequenceName) { + this.currentSequence = sequenceName; + this.sequenceFPS = this.defaultFPS; + this.startSequenceTimerFPS(this.defaultFPS); + }; + + if (this.sprite_properties.url !== undefined) { + this.setURL(this.sprite_properties.url); + } + + if (this.sprite_properties.sprite_size !== undefined) { + this.setSpriteSize(this.sprite_properties.sprite_size); + } + + if (this.sprite_properties.scale !== undefined) { + this.setScale(this.sprite_properties.scale); + } + + if (this.sprite_properties.alpha !== undefined) { + this.setAlpha(this.sprite_properties.alpha); + } + + if (this.sprite_properties.position !== undefined) { + this.setPosition(this.sprite_properties.position); + } + + // set the overlay + this.overlay = Overlays.addOverlay("billboard", this.overlay_properties); + this.new_properties = {}; + + if (this.sprite_properties.startup_sequence != undefined) { + this.start(this.sprite_properties.startup_sequence); + } + + Script.scriptEnding.connect(function () { + if (_this.sequenceTimer != null) { + Script.clearInterval(_this.sequenceTimer); + } + Overlays.deleteOverlay(_this.overlay); + }); +} + +var chrismastree = new SpriteBillboard({ + position: getRandomPosAroundMyAvatar(6), + url: CHRISTMAS_TREE_SPRITES_URL, + sprite_size: {x: 0, y: 0, width: 250.000, height: 357.626}, + scale: 6, + alpha: 1, + sequences: {"idle": [{x: 0, y: 0, step_to_next: true, fps: 3}, {x: 3, step_to_next: false}]}, + startup_sequence: "idle" +}); + +var santa = new SpriteBillboard({ + position: getRandomPosAroundMyAvatar(6), + url: SANTA_SPRITES_URL, + loop: true, + sprite_size: {x: 0, y: 0, width: 64, height: 72}, + scale: 4, + alpha: 1, + sequences: { + "walk_left": [{x: 2, y: 0, step_to_next: true, fps: 4}, {x: 10, step_to_next: false}], + "walk_right": [{x: 10, y: 1, step_to_next: true, fps: 4}, {x: 2, step_to_next: false}], + }, + startup_sequence: "walk_left" +}); + +var santa = new SpriteBillboard({ + position: getRandomPosAroundMyAvatar(6), + url: SANTA_SPRITES_URL, + loop: true, + sprite_size: {x: 0, y: 0, width: 64, height: 72}, + scale: 4, + alpha: 1, + sequences: { + "walk_left": [{x: 2, y: 0, step_to_next: true, fps: 4}, {x: 10, step_to_next: false}], + "walk_right": [{x: 10, y: 1, step_to_next: true, fps: 4}, {x: 2, step_to_next: false}], + }, + startup_sequence: "walk_right" +}); \ No newline at end of file diff --git a/interface/src/ui/overlays/Grid3DOverlay.cpp b/interface/src/ui/overlays/Grid3DOverlay.cpp index c628199fe3..be99612a1a 100644 --- a/interface/src/ui/overlays/Grid3DOverlay.cpp +++ b/interface/src/ui/overlays/Grid3DOverlay.cpp @@ -116,3 +116,15 @@ void Grid3DOverlay::setProperties(const QScriptValue& properties) { _majorGridEvery = properties.property("majorGridEvery").toVariant().toInt(); } } + +Grid3DOverlay* Grid3DOverlay::createClone() { + Grid3DOverlay* clone = new Grid3DOverlay(); + writeToClone(clone); + return clone; +} + +void Grid3DOverlay::writeToClone(Grid3DOverlay* clone) { + Base3DOverlay::writeToClone(clone); + clone->_minorGridWidth = _minorGridWidth; + clone->_majorGridEvery = _majorGridEvery; +} diff --git a/interface/src/ui/overlays/Grid3DOverlay.h b/interface/src/ui/overlays/Grid3DOverlay.h index b1675f15d7..319f298b2c 100644 --- a/interface/src/ui/overlays/Grid3DOverlay.h +++ b/interface/src/ui/overlays/Grid3DOverlay.h @@ -34,7 +34,11 @@ public: virtual void render(RenderArgs* args); virtual void setProperties(const QScriptValue& properties); + virtual Grid3DOverlay* createClone(); + private: + virtual void writeToClone(Grid3DOverlay* clone); + float _minorGridWidth; int _majorGridEvery; From cbb3d463b697b958366dacb2f8100fd691aaaed9 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Thu, 13 Nov 2014 23:29:05 +0100 Subject: [PATCH 19/94] Fixed Overlays::isLoaded which did not to find my just created overlay. --- interface/src/ui/overlays/Overlays.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 6702c88125..00b16cf5b7 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -359,14 +359,14 @@ void RayToOverlayIntersectionResultFromScriptValue(const QScriptValue& object, R bool Overlays::isLoaded(unsigned int id) { QReadLocker lock(&_lock); - Overlay* overlay = _overlays2D.value(id); - if (!overlay) { - _overlays3D.value(id); - } - if (!overlay) { + Overlay* thisOverlay = NULL; + if (_overlays2D.contains(id)) { + thisOverlay = _overlays2D[id]; + } else if (_overlays3D.contains(id)) { + thisOverlay = _overlays3D[id]; + } else { return false; // not found } - - return overlay->isLoaded(); + return thisOverlay->isLoaded(); } From e964741e30d6ab49e39b003a1443f627733a924f Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Fri, 14 Nov 2014 00:01:51 +0100 Subject: [PATCH 20/94] added OverlayPreloader and made a bunch of clones --- examples/clonedOverlaysExample.js | 204 ++++++++++++++++-------------- 1 file changed, 110 insertions(+), 94 deletions(-) diff --git a/examples/clonedOverlaysExample.js b/examples/clonedOverlaysExample.js index aacca939f6..7aea048175 100644 --- a/examples/clonedOverlaysExample.js +++ b/examples/clonedOverlaysExample.js @@ -11,6 +11,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +const NUM_OF_TREES = 40; +const NUM_OF_SANTAS = 20; + // Image source: https://openclipart.org/detail/447/christmas-tree-by-theresaknott (heavily edited by Maximillian Merlin) const CHRISTMAS_TREE_SPRITES_URL = "http://test.thoys.nl/hifi/images/santa/christmas-tree.svg"; @@ -27,13 +30,31 @@ Array.prototype.contains = function(obj) { return false; }; -function getRandomPosAroundMyAvatar(radius) { - return {x: MyAvatar.position.x + Math.floor(Math.random() * radius * 2) - radius, y: MyAvatar.position.y, z: MyAvatar.position.z + Math.floor(Math.random() * radius * 2) - radius}; +function getRandomPosAroundMyAvatar(radius, height_offset) { + if (height_offset == undefined) { + height_offset = 0; + } + return {x: MyAvatar.position.x + Math.floor(Math.random() * radius * 2) - radius, y: MyAvatar.position.y + height_offset, z: MyAvatar.position.z + Math.floor(Math.random() * radius * 2) - radius}; } -function SpriteBillboard(sprite_properties) { +function OverlayPreloader(overlay_type, overlay_properties, loaded_callback) { var _this = this; + this.loaded_callback = loaded_callback; + this.overlay = Overlays.addOverlay(overlay_type, overlay_properties); + this.timer = null; + this.timer = Script.setInterval(function() { + if (Overlays.isLoaded(_this.overlay)) { + Script.clearInterval(_this.timer); + _this.loaded_callback(); + } + }, 100); +} + +function SpriteBillboard(sprite_properties, overlay) { + var _this = this; + // set properties + this.overlay = overlay; this.overlay_properties = {}; this.sprite_properties = sprite_properties; this.edited_overlay_properties = []; @@ -41,11 +62,11 @@ function SpriteBillboard(sprite_properties) { this.currentSequence = ""; this.sequenceIndex = 0; this.sequenceFPS = 0; - this.sequenceStepToNext = false; + this.sequenceStepToNext = false; this.sequenceTimer = null; this.prevSequenceIndex = -1; - this.sequenceX = 0; - this.sequenceY = 0; + this.sequenceX = 0; + this.sequenceY = 0; this.spriteSize = {x: 0, y: 0, width: 32, height: 64}; @@ -67,12 +88,6 @@ function SpriteBillboard(sprite_properties) { return _this; }; - this.setURL = function(url) { - this.overlay_properties.url = url; - this.editedProperty("url"); - return _this; - } - this.setAlpha = function(alpha) { this.overlay_properties.alpha = alpha; this.editedProperty("alpha"); @@ -92,14 +107,14 @@ function SpriteBillboard(sprite_properties) { }; this.setSpriteXIndex = function(x_index) { - _this.sequenceX = x_index; + _this.sequenceX = x_index; _this.overlay_properties.subImage.x = x_index * _this.overlay_properties.subImage.width; _this.editedProperty("subImage"); return _this; } this.setSpriteYIndex = function(y_index) { - _this.sequenceY = y_index; + _this.sequenceY = y_index; _this.overlay_properties.subImage.y = y_index * _this.overlay_properties.subImage.height; _this.editedProperty("subImage"); return _this; @@ -107,8 +122,8 @@ function SpriteBillboard(sprite_properties) { this.editOverlay = function(properties) { for (var key in properties) { - _this.overlay_properties[attrname] = properties[key]; - _this.editedProperty(key); + _this.overlay_properties[attrname] = properties[key]; + _this.editedProperty(key); } return _this; }; @@ -119,9 +134,9 @@ function SpriteBillboard(sprite_properties) { var key = _this.edited_overlay_properties[i]; changed_properties[key] = _this.overlay_properties[key]; } - if (Object.keys(changed_properties).length === 0) { - return; - } + if (Object.keys(changed_properties).length === 0) { + return; + } Overlays.editOverlay(_this.overlay, changed_properties); _this.edited_overlay_properties = []; }; @@ -129,9 +144,9 @@ function SpriteBillboard(sprite_properties) { this._renderFrame = function() { var currentSequence = _this.sprite_properties.sequences[_this.currentSequence]; var currentItem = currentSequence[_this.sequenceIndex]; - var indexChanged = _this.sequenceIndex != _this.prevSequenceIndex; - var canMoveToNext = true; - _this.prevSequenceIndex = _this.sequenceIndex; + var indexChanged = _this.sequenceIndex != _this.prevSequenceIndex; + var canMoveToNext = true; + _this.prevSequenceIndex = _this.sequenceIndex; if (indexChanged) { if (currentItem.loop != undefined) { _this.loopSequence = currentItem.loop; @@ -139,45 +154,44 @@ function SpriteBillboard(sprite_properties) { if (currentItem.fps !== undefined && currentItem.fps != _this.sequenceFPS) { _this.startSequenceTimerFPS(currentItem.fps); } - if (currentItem.step_to_next !== undefined) { - _this.sequenceStepToNext = currentItem.step_to_next; - } - if (currentItem.x !== undefined) { - _this.setSpriteXIndex(currentItem.x); - } - if (currentItem.y !== undefined) { - _this.setSpriteYIndex(currentItem.y); - } - - if (_this.sequenceStepToNext) { - canMoveToNext = false; - } + if (currentItem.step_to_next !== undefined) { + _this.sequenceStepToNext = currentItem.step_to_next; + } + if (currentItem.x !== undefined) { + _this.setSpriteXIndex(currentItem.x); + } + if (currentItem.y !== undefined) { + _this.setSpriteYIndex(currentItem.y); + } + + if (_this.sequenceStepToNext) { + canMoveToNext = false; + } } - _this.prevSequenceIndex = _this.sequenceIndex; + _this.prevSequenceIndex = _this.sequenceIndex; var nextIndex = (_this.sequenceIndex + 1) % currentSequence.length; var nextItem = currentSequence[nextIndex]; - var nextX = nextItem.x != undefined ? nextItem.x : _this.sequenceX; - var nextY = nextItem.Y != undefined ? nextItem.Y : _this.sequenceY; - - if (_this.sequenceStepToNext && !indexChanged) { - var XMoveNext = true; - var YMoveNext = true; - if (Math.abs(nextX - _this.sequenceX) > 1) { - _this.setSpriteXIndex(_this.sequenceX + (nextX > _this.sequenceX ? 1 : -1)); - XMoveNext = Math.abs(nextX - _this.sequenceX) == 1; + var nextX = nextItem.x != undefined ? nextItem.x : _this.sequenceX; + var nextY = nextItem.Y != undefined ? nextItem.Y : _this.sequenceY; + + if (_this.sequenceStepToNext && !indexChanged) { + var XMoveNext = true; + var YMoveNext = true; + if (Math.abs(nextX - _this.sequenceX) > 1) { + _this.setSpriteXIndex(_this.sequenceX + (nextX > _this.sequenceX ? 1 : -1)); + XMoveNext = Math.abs(nextX - _this.sequenceX) == 1; } - if (Math.abs(nextY - _this.sequenceY) > 1) { - _this.setSpriteYIndex(_this.sequenceY + (nextY > _this.sequenceY ? 1 : -1)); - YMoveNext = Math.abs(nextY - _this.sequenceY) == 1; + if (Math.abs(nextY - _this.sequenceY) > 1) { + _this.setSpriteYIndex(_this.sequenceY + (nextY > _this.sequenceY ? 1 : -1)); + YMoveNext = Math.abs(nextY - _this.sequenceY) == 1; } - canMoveToNext = XMoveNext && YMoveNext; - - } - if (canMoveToNext) { + canMoveToNext = XMoveNext && YMoveNext; + } + if (canMoveToNext) { _this.sequenceIndex = nextIndex; - } - _this.commitChanges(); - + } + _this.commitChanges(); + }; this.clone = function() { @@ -223,14 +237,12 @@ function SpriteBillboard(sprite_properties) { this.setPosition(this.sprite_properties.position); } - // set the overlay - this.overlay = Overlays.addOverlay("billboard", this.overlay_properties); - this.new_properties = {}; + _this.commitChanges(); if (this.sprite_properties.startup_sequence != undefined) { this.start(this.sprite_properties.startup_sequence); } - + Script.scriptEnding.connect(function () { if (_this.sequenceTimer != null) { Script.clearInterval(_this.sequenceTimer); @@ -239,40 +251,44 @@ function SpriteBillboard(sprite_properties) { }); } -var chrismastree = new SpriteBillboard({ - position: getRandomPosAroundMyAvatar(6), - url: CHRISTMAS_TREE_SPRITES_URL, - sprite_size: {x: 0, y: 0, width: 250.000, height: 357.626}, - scale: 6, - alpha: 1, - sequences: {"idle": [{x: 0, y: 0, step_to_next: true, fps: 3}, {x: 3, step_to_next: false}]}, - startup_sequence: "idle" -}); +var christmastree_loader = null; +christmastree_loader = new OverlayPreloader("billboard", + {url: CHRISTMAS_TREE_SPRITES_URL, alpha: 0}, function() { + for (var i = 0; i < NUM_OF_TREES; i++) { + var clonedOverlay = Overlays.cloneOverlay(christmastree_loader.overlay); + new SpriteBillboard({ + position: getRandomPosAroundMyAvatar(20), + sprite_size: {x: 0, y: 0, width: 250.000, height: 357.626}, + scale: 6, + alpha: 1, + sequences: {"idle": [{x: 0, y: 0, step_to_next: true, fps: 3}, {x: 3, step_to_next: false}]}, + startup_sequence: "idle" + }, clonedOverlay); + } + } +); -var santa = new SpriteBillboard({ - position: getRandomPosAroundMyAvatar(6), - url: SANTA_SPRITES_URL, - loop: true, - sprite_size: {x: 0, y: 0, width: 64, height: 72}, - scale: 4, - alpha: 1, - sequences: { - "walk_left": [{x: 2, y: 0, step_to_next: true, fps: 4}, {x: 10, step_to_next: false}], - "walk_right": [{x: 10, y: 1, step_to_next: true, fps: 4}, {x: 2, step_to_next: false}], - }, - startup_sequence: "walk_left" -}); +var santa_loader = null; +santa_loader = new OverlayPreloader("billboard", + {url: SANTA_SPRITES_URL, alpha: 0}, function() { + for (var i = 0; i < NUM_OF_SANTAS; i++) { + var clonedOverlay = Overlays.cloneOverlay(santa_loader.overlay); + new SpriteBillboard({ + position: getRandomPosAroundMyAvatar(18, -1), + sprite_size: {x: 0, y: 0, width: 64, height: 72}, + scale: 4, + alpha: 1, + sequences: { + "walk_left": [{x: 2, y: 0, step_to_next: true, fps: 4}, {x: 10, step_to_next: false}], + "walk_right": [{x: 10, y: 1, step_to_next: true, fps: 4}, {x: 2, step_to_next: false}], + }, + startup_sequence: (i % 2 == 0) ? "walk_left" : "walk_right" + }, clonedOverlay); + } + } +); -var santa = new SpriteBillboard({ - position: getRandomPosAroundMyAvatar(6), - url: SANTA_SPRITES_URL, - loop: true, - sprite_size: {x: 0, y: 0, width: 64, height: 72}, - scale: 4, - alpha: 1, - sequences: { - "walk_left": [{x: 2, y: 0, step_to_next: true, fps: 4}, {x: 10, step_to_next: false}], - "walk_right": [{x: 10, y: 1, step_to_next: true, fps: 4}, {x: 2, step_to_next: false}], - }, - startup_sequence: "walk_right" -}); \ No newline at end of file +Script.scriptEnding.connect(function () { + Overlays.deleteOverlay(christmastree_loader.overlay); + Overlays.deleteOverlay(santa_loader.overlay); +}); From 4254d38cddbb3cc18d0807d7180a4f8903a9985d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 13 Nov 2014 17:40:21 -0800 Subject: [PATCH 21/94] Update buttons to grid tool --- examples/html/gridControls.html | 145 +++++++++++++------------------- examples/html/style.css | 95 +++++++++++++++++++++ examples/libraries/gridTool.js | 9 ++ 3 files changed, 163 insertions(+), 86 deletions(-) create mode 100644 examples/html/style.css diff --git a/examples/html/gridControls.html b/examples/html/gridControls.html index e7bf1cdf8c..4cb935e600 100644 --- a/examples/html/gridControls.html +++ b/examples/html/gridControls.html @@ -1,5 +1,6 @@ + -
-
+
- -
-
-
- +
+ + + +
- -
-
-
- +
+ + + +
- -
-
-
- +
+ + + +
- -
-
-
- +
+ + + +
- -
-
-
+
+ + + + +
+ +
+ + +
+ +
+ + + +
+
+ + +
diff --git a/examples/html/style.css b/examples/html/style.css new file mode 100644 index 0000000000..1625fd094f --- /dev/null +++ b/examples/html/style.css @@ -0,0 +1,95 @@ +* { +} + +body { + margin: 0; + padding: 0; + + background-color: #efefef; + font-family: Sans-Serif; + font-size: 12px; + + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +input { + line-height: 2; +} + +.input-left { + display: inline-block; + width: 20px; +} + +.color-box { + display: inline-block; + width: 20px; + height: 20px; + border: 1px solid black; + margin: 2px; + cursor: pointer; +} + +.color-box.highlight { + width: 18px; + height: 18px; + border: 2px solid black; +} + +.section-header { + background: #AAA; + border-bottom: 1px solid #CCC; + background-color: #333333; + color: #999; + padding: 4px; +} + +.section-header label { + font-weight: bold; +} + +.multi-property-section { +} +.property-section { + display: block; + margin: 10 10; + height: 30px; +} + +.property-section label { + font-weight: bold; + vertical-align: middle; +} + +.property-section span { + float: right; +} + +.grid-section { + border-top: 1px solid #DDD; + background-color: #efefef; +} + +input[type=button] { + cursor: pointer; + background-color: #608e96; + border-color: #608e96; + border-radius: 5px; + padding: 5px 10px; + border: 0; + color: #fff; + font-weight: bold; + margin: 0 2px; + margin-top: 5px; + font-size: .9em; +} + +input.coord { + width: 6em; + height: 2em; +} diff --git a/examples/libraries/gridTool.js b/examples/libraries/gridTool.js index 34e25d6733..04547a6918 100644 --- a/examples/libraries/gridTool.js +++ b/examples/libraries/gridTool.js @@ -174,6 +174,15 @@ GridTool = function(opts) { for (var i = 0; i < listeners.length; i++) { listeners[i](data); } + } else if (data.type == "action") { + var action = data.action; + if (action == "moveToAvatar") { + grid.setPosition(MyAvatar.position); + } else if (action == "moveToSelection") { + var newPosition = selectionManager.worldPosition; + newPosition = Vec3.subtract(newPosition, { x: 0, y: selectionManager.worldDimensions.y * 0.5, z: 0 }); + grid.setPosition(newPosition); + } } }); From 49563dbff7a9c90844e8c837de015f38649a880d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 13 Nov 2014 17:41:51 -0800 Subject: [PATCH 22/94] Add entityProperties tool window --- examples/html/entityProperties.html | 561 ++++++++++++++++++++++ examples/libraries/entitySelectionTool.js | 15 +- examples/newEditEntities.js | 35 +- 3 files changed, 605 insertions(+), 6 deletions(-) create mode 100644 examples/html/entityProperties.html diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html new file mode 100644 index 0000000000..408e83198f --- /dev/null +++ b/examples/html/entityProperties.html @@ -0,0 +1,561 @@ + + + + + + +
+ +
+
+
+ + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + X + Y + Z + +
+ +
+ + + X + Y + Z + +
+ +
+ + + + +
+
+ + + + +
+
+ + + + +
+ +
+ + + X + Y + Z + +
+
+ + + + +
+
+ + + Pitch + Roll + Yaw + +
+
+ + + + +
+ +
+ + + X + Y + Z + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + +
+ + +
+
+ + + Red + Green + Blue + +
+
+ + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + +
+
+ + + + +
+
+ + + Red + Green + Blue + +
+
+ + + Red + Green + Blue + +
+
+ + + Red + Green + Blue + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+
+ + + diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index 22f75cb187..6733ccaf39 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -23,12 +23,13 @@ SelectionManager = (function() { that.savedProperties = {}; - that.eventListener = null; that.selections = []; // These are selections that don't have a known ID yet that.pendingSelections = []; var pendingSelectionTimer = null; + var listeners = []; + that.localRotation = Quat.fromPitchYawRollDegrees(0, 0, 0); that.localPosition = { x: 0, y: 0, z: 0 }; that.localDimensions = { x: 0, y: 0, z: 0 }; @@ -46,8 +47,8 @@ SelectionManager = (function() { } }; - that.setEventListener = function(func) { - that.eventListener = func; + that.addEventListener = function(func) { + listeners.push(func); }; that.hasSelection = function() { @@ -187,8 +188,12 @@ SelectionManager = (function() { SelectionDisplay.setSpaceMode(SPACE_WORLD); } - if (that.eventListener) { - that.eventListener(); + for (var i = 0; i < listeners.length; i++) { + try { + listeners[i](); + } catch (e) { + print("got exception"); + } } }; diff --git a/examples/newEditEntities.js b/examples/newEditEntities.js index 68e0d0c146..f5af558fa1 100644 --- a/examples/newEditEntities.js +++ b/examples/newEditEntities.js @@ -39,7 +39,7 @@ Script.include("libraries/gridTool.js"); var grid = Grid(); gridTool = GridTool({ horizontalGrid: grid }); -selectionManager.setEventListener(selectionDisplay.updateHandles); +selectionManager.addEventListener(selectionDisplay.updateHandles); var windowDimensions = Controller.getViewportDimensions(); var toolIconUrl = HIFI_PUBLIC_BUCKET + "images/tools/"; @@ -908,3 +908,36 @@ function pushCommandForSelections(createdEntityData, deletedEntityData) { } UndoStack.pushCommand(applyEntityProperties, undoData, applyEntityProperties, redoData); } + +PropertiesTool = function(opts) { + var that = {}; + + var url = Script.resolvePath('html/entityProperties.html'); + var webView = new WebWindow('Entity Properties', url, 200, 280); + + webView.setVisible(true); + + selectionManager.addEventListener(function() { + data = { + type: 'update', + }; + if (selectionManager.hasSelection()) { + data.properties = Entities.getEntityProperties(selectionManager.selections[0]); + } + webView.eventBridge.emitScriptEvent(JSON.stringify(data)); + }); + + webView.eventBridge.webEventReceived.connect(function(data) { + print(data); + data = JSON.parse(data); + if (data.type == "update") { + Entities.editEntity(selectionManager.selections[0], data.properties); + selectionManager._update(); + } + }); + + return that; +}; + +propertiesTool = PropertiesTool(); + From 55612cc5962f6c2b30445b1a6fdbe6938d4d6f47 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 13 Nov 2014 17:46:20 -0800 Subject: [PATCH 23/94] Add title to WebWindowClass --- examples/libraries/gridTool.js | 2 +- interface/src/scripting/WebWindowClass.cpp | 8 +++++--- interface/src/scripting/WebWindowClass.h | 2 +- interface/src/scripting/WindowScriptingInterface.cpp | 4 ++-- interface/src/scripting/WindowScriptingInterface.h | 2 +- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/examples/libraries/gridTool.js b/examples/libraries/gridTool.js index 04547a6918..9945fe3e98 100644 --- a/examples/libraries/gridTool.js +++ b/examples/libraries/gridTool.js @@ -159,7 +159,7 @@ GridTool = function(opts) { var listeners = []; var url = Script.resolvePath('html/gridControls.html'); - var webView = new WebWindow(url, 200, 280); + var webView = new WebWindow('Grid', url, 200, 280); horizontalGrid.addListener(function(data) { webView.eventBridge.emitScriptEvent(JSON.stringify(data)); diff --git a/interface/src/scripting/WebWindowClass.cpp b/interface/src/scripting/WebWindowClass.cpp index d280d8eecf..01a7983098 100644 --- a/interface/src/scripting/WebWindowClass.cpp +++ b/interface/src/scripting/WebWindowClass.cpp @@ -28,7 +28,8 @@ void ScriptEventBridge::emitScriptEvent(const QString& data) { emit scriptEventReceived(data); } -WebWindowClass::WebWindowClass(const QString& url, int width, int height) + +WebWindowClass::WebWindowClass(const QString& title, const QString& url, int width, int height) : QObject(NULL), _window(new QWidget(NULL, Qt::Tool)), _eventBridge(new ScriptEventBridge(this)) { @@ -59,8 +60,9 @@ QScriptValue WebWindowClass::constructor(QScriptContext* context, QScriptEngine* QMetaObject::invokeMethod(WindowScriptingInterface::getInstance(), "doCreateWebWindow", Qt::BlockingQueuedConnection, Q_RETURN_ARG(WebWindowClass*, retVal), Q_ARG(const QString&, file), - Q_ARG(int, context->argument(1).toInteger()), - Q_ARG(int, context->argument(2).toInteger())); + Q_ARG(QString, context->argument(1).toString()), + Q_ARG(int, context->argument(2).toInteger()), + Q_ARG(int, context->argument(3).toInteger())); connect(engine, &QScriptEngine::destroyed, retVal, &WebWindowClass::deleteLater); diff --git a/interface/src/scripting/WebWindowClass.h b/interface/src/scripting/WebWindowClass.h index 7b77299774..928b8fb23b 100644 --- a/interface/src/scripting/WebWindowClass.h +++ b/interface/src/scripting/WebWindowClass.h @@ -34,7 +34,7 @@ class WebWindowClass : public QObject { Q_OBJECT Q_PROPERTY(QObject* eventBridge READ getEventBridge) public: - WebWindowClass(const QString& url, int width, int height); + WebWindowClass(const QString& title, const QString& url, int width, int height); ~WebWindowClass(); static QScriptValue constructor(QScriptContext* context, QScriptEngine* engine); diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index 8c2066f253..8a79cad6e1 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -34,8 +34,8 @@ WindowScriptingInterface::WindowScriptingInterface() : { } -WebWindowClass* WindowScriptingInterface::doCreateWebWindow(const QString& url, int width, int height) { - return new WebWindowClass(url, width, height); +WebWindowClass* WindowScriptingInterface::doCreateWebWindow(const QString& title, const QString& url, int width, int height) { + return new WebWindowClass(title, url, width, height); } QScriptValue WindowScriptingInterface::hasFocus() { diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index 5529d31efd..0b320f23a1 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -78,7 +78,7 @@ private slots: void nonBlockingFormAccepted() { _nonBlockingFormActive = false; _formResult = QDialog::Accepted; emit nonBlockingFormClosed(); } void nonBlockingFormRejected() { _nonBlockingFormActive = false; _formResult = QDialog::Rejected; emit nonBlockingFormClosed(); } - WebWindowClass* doCreateWebWindow(const QString& url, int width, int height); + WebWindowClass* doCreateWebWindow(const QString& title, const QString& url, int width, int height); private: WindowScriptingInterface(); From 03f155bcd8d5f9405563cae5fd43bafa3f2b0779 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 13 Nov 2014 17:47:02 -0800 Subject: [PATCH 24/94] Add tool window --- interface/src/Application.cpp | 4 ++++ interface/src/Application.h | 4 ++++ interface/src/Menu.cpp | 11 +++++++++++ interface/src/Menu.h | 2 ++ interface/src/scripting/WebWindowClass.cpp | 17 ++++++++++------- interface/src/scripting/WebWindowClass.h | 2 +- 6 files changed, 32 insertions(+), 8 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b1c969b66f..3958011ba2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -370,6 +370,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : // enable mouse tracking; otherwise, we only get drag events _glWidget->setMouseTracking(true); + _toolWindow = new QMainWindow(); + _toolWindow->setWindowFlags(_toolWindow->windowFlags() | Qt::WindowStaysOnTopHint); + _toolWindow->setWindowTitle("Tools"); + // initialization continues in initializeGL when OpenGL context is ready // Tell our voxel edit sender about our known jurisdictions diff --git a/interface/src/Application.h b/interface/src/Application.h index eee2581e2e..a6f94f0ab5 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -244,6 +244,8 @@ public: void lockOctreeSceneStats() { _octreeSceneStatsLock.lockForRead(); } void unlockOctreeSceneStats() { _octreeSceneStatsLock.unlock(); } + QMainWindow* getToolWindow() { return _toolWindow ; } + GeometryCache* getGeometryCache() { return &_geometryCache; } AnimationCache* getAnimationCache() { return &_animationCache; } TextureCache* getTextureCache() { return &_textureCache; } @@ -457,6 +459,8 @@ private: MainWindow* _window; GLCanvas* _glWidget; // our GLCanvas has a couple extra features + QMainWindow* _toolWindow; + BandwidthMeter _bandwidthMeter; QThread* _nodeThread; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index cd074805b6..fd0db559ff 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -247,6 +247,12 @@ Menu::Menu() : _chatWindow = new ChatWindow(Application::getInstance()->getWindow()); #endif + addActionToQMenuAndActionHash(toolsMenu, + MenuOption::ToolWindow, + Qt::CTRL | Qt::ALT | Qt::Key_T, + this, + SLOT(toggleToolWindow())); + addActionToQMenuAndActionHash(toolsMenu, MenuOption::Console, Qt::CTRL | Qt::ALT | Qt::Key_J, @@ -1461,6 +1467,11 @@ void Menu::toggleConsole() { _jsConsole->setVisible(!_jsConsole->isVisible()); } +void Menu::toggleToolWindow() { + QMainWindow* toolWindow = Application::getInstance()->getToolWindow(); + toolWindow->setVisible(!toolWindow->isVisible()); +} + void Menu::audioMuteToggled() { QAction *muteAction = _actionHash.value(MenuOption::MuteAudio); if (muteAction) { diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 8af91ccae4..badd79759f 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -224,6 +224,7 @@ private slots: void showScriptEditor(); void showChat(); void toggleConsole(); + void toggleToolWindow(); void toggleChat(); void audioMuteToggled(); void displayNameLocationResponse(const QString& errorString); @@ -491,6 +492,7 @@ namespace MenuOption { const QString StringHair = "String Hair"; const QString SuppressShortTimings = "Suppress Timings Less than 10ms"; const QString TestPing = "Test Ping"; + const QString ToolWindow = "Tool Window"; const QString TransmitterDrive = "Transmitter Drive"; const QString TurnWithHead = "Turn using Head"; const QString UploadAttachment = "Upload Attachment Model"; diff --git a/interface/src/scripting/WebWindowClass.cpp b/interface/src/scripting/WebWindowClass.cpp index 01a7983098..1645fe2f56 100644 --- a/interface/src/scripting/WebWindowClass.cpp +++ b/interface/src/scripting/WebWindowClass.cpp @@ -11,9 +11,13 @@ #include #include +#include +#include #include #include +#include +#include "Application.h" #include "WindowScriptingInterface.h" #include "WebWindowClass.h" @@ -31,18 +35,17 @@ void ScriptEventBridge::emitScriptEvent(const QString& data) { WebWindowClass::WebWindowClass(const QString& title, const QString& url, int width, int height) : QObject(NULL), - _window(new QWidget(NULL, Qt::Tool)), _eventBridge(new ScriptEventBridge(this)) { + QMainWindow* toolWindow = Application::getInstance()->getToolWindow(); + + _window = new QDockWidget(title, toolWindow); QWebView* webView = new QWebView(_window); webView->page()->mainFrame()->addToJavaScriptWindowObject("EventBridge", _eventBridge); webView->setUrl(url); - QVBoxLayout* layout = new QVBoxLayout(_window); - _window->setLayout(layout); - layout->addWidget(webView); - layout->setSpacing(0); - layout->setContentsMargins(0, 0, 0, 0); - _window->setGeometry(0, 0, width, height); + _window->setWidget(webView); + + toolWindow->addDockWidget(Qt::RightDockWidgetArea, _window); connect(this, &WebWindowClass::destroyed, _window, &QWidget::deleteLater); } diff --git a/interface/src/scripting/WebWindowClass.h b/interface/src/scripting/WebWindowClass.h index 928b8fb23b..c37b7aea48 100644 --- a/interface/src/scripting/WebWindowClass.h +++ b/interface/src/scripting/WebWindowClass.h @@ -44,7 +44,7 @@ public slots: ScriptEventBridge* getEventBridge() const { return _eventBridge; } private: - QWidget* _window; + QDockWidget* _window; ScriptEventBridge* _eventBridge; }; From a6f027e33aadc9bc22cd1ac74b2f6003ebd7b354 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 13 Nov 2014 18:31:32 -0800 Subject: [PATCH 25/94] Fix entity edit grid not hiding when disabling tools --- examples/libraries/gridTool.js | 8 +++++++- examples/newEditEntities.js | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/examples/libraries/gridTool.js b/examples/libraries/gridTool.js index 9945fe3e98..d8b84babf9 100644 --- a/examples/libraries/gridTool.js +++ b/examples/libraries/gridTool.js @@ -31,6 +31,7 @@ Grid = function(opts) { that.getMajorIncrement = function() { return minorGridSpacing * majorGridEvery; }; that.visible = false; + that.enabled = false; that.getOrigin = function() { return origin; @@ -38,6 +39,11 @@ Grid = function(opts) { that.getSnapToGrid = function() { return snapToGrid; }; + that.setEnabled = function(enabled) { + that.enabled = enabled; + updateGrid(); + } + that.setVisible = function(visible, noUpdate) { that.visible = visible; updateGrid(); @@ -127,7 +133,7 @@ Grid = function(opts) { function updateGrid() { Overlays.editOverlay(gridOverlay, { position: { x: origin.y, y: origin.y, z: -origin.y }, - visible: that.visible, + visible: that.visible && that.enabled, minorGridWidth: minorGridSpacing, majorGridEvery: majorGridEvery, color: gridColor, diff --git a/examples/newEditEntities.js b/examples/newEditEntities.js index 8a2c8a636d..0b8eebfee5 100644 --- a/examples/newEditEntities.js +++ b/examples/newEditEntities.js @@ -272,11 +272,13 @@ var toolBar = (function () { isActive = !isActive; if (!isActive) { gridTool.setVisible(false); + grid.setEnabled(false); selectionManager.clearSelections(); cameraManager.disable(); } else { cameraManager.enable(); gridTool.setVisible(Menu.isOptionChecked(MENU_GRID_TOOL_ENABLED)); + grid.setEnabled(true); } return true; } From 3658d65028c57945cef9d6376f3814d90fe24a02 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 13 Nov 2014 20:02:19 -0800 Subject: [PATCH 26/94] Remove grid tool from menu --- examples/newEditEntities.js | 25 ++++++++++------------ interface/src/scripting/WebWindowClass.cpp | 13 +++++------ interface/src/scripting/WebWindowClass.h | 2 +- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/examples/newEditEntities.js b/examples/newEditEntities.js index 0b8eebfee5..cc3c0fceda 100644 --- a/examples/newEditEntities.js +++ b/examples/newEditEntities.js @@ -55,13 +55,11 @@ var wantEntityGlow = false; var SPAWN_DISTANCE = 1; var DEFAULT_DIMENSION = 0.20; -var MENU_GRID_TOOL_ENABLED = 'Grid Tool'; var MENU_INSPECT_TOOL_ENABLED = "Inspect Tool"; var MENU_EASE_ON_FOCUS = "Ease Orientation on Focus"; var SETTING_INSPECT_TOOL_ENABLED = "inspectToolEnabled"; var SETTING_EASE_ON_FOCUS = "cameraEaseOnFocus"; -var SETTING_GRID_TOOL_ENABLED = 'GridToolEnabled'; var modelURLs = [ HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Alder.fbx", @@ -273,12 +271,14 @@ var toolBar = (function () { if (!isActive) { gridTool.setVisible(false); grid.setEnabled(false); + propertiesTool.setVisible(false); selectionManager.clearSelections(); cameraManager.disable(); } else { cameraManager.enable(); - gridTool.setVisible(Menu.isOptionChecked(MENU_GRID_TOOL_ENABLED)); + gridTool.setVisible(true); grid.setEnabled(true); + propertiesTool.setVisible(true); } return true; } @@ -610,10 +610,6 @@ function setupModelMenus() { Menu.addMenuItem({ menuName: "File", menuItemName: "Import Models", shortcutKey: "CTRL+META+I", afterItem: "Export Models" }); Menu.addMenuItem({ menuName: "Developer", menuItemName: "Debug Ryans Rotation Problems", isCheckable: true }); - Menu.addMenuItem({ menuName: "View", menuItemName: MENU_GRID_TOOL_ENABLED, afterItem: "Edit Entities Help...", isCheckable: true, - isChecked: Settings.getValue(SETTING_GRID_TOOL_ENABLED) == 'true'}); - Menu.addMenuItem({ menuName: "View", menuItemName: MENU_INSPECT_TOOL_ENABLED, afterItem: MENU_GRID_TOOL_ENABLED, - isCheckable: true, isChecked: Settings.getValue(SETTING_INSPECT_TOOL_ENABLED) == "true" }); Menu.addMenuItem({ menuName: "View", menuItemName: MENU_EASE_ON_FOCUS, afterItem: MENU_INSPECT_TOOL_ENABLED, isCheckable: true, isChecked: Settings.getValue(SETTING_EASE_ON_FOCUS) == "true" }); } @@ -638,8 +634,6 @@ function cleanupModelMenus() { Menu.removeMenuItem("File", "Import Models"); Menu.removeMenuItem("Developer", "Debug Ryans Rotation Problems"); - Settings.setValue(SETTING_GRID_TOOL_ENABLED, Menu.isOptionChecked(MENU_GRID_TOOL_ENABLED)); - Menu.removeMenuItem("View", MENU_GRID_TOOL_ENABLED); Menu.removeMenuItem("View", MENU_INSPECT_TOOL_ENABLED); Menu.removeMenuItem("View", MENU_EASE_ON_FOCUS); } @@ -751,10 +745,6 @@ function handeMenuEvent(menuItem) { } } else if (menuItem == "Import Models") { modelImporter.doImport(); - } else if (menuItem == MENU_GRID_TOOL_ENABLED) { - if (isActive) { - gridTool.setVisible(Menu.isOptionChecked(MENU_GRID_TOOL_ENABLED)); - } } tooltip.show(false); } @@ -920,7 +910,14 @@ PropertiesTool = function(opts) { var url = Script.resolvePath('html/entityProperties.html'); var webView = new WebWindow('Entity Properties', url, 200, 280); - webView.setVisible(true); + var visible = false; + + webView.setVisible(visible); + + that.setVisible = function(newVisible) { + visible = newVisible; + webView.setVisible(visible); + }; selectionManager.addEventListener(function() { data = { diff --git a/interface/src/scripting/WebWindowClass.cpp b/interface/src/scripting/WebWindowClass.cpp index 1645fe2f56..7f11dbe580 100644 --- a/interface/src/scripting/WebWindowClass.cpp +++ b/interface/src/scripting/WebWindowClass.cpp @@ -39,22 +39,23 @@ WebWindowClass::WebWindowClass(const QString& title, const QString& url, int wid QMainWindow* toolWindow = Application::getInstance()->getToolWindow(); - _window = new QDockWidget(title, toolWindow); - QWebView* webView = new QWebView(_window); + _dockWidget = new QDockWidget(title, toolWindow); + _dockWidget->setFeatures(QDockWidget::DockWidgetMovable); + QWebView* webView = new QWebView(_dockWidget); webView->page()->mainFrame()->addToJavaScriptWindowObject("EventBridge", _eventBridge); webView->setUrl(url); - _window->setWidget(webView); + _dockWidget->setWidget(webView); - toolWindow->addDockWidget(Qt::RightDockWidgetArea, _window); + toolWindow->addDockWidget(Qt::RightDockWidgetArea, _dockWidget); - connect(this, &WebWindowClass::destroyed, _window, &QWidget::deleteLater); + connect(this, &WebWindowClass::destroyed, _dockWidget, &QWidget::deleteLater); } WebWindowClass::~WebWindowClass() { } void WebWindowClass::setVisible(bool visible) { - QMetaObject::invokeMethod(_window, "setVisible", Qt::BlockingQueuedConnection, Q_ARG(bool, visible)); + QMetaObject::invokeMethod(_dockWidget, "setVisible", Qt::BlockingQueuedConnection, Q_ARG(bool, visible)); } QScriptValue WebWindowClass::constructor(QScriptContext* context, QScriptEngine* engine) { diff --git a/interface/src/scripting/WebWindowClass.h b/interface/src/scripting/WebWindowClass.h index c37b7aea48..ae0d14ae06 100644 --- a/interface/src/scripting/WebWindowClass.h +++ b/interface/src/scripting/WebWindowClass.h @@ -44,7 +44,7 @@ public slots: ScriptEventBridge* getEventBridge() const { return _eventBridge; } private: - QDockWidget* _window; + QDockWidget* _dockWidget; ScriptEventBridge* _eventBridge; }; From 11058355a01e98c3ac0e26c917224f4b7ae164bb Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Nov 2014 09:55:32 -0800 Subject: [PATCH 27/94] implement aboutToFinish for persist thread to allow final save before shutdown --- assignment-client/src/octree/OctreeServer.cpp | 3 ++ libraries/entities/src/EntityTree.cpp | 2 - libraries/octree/src/OctreePersistThread.cpp | 38 +++++++++++++------ libraries/octree/src/OctreePersistThread.h | 4 ++ 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 26cf94269b..34378effd3 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -1197,6 +1197,9 @@ void OctreeServer::aboutToFinish() { qDebug() << qPrintable(_safeServerName) << "server about to finish while node still connected node:" << *node; forceNodeShutdown(node); } + if (_persistThread) { + _persistThread->aboutToFinish(); + } qDebug() << qPrintable(_safeServerName) << "server ENDING about to finish..."; } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index bc2823e15c..73957ad077 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1089,7 +1089,6 @@ bool DebugOperator::preRecursion(OctreeElement* element) { } void EntityTree::dumpTree() { - // First, look for the existing entity in the tree.. DebugOperator theOperator; recurseTreeWithOperator(&theOperator); } @@ -1107,7 +1106,6 @@ bool PruneOperator::postRecursion(OctreeElement* element) { } void EntityTree::pruneTree() { - // First, look for the existing entity in the tree.. PruneOperator theOperator; recurseTreeWithOperator(&theOperator); } diff --git a/libraries/octree/src/OctreePersistThread.cpp b/libraries/octree/src/OctreePersistThread.cpp index 406681c2c5..dd81b3ff4d 100644 --- a/libraries/octree/src/OctreePersistThread.cpp +++ b/libraries/octree/src/OctreePersistThread.cpp @@ -78,19 +78,33 @@ bool OctreePersistThread::process() { quint64 intervalToCheck = _persistInterval * MSECS_TO_USECS; if (sinceLastSave > intervalToCheck) { - // check the dirty bit and persist here... - _lastCheck = usecTimestampNow(); - if (_tree->isDirty()) { - qDebug() << "pruning Octree before saving..."; - _tree->pruneTree(); - qDebug() << "DONE pruning Octree before saving..."; - - qDebug() << "saving Octree to file " << _filename << "..."; - _tree->writeToSVOFile(_filename.toLocal8Bit().constData()); - _tree->clearDirtyBit(); // tree is clean after saving - qDebug("DONE saving Octree to file..."); - } + _lastCheck = now; + persistOperation(); } } return isStillRunning(); // keep running till they terminate us } + + +void OctreePersistThread::aboutToFinish() { + qDebug() << "Persist thread about to finish..."; + persistOperation(); + qDebug() << "Persist thread done with about to finish..."; +} + +void OctreePersistThread::persistOperation() { + if (_tree->isDirty()) { + _tree->lockForWrite(); + { + qDebug() << "pruning Octree before saving..."; + _tree->pruneTree(); + qDebug() << "DONE pruning Octree before saving..."; + } + _tree->unlock(); + + qDebug() << "saving Octree to file " << _filename << "..."; + _tree->writeToSVOFile(_filename.toLocal8Bit().constData()); + _tree->clearDirtyBit(); // tree is clean after saving + qDebug("DONE saving Octree to file..."); + } +} diff --git a/libraries/octree/src/OctreePersistThread.h b/libraries/octree/src/OctreePersistThread.h index 2f86320b2e..c4bccd55b9 100644 --- a/libraries/octree/src/OctreePersistThread.h +++ b/libraries/octree/src/OctreePersistThread.h @@ -29,12 +29,16 @@ public: bool isInitialLoadComplete() const { return _initialLoadComplete; } quint64 getLoadElapsedTime() const { return _loadTimeUSecs; } + void aboutToFinish(); /// call this to inform the persist thread that the owner is about to finish to support final persist + signals: void loadCompleted(); protected: /// Implements generic processing behavior for this thread. virtual bool process(); + + void persistOperation(); private: Octree* _tree; QString _filename; From 642f436fbaf65358fe5e444fa2033bf52ea4f3ad Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 14 Nov 2014 09:56:36 -0800 Subject: [PATCH 28/94] first draft of factorizing the rendering traversal for both sides in stereo --- interface/src/Application.cpp | 14 +- interface/src/Application.h | 14 +- interface/src/devices/TV3DManager.cpp | 4 +- interface/src/entities/EntityTreeRenderer.cpp | 8 +- interface/src/entities/EntityTreeRenderer.h | 2 +- interface/src/renderer/Model.cpp | 248 +++++++++--------- interface/src/renderer/Model.h | 4 +- interface/src/ui/overlays/Overlays.cpp | 6 +- interface/src/ui/overlays/Overlays.h | 2 +- libraries/octree/src/OctreeRenderer.cpp | 4 +- libraries/octree/src/OctreeRenderer.h | 2 +- libraries/shared/src/RenderArgs.h | 2 + 12 files changed, 168 insertions(+), 142 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f11ac14d40..83a4a46403 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -723,7 +723,7 @@ void Application::paintGL() { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); - displaySide(*whichCamera); + displaySide(RenderContext(*whichCamera)); glPopMatrix(); if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { @@ -2873,12 +2873,16 @@ QImage Application::renderAvatarBillboard() { return image; } -void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { +//void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { +void Application::displaySide(RenderContext& renderContext) { PROFILE_RANGE(__FUNCTION__); PerformanceTimer perfTimer("display"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()"); // transform by eye offset + Camera& whichCamera = renderContext._whichCamera; + bool selfAvatarOnly = renderContext._selfAvatarOnly; + // load the view frustum loadViewFrustum(whichCamera, _displayViewFrustum); @@ -3020,7 +3024,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { PerformanceTimer perfTimer("entities"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... entities..."); - _entities.render(); + _entities.render(RenderArgs::DEFAULT_RENDER_MODE, renderContext._renderSide); } // render JS/scriptable overlays @@ -3265,7 +3269,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { _shadowMatrices[i] = glm::transpose(glm::transpose(_shadowMatrices[i]) * glm::translate(-delta)); } - displaySide(_mirrorCamera, true); + displaySide(RenderContext(_mirrorCamera, true)); // restore absolute translations _myAvatar->getSkeletonModel().setTranslation(absoluteSkeletonTranslation); @@ -3279,7 +3283,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { _shadowMatrices[i] = savedShadowMatrices[i]; } } else { - displaySide(_mirrorCamera, true); + displaySide(RenderContext(_mirrorCamera, true)); } glPopMatrix(); diff --git a/interface/src/Application.h b/interface/src/Application.h index cba39317a5..2cea413dd4 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -262,7 +262,19 @@ public: QImage renderAvatarBillboard(); - void displaySide(Camera& whichCamera, bool selfAvatarOnly = false); + struct RenderContext { + Camera& _whichCamera; + bool _selfAvatarOnly; + RenderArgs::RenderSide _renderSide; + + RenderContext(Camera& whichCamera, bool selfAvatarOnly = false, RenderArgs::RenderSide renderSide = RenderArgs::MONO) : + _whichCamera(whichCamera), + _selfAvatarOnly(selfAvatarOnly), + _renderSide(renderSide) { + } + }; + // void displaySide(Camera& whichCamera, bool selfAvatarOnly = false); + void displaySide(RenderContext& renderContext); /// Stores the current modelview matrix as the untranslated view matrix to use for transforms and the supplied vector as /// the view matrix translation. diff --git a/interface/src/devices/TV3DManager.cpp b/interface/src/devices/TV3DManager.cpp index 872f4ce7e6..bd0129f88e 100644 --- a/interface/src/devices/TV3DManager.cpp +++ b/interface/src/devices/TV3DManager.cpp @@ -126,7 +126,7 @@ void TV3DManager::display(Camera& whichCamera) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - Application::getInstance()->displaySide(whichCamera); + Application::getInstance()->displaySide(Application::RenderContext(whichCamera, false, RenderArgs::STEREO_LEFT)); if (displayOverlays) { applicationOverlay.displayOverlayTexture3DTV(whichCamera, _aspect, fov); @@ -156,7 +156,7 @@ void TV3DManager::display(Camera& whichCamera) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - Application::getInstance()->displaySide(whichCamera); + Application::getInstance()->displaySide(Application::RenderContext(whichCamera, false, RenderArgs::STEREO_RIGHT)); if (displayOverlays) { applicationOverlay.displayOverlayTexture3DTV(whichCamera, _aspect, fov); diff --git a/interface/src/entities/EntityTreeRenderer.cpp b/interface/src/entities/EntityTreeRenderer.cpp index 99e4916c62..2209a992c1 100644 --- a/interface/src/entities/EntityTreeRenderer.cpp +++ b/interface/src/entities/EntityTreeRenderer.cpp @@ -252,15 +252,15 @@ void EntityTreeRenderer::checkEnterLeaveEntities() { } } -void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode) { +void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { bool dontRenderAsScene = !Menu::getInstance()->isOptionChecked(MenuOption::RenderEntitiesAsScene); if (dontRenderAsScene) { - OctreeRenderer::render(renderMode); + OctreeRenderer::render(renderMode, renderSide); } else { if (_tree) { - Model::startScene(); - RenderArgs args = { this, _viewFrustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode, + Model::startScene(renderSide); + RenderArgs args = { this, _viewFrustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode, renderSide, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; _tree->lockForRead(); _tree->recurseTreeWithOperation(renderOperation, &args); diff --git a/interface/src/entities/EntityTreeRenderer.h b/interface/src/entities/EntityTreeRenderer.h index 7c1c81b6c9..66107b368a 100644 --- a/interface/src/entities/EntityTreeRenderer.h +++ b/interface/src/entities/EntityTreeRenderer.h @@ -56,7 +56,7 @@ public: void processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode); virtual void init(); - virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE); + virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::RenderSide renderSide = RenderArgs::MONO); virtual const FBXGeometry* getGeometryForEntity(const EntityItem* entityItem); virtual const Model* getModelForEntityItem(const EntityItem* entityItem); diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index c007f44f2e..71e42d32e0 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1484,8 +1484,10 @@ void Model::deleteGeometry() { // Scene rendering support QVector Model::_modelsInScene; gpu::Batch Model::_sceneRenderBatch; -void Model::startScene() { - _modelsInScene.clear(); +void Model::startScene(RenderArgs::RenderSide renderSide) { + if (renderSide != RenderArgs::STEREO_RIGHT) { + _modelsInScene.clear(); + } } void Model::setupBatchTransform(gpu::Batch& batch) { @@ -1503,146 +1505,152 @@ void Model::setupBatchTransform(gpu::Batch& batch) { void Model::endScene(RenderMode mode, RenderArgs* args) { PROFILE_RANGE(__FUNCTION__); - // Let's introduce a gpu::Batch to capture all the calls to the graphics api - _sceneRenderBatch.clear(); - gpu::Batch& batch = _sceneRenderBatch; + auto side = RenderArgs::MONO; + if (args) side = args->_renderSide; - GLBATCH(glDisable)(GL_COLOR_MATERIAL); + if (side != RenderArgs::STEREO_RIGHT) { + // Let's introduce a gpu::Batch to capture all the calls to the graphics api + _sceneRenderBatch.clear(); + gpu::Batch& batch = _sceneRenderBatch; + + GLBATCH(glDisable)(GL_COLOR_MATERIAL); + + if (mode == DIFFUSE_RENDER_MODE || mode == NORMAL_RENDER_MODE) { + GLBATCH(glDisable)(GL_CULL_FACE); + } else { + GLBATCH(glEnable)(GL_CULL_FACE); + if (mode == SHADOW_RENDER_MODE) { + GLBATCH(glCullFace)(GL_FRONT); + } + } + + // render opaque meshes with alpha testing + + GLBATCH(glDisable)(GL_BLEND); + GLBATCH(glEnable)(GL_ALPHA_TEST); - if (mode == DIFFUSE_RENDER_MODE || mode == NORMAL_RENDER_MODE) { - GLBATCH(glDisable)(GL_CULL_FACE); - } else { - GLBATCH(glEnable)(GL_CULL_FACE); if (mode == SHADOW_RENDER_MODE) { - GLBATCH(glCullFace)(GL_FRONT); + GLBATCH(glAlphaFunc)(GL_EQUAL, 0.0f); } - } - - // render opaque meshes with alpha testing - - GLBATCH(glDisable)(GL_BLEND); - GLBATCH(glEnable)(GL_ALPHA_TEST); - - if (mode == SHADOW_RENDER_MODE) { - GLBATCH(glAlphaFunc)(GL_EQUAL, 0.0f); - } - /*Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers( - mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE, - mode == DEFAULT_RENDER_MODE || mode == NORMAL_RENDER_MODE, - mode == DEFAULT_RENDER_MODE); - */ - { - GLenum buffers[3]; - int bufferCount = 0; - if (mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE) { - buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; + /*Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers( + mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE, + mode == DEFAULT_RENDER_MODE || mode == NORMAL_RENDER_MODE, + mode == DEFAULT_RENDER_MODE); + */ + { + GLenum buffers[3]; + int bufferCount = 0; + if (mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE) { + buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; + } + if (mode == DEFAULT_RENDER_MODE || mode == NORMAL_RENDER_MODE) { + buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; + } + if (mode == DEFAULT_RENDER_MODE) { + buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; + } + GLBATCH(glDrawBuffers)(bufferCount, buffers); } - if (mode == DEFAULT_RENDER_MODE || mode == NORMAL_RENDER_MODE) { + + const float DEFAULT_ALPHA_THRESHOLD = 0.5f; + + int opaqueMeshPartsRendered = 0; + + // now, for each model in the scene, render the mesh portions + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, args); + + // render translucent meshes afterwards + //Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true); + { + GLenum buffers[2]; + int bufferCount = 0; buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; - } - if (mode == DEFAULT_RENDER_MODE) { buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; + GLBATCH(glDrawBuffers)(bufferCount, buffers); } - GLBATCH(glDrawBuffers)(bufferCount, buffers); + + int translucentParts = 0; + const float MOSTLY_OPAQUE_THRESHOLD = 0.75f; + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, true, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, true, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, true, true, args); + + GLBATCH(glDisable)(GL_ALPHA_TEST); + GLBATCH(glEnable)(GL_BLEND); + GLBATCH(glDepthMask)(false); + GLBATCH(glDepthFunc)(GL_LEQUAL); + + //Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true); + { + GLenum buffers[1]; + int bufferCount = 0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; + GLBATCH(glDrawBuffers)(bufferCount, buffers); + } + + if (mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE) { + const float MOSTLY_TRANSPARENT_THRESHOLD = 0.0f; + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, true, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, true, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, true, true, args); + } + + GLBATCH(glDepthMask)(true); + GLBATCH(glDepthFunc)(GL_LESS); + GLBATCH(glDisable)(GL_CULL_FACE); + + if (mode == SHADOW_RENDER_MODE) { + GLBATCH(glCullFace)(GL_BACK); + } + + // deactivate vertex arrays after drawing + GLBATCH(glDisableClientState)(GL_NORMAL_ARRAY); + GLBATCH(glDisableClientState)(GL_VERTEX_ARRAY); + GLBATCH(glDisableClientState)(GL_TEXTURE_COORD_ARRAY); + GLBATCH(glDisableClientState)(GL_COLOR_ARRAY); + GLBATCH(glDisableVertexAttribArray)(gpu::Stream::TANGENT); + GLBATCH(glDisableVertexAttribArray)(gpu::Stream::SKIN_CLUSTER_INDEX); + GLBATCH(glDisableVertexAttribArray)(gpu::Stream::SKIN_CLUSTER_WEIGHT); + + // bind with 0 to switch back to normal operation + GLBATCH(glBindBuffer)(GL_ARRAY_BUFFER, 0); + GLBATCH(glBindBuffer)(GL_ELEMENT_ARRAY_BUFFER, 0); + GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); + if (args) { + args->_translucentMeshPartsRendered = translucentParts; + args->_opaqueMeshPartsRendered = opaqueMeshPartsRendered; } - const float DEFAULT_ALPHA_THRESHOLD = 0.5f; - - int opaqueMeshPartsRendered = 0; - - // now, for each model in the scene, render the mesh portions - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, args); - - // render translucent meshes afterwards - //Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true); - { - GLenum buffers[2]; - int bufferCount = 0; - buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; - buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; - GLBATCH(glDrawBuffers)(bufferCount, buffers); } - int translucentParts = 0; - const float MOSTLY_OPAQUE_THRESHOLD = 0.75f; - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, true, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, true, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, true, true, args); - - GLBATCH(glDisable)(GL_ALPHA_TEST); - GLBATCH(glEnable)(GL_BLEND); - GLBATCH(glDepthMask)(false); - GLBATCH(glDepthFunc)(GL_LEQUAL); - - //Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true); - { - GLenum buffers[1]; - int bufferCount = 0; - buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; - GLBATCH(glDrawBuffers)(bufferCount, buffers); - } - - if (mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE) { - const float MOSTLY_TRANSPARENT_THRESHOLD = 0.0f; - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, true, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, true, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, true, true, args); - } - - GLBATCH(glDepthMask)(true); - GLBATCH(glDepthFunc)(GL_LESS); - GLBATCH(glDisable)(GL_CULL_FACE); - - if (mode == SHADOW_RENDER_MODE) { - GLBATCH(glCullFace)(GL_BACK); - } - - // deactivate vertex arrays after drawing - GLBATCH(glDisableClientState)(GL_NORMAL_ARRAY); - GLBATCH(glDisableClientState)(GL_VERTEX_ARRAY); - GLBATCH(glDisableClientState)(GL_TEXTURE_COORD_ARRAY); - GLBATCH(glDisableClientState)(GL_COLOR_ARRAY); - GLBATCH(glDisableVertexAttribArray)(gpu::Stream::TANGENT); - GLBATCH(glDisableVertexAttribArray)(gpu::Stream::SKIN_CLUSTER_INDEX); - GLBATCH(glDisableVertexAttribArray)(gpu::Stream::SKIN_CLUSTER_WEIGHT); - - // bind with 0 to switch back to normal operation - GLBATCH(glBindBuffer)(GL_ARRAY_BUFFER, 0); - GLBATCH(glBindBuffer)(GL_ELEMENT_ARRAY_BUFFER, 0); - GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); - // Render! { PROFILE_RANGE("render Batch"); - ::gpu::GLBackend::renderBatch(batch); + ::gpu::GLBackend::renderBatch(_sceneRenderBatch); } // restore all the default material settings Application::getInstance()->setupWorldLight(); - if (args) { - args->_translucentMeshPartsRendered = translucentParts; - args->_opaqueMeshPartsRendered = opaqueMeshPartsRendered; - } } bool Model::renderInScene(float alpha, RenderArgs* args) { diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 32c072dc99..4dceb07655 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -31,7 +31,7 @@ class QScriptEngine; class Shape; -class RenderArgs; +#include "RenderArgs.h" class ViewFrustum; @@ -91,7 +91,7 @@ public: bool render(float alpha = 1.0f, RenderMode mode = DEFAULT_RENDER_MODE, RenderArgs* args = NULL); // Scene rendering support - static void startScene(); + static void startScene(RenderArgs::RenderSide renderSide); bool renderInScene(float alpha = 1.0f, RenderArgs* args = NULL); static void endScene(RenderMode mode = DEFAULT_RENDER_MODE, RenderArgs* args = NULL); diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 4bdabcc566..6584fce396 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -84,14 +84,14 @@ void Overlays::render2D() { RenderArgs args = { NULL, Application::getInstance()->getViewFrustum(), Menu::getInstance()->getVoxelSizeScale(), Menu::getInstance()->getBoundaryLevelAdjust(), - RenderArgs::DEFAULT_RENDER_MODE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; foreach(Overlay* thisOverlay, _overlays2D) { thisOverlay->render(&args); } } -void Overlays::render3D(RenderArgs::RenderMode renderMode) { +void Overlays::render3D(RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { QReadLocker lock(&_lock); if (_overlays3D.size() == 0) { return; @@ -106,7 +106,7 @@ void Overlays::render3D(RenderArgs::RenderMode renderMode) { RenderArgs args = { NULL, Application::getInstance()->getViewFrustum(), Menu::getInstance()->getVoxelSizeScale(), Menu::getInstance()->getBoundaryLevelAdjust(), - renderMode, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + renderMode, renderSide, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; foreach(Overlay* thisOverlay, _overlays3D) { diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 66232196f2..31e4ad1ebc 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -39,7 +39,7 @@ public: ~Overlays(); void init(QGLWidget* parent); void update(float deltatime); - void render3D(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE); + void render3D(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::RenderSide renderSide = RenderArgs::MONO); void render2D(); public slots: diff --git a/libraries/octree/src/OctreeRenderer.cpp b/libraries/octree/src/OctreeRenderer.cpp index a8aafbe34d..5bcf49a1a4 100644 --- a/libraries/octree/src/OctreeRenderer.cpp +++ b/libraries/octree/src/OctreeRenderer.cpp @@ -162,8 +162,8 @@ bool OctreeRenderer::renderOperation(OctreeElement* element, void* extraData) { return false; } -void OctreeRenderer::render(RenderArgs::RenderMode renderMode) { - RenderArgs args = { this, _viewFrustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode, +void OctreeRenderer::render(RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { + RenderArgs args = { this, _viewFrustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode, renderSide, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; if (_tree) { _tree->lockForRead(); diff --git a/libraries/octree/src/OctreeRenderer.h b/libraries/octree/src/OctreeRenderer.h index d418467012..e8612b4cb6 100644 --- a/libraries/octree/src/OctreeRenderer.h +++ b/libraries/octree/src/OctreeRenderer.h @@ -52,7 +52,7 @@ public: virtual void init(); /// render the content of the octree - virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE); + virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::RenderSide renderSide = RenderArgs::MONO); ViewFrustum* getViewFrustum() const { return _viewFrustum; } void setViewFrustum(ViewFrustum* viewFrustum) { _viewFrustum = viewFrustum; } diff --git a/libraries/shared/src/RenderArgs.h b/libraries/shared/src/RenderArgs.h index 1ed43f94ad..e447472fee 100644 --- a/libraries/shared/src/RenderArgs.h +++ b/libraries/shared/src/RenderArgs.h @@ -18,12 +18,14 @@ class OctreeRenderer; class RenderArgs { public: enum RenderMode { DEFAULT_RENDER_MODE, SHADOW_RENDER_MODE, DIFFUSE_RENDER_MODE, NORMAL_RENDER_MODE }; + enum RenderSide { MONO, STEREO_LEFT, STEREO_RIGHT }; OctreeRenderer* _renderer; ViewFrustum* _viewFrustum; float _sizeScale; int _boundaryLevelAdjust; RenderMode _renderMode; + RenderSide _renderSide; int _elementsTouched; int _itemsRendered; From 76ae60c5caaa5cd8ddfa9c5bd972bedeaadb937e Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Fri, 14 Nov 2014 19:27:27 +0100 Subject: [PATCH 29/94] fix Ubuntu build --- interface/src/ui/overlays/TextOverlay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/TextOverlay.cpp b/interface/src/ui/overlays/TextOverlay.cpp index 70d82ec28e..19f85aed68 100644 --- a/interface/src/ui/overlays/TextOverlay.cpp +++ b/interface/src/ui/overlays/TextOverlay.cpp @@ -133,7 +133,7 @@ TextOverlay* TextOverlay::createClone() { void TextOverlay::writeToClone(TextOverlay* clone) { Overlay2D::writeToClone(clone); - clone->_text = QString::QString(_text); + clone->_text = _text; clone->_backgroundColor = _backgroundColor; clone->_leftMargin = _leftMargin; clone->_topMargin = _topMargin; From 20fdd6d8117405296b02e7a383630dc95aab0ae4 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 14 Nov 2014 10:31:30 -0800 Subject: [PATCH 30/94] Disable model overlay properties example It causes intermittent crashes in NetworkGeometry::setTextureWithNameToURL() --- examples/overlaysExample.js | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/examples/overlaysExample.js b/examples/overlaysExample.js index 3ab70a0562..0d47f7ca64 100644 --- a/examples/overlaysExample.js +++ b/examples/overlaysExample.js @@ -194,20 +194,23 @@ print("Cube overlay color =\n" + "green: " + cubeColor.green + "\n" + "blue: " + cubeColor.blue ); -var modelOverlayProperties = { - textures: { - filename1: "http://url1", - filename2: "http://url2" - } -} -var modelOverlay = Overlays.addOverlay("model", modelOverlayProperties); -var textures = Overlays.getProperty(modelOverlay, "textures"); -var textureValues = ""; -for (key in textures) { - textureValues += "\n" + key + ": " + textures[key]; -} -print("Model overlay textures =" + textureValues); -Overlays.deleteOverlay(modelOverlay); + +// This model overlay example causes intermittent crashes in NetworkGeometry::setTextureWithNameToURL() +//var modelOverlayProperties = { +// textures: { +// filename1: HIFI_PUBLIC_BUCKET + "images/testing-swatches.svg", +// filename2: HIFI_PUBLIC_BUCKET + "images/hifi-interface-tools.svg" +// } +//} +//var modelOverlay = Overlays.addOverlay("model", modelOverlayProperties); +//var textures = Overlays.getProperty(modelOverlay, "textures"); +//var textureValues = ""; +//for (key in textures) { +// textureValues += "\n" + key + ": " + textures[key]; +//} +//print("Model overlay textures =" + textureValues); +//Overlays.deleteOverlay(modelOverlay); + print("Unknown overlay property =\n" + Overlays.getProperty(1000, "text")); // value = undefined // When our script shuts down, we should clean up all of our overlays From 86284036f1c6d8054c97bef7b43c9ca39b3b2d6a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 14 Nov 2014 10:35:13 -0800 Subject: [PATCH 31/94] put back timestamp in log --- libraries/shared/src/LogHandler.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index dfac02b912..a13f3a9dad 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -119,6 +119,8 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont char dateString[100]; strftime(dateString, sizeof(dateString), DATE_STRING_FORMAT, localTime); + prefixString.append(QString(" [%1]").arg(dateString)); + if (_shouldOutputPID) { prefixString.append(QString(" [%1").arg(getpid())); From 903cd05ff83eb1f79c80829ef556ce28788d1b88 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 14 Nov 2014 10:39:45 -0800 Subject: [PATCH 32/94] put newlines back in interface log --- interface/src/Application.cpp | 2 +- interface/src/FileLogger.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 605bd62118..5e158352bb 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -124,7 +124,7 @@ void messageHandler(QtMsgType type, const QMessageLogContext& context, const QSt QString logMessage = LogHandler::getInstance().printMessage((LogMsgType) type, context, message); if (!logMessage.isEmpty()) { - Application::getInstance()->getLogger()->addMessage(qPrintable(logMessage)); + Application::getInstance()->getLogger()->addMessage(qPrintable(logMessage + "\n")); } } diff --git a/interface/src/FileLogger.cpp b/interface/src/FileLogger.cpp index 505cb6a029..4808842036 100644 --- a/interface/src/FileLogger.cpp +++ b/interface/src/FileLogger.cpp @@ -41,7 +41,7 @@ void FileLogger::addMessage(QString message) { QFile file(_fileName); if (file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) { QTextStream out(&file); - out << message << "\n"; + out << message; } } From 604b1b620b628fcb2c9b24699cbe999b79bca0bf Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 14 Nov 2014 10:52:08 -0800 Subject: [PATCH 33/94] Move dock window to ToolWindow --- interface/src/Application.cpp | 2 +- interface/src/Application.h | 5 +- interface/src/scripting/WebWindowClass.cpp | 6 +- interface/src/ui/ToolWindow.cpp | 82 ++++++++++++++++++++++ interface/src/ui/ToolWindow.h | 40 +++++++++++ 5 files changed, 131 insertions(+), 4 deletions(-) create mode 100644 interface/src/ui/ToolWindow.cpp create mode 100644 interface/src/ui/ToolWindow.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index eefc41cf24..1664cc700e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -373,7 +373,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : // enable mouse tracking; otherwise, we only get drag events _glWidget->setMouseTracking(true); - _toolWindow = new QMainWindow(); + _toolWindow = new ToolWindow(); _toolWindow->setWindowFlags(_toolWindow->windowFlags() | Qt::WindowStaysOnTopHint); _toolWindow->setWindowTitle("Tools"); diff --git a/interface/src/Application.h b/interface/src/Application.h index f2a6615cbf..d31833897f 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -82,6 +82,7 @@ #include "ui/overlays/Overlays.h" #include "ui/ApplicationOverlay.h" #include "ui/RunningScriptsWidget.h" +#include "ui/ToolWindow.h" #include "ui/VoxelImportDialog.h" #include "voxels/VoxelFade.h" #include "voxels/VoxelHideShowThread.h" @@ -246,7 +247,7 @@ public: void lockOctreeSceneStats() { _octreeSceneStatsLock.lockForRead(); } void unlockOctreeSceneStats() { _octreeSceneStatsLock.unlock(); } - QMainWindow* getToolWindow() { return _toolWindow ; } + ToolWindow* getToolWindow() { return _toolWindow ; } GeometryCache* getGeometryCache() { return &_geometryCache; } AnimationCache* getAnimationCache() { return &_animationCache; } @@ -461,7 +462,7 @@ private: MainWindow* _window; GLCanvas* _glWidget; // our GLCanvas has a couple extra features - QMainWindow* _toolWindow; + ToolWindow* _toolWindow; BandwidthMeter _bandwidthMeter; diff --git a/interface/src/scripting/WebWindowClass.cpp b/interface/src/scripting/WebWindowClass.cpp index 7f11dbe580..cc6f4fbfff 100644 --- a/interface/src/scripting/WebWindowClass.cpp +++ b/interface/src/scripting/WebWindowClass.cpp @@ -37,7 +37,7 @@ WebWindowClass::WebWindowClass(const QString& title, const QString& url, int wid : QObject(NULL), _eventBridge(new ScriptEventBridge(this)) { - QMainWindow* toolWindow = Application::getInstance()->getToolWindow(); + ToolWindow* toolWindow = Application::getInstance()->getToolWindow(); _dockWidget = new QDockWidget(title, toolWindow); _dockWidget->setFeatures(QDockWidget::DockWidgetMovable); @@ -55,6 +55,10 @@ WebWindowClass::~WebWindowClass() { } void WebWindowClass::setVisible(bool visible) { + if (visible) { + QMetaObject::invokeMethod( + Application::getInstance()->getToolWindow(), "setVisible", Qt::BlockingQueuedConnection, Q_ARG(bool, visible)); + } QMetaObject::invokeMethod(_dockWidget, "setVisible", Qt::BlockingQueuedConnection, Q_ARG(bool, visible)); } diff --git a/interface/src/ui/ToolWindow.cpp b/interface/src/ui/ToolWindow.cpp new file mode 100644 index 0000000000..1375ff1ea5 --- /dev/null +++ b/interface/src/ui/ToolWindow.cpp @@ -0,0 +1,82 @@ +// +// ToolWindow.cpp +// interface/src/ui +// +// Created by Ryan Huffman on 11/13/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 +// + +#include "Application.h" +#include "ToolWindow.h" +#include "UIUtil.h" + +const int DEFAULT_WIDTH = 300; + +ToolWindow::ToolWindow(QWidget* parent) : + QMainWindow(parent), + _hasShown(false), + _lastGeometry() { +} + +bool ToolWindow::event(QEvent* event) { + QEvent::Type type = event->type(); + if (type == QEvent::Show) { + if (!_hasShown) { + _hasShown = true; + + QMainWindow* mainWindow = Application::getInstance()->getWindow(); + QRect mainGeometry = mainWindow->geometry(); + + int titleBarHeight = UIUtil::getWindowTitleBarHeight(this); + int menuBarHeight = Menu::getInstance()->geometry().height(); + int topMargin = titleBarHeight + menuBarHeight; + + _lastGeometry = QRect(mainGeometry.topLeft().x(), mainGeometry.topLeft().y() + topMargin, + DEFAULT_WIDTH, mainGeometry.height() - topMargin); + } + setGeometry(_lastGeometry); + return true; + } else if (type == QEvent::Hide) { + _lastGeometry = geometry(); + return true; + } + + return QMainWindow::event(event); +} + +void ToolWindow::onChildVisibilityUpdated(bool visible) { + if (visible) { + setVisible(true); + } else { + bool hasVisible = false; + QList dockWidgets = findChildren(); + for (int i = 0; i < dockWidgets.count(); i++) { + if (dockWidgets[i]->isVisible()) { + hasVisible = true; + break; + } + } + setVisible(hasVisible); + } +} + +void ToolWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget* dockWidget) { + QMainWindow::addDockWidget(area, dockWidget); + + connect(dockWidget, &QDockWidget::visibilityChanged, this, &ToolWindow::onChildVisibilityUpdated); +} + +void ToolWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget* dockWidget, Qt::Orientation orientation) { + QMainWindow::addDockWidget(area, dockWidget, orientation); + + connect(dockWidget, &QDockWidget::visibilityChanged, this, &ToolWindow::onChildVisibilityUpdated); +} + +void ToolWindow::removeDockWidget(QDockWidget* dockWidget) { + QMainWindow::removeDockWidget(dockWidget); + + disconnect(dockWidget, &QDockWidget::visibilityChanged, this, &ToolWindow::onChildVisibilityUpdated); +} diff --git a/interface/src/ui/ToolWindow.h b/interface/src/ui/ToolWindow.h new file mode 100644 index 0000000000..87b94d46df --- /dev/null +++ b/interface/src/ui/ToolWindow.h @@ -0,0 +1,40 @@ +// +// ToolWindow.h +// interface/src/ui +// +// Created by Ryan Huffman on 11/13/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 +// + +#ifndef hifi_ToolWindow_h +#define hifi_ToolWindow_h + +#include +#include +#include +#include +#include + +class ToolWindow : public QMainWindow { + Q_OBJECT +public: + ToolWindow(QWidget* parent = NULL); + + virtual bool event(QEvent* event); + virtual void addDockWidget(Qt::DockWidgetArea area, QDockWidget* dockWidget); + virtual void addDockWidget(Qt::DockWidgetArea area, QDockWidget* dockWidget, Qt::Orientation orientation); + virtual void removeDockWidget(QDockWidget* dockWidget); + +public slots: + void onChildVisibilityUpdated(bool visible); + + +private: + bool _hasShown; + QRect _lastGeometry; +}; + +#endif // hifi_ToolWindow_h From fa03a7eb0cac1991c3d9172364ecba18ef2570a5 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Fri, 14 Nov 2014 19:53:56 +0100 Subject: [PATCH 34/94] fix ubuntu build --- interface/src/ui/overlays/BillboardOverlay.cpp | 2 +- interface/src/ui/overlays/ImageOverlay.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/overlays/BillboardOverlay.cpp b/interface/src/ui/overlays/BillboardOverlay.cpp index aec5e993dd..f1d991d5cb 100644 --- a/interface/src/ui/overlays/BillboardOverlay.cpp +++ b/interface/src/ui/overlays/BillboardOverlay.cpp @@ -210,5 +210,5 @@ void BillboardOverlay::writeToClone(BillboardOverlay* clone) { clone->setIsFacingAvatar(_isFacingAvatar); clone->setClipFromSource(_fromImage); clone->_url = _url; - clone->_billboard = QByteArray::QByteArray(_billboard); + clone->_billboard = _billboard; } diff --git a/interface/src/ui/overlays/ImageOverlay.cpp b/interface/src/ui/overlays/ImageOverlay.cpp index 6c2b09018e..04038834c2 100644 --- a/interface/src/ui/overlays/ImageOverlay.cpp +++ b/interface/src/ui/overlays/ImageOverlay.cpp @@ -160,6 +160,6 @@ ImageOverlay* ImageOverlay::createClone() { void ImageOverlay::writeToClone(ImageOverlay* clone) { Overlay2D::writeToClone(clone); clone->_imageURL = _imageURL; - clone->_textureImage = QImage::QImage(_textureImage); + clone->_textureImage = _textureImage; clone->_renderImage = _renderImage; } From cd4b2677324981374c2d63b1d8d485a59eebff08 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Nov 2014 11:11:32 -0800 Subject: [PATCH 35/94] implement persist backup --- assignment-client/src/octree/OctreeServer.cpp | 25 ++++++- assignment-client/src/octree/OctreeServer.h | 5 ++ libraries/octree/src/OctreePersistThread.cpp | 74 +++++++++++++++---- libraries/octree/src/OctreePersistThread.h | 16 +++- 4 files changed, 101 insertions(+), 19 deletions(-) diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 34378effd3..f78a9a2b30 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -1020,7 +1020,7 @@ void OctreeServer::readConfiguration() { bool noPersist; readOptionBool(QString("NoPersist"), settingsSectionObject, noPersist); _wantPersist = !noPersist; - qDebug("wantPersist=%s", debug::valueOf(_wantPersist)); + qDebug() << "wantPersist=" << _wantPersist; if (_wantPersist) { QString persistFilename; @@ -1029,6 +1029,26 @@ void OctreeServer::readConfiguration() { } strcpy(_persistFilename, qPrintable(persistFilename)); qDebug("persistFilename=%s", _persistFilename); + + _persistInterval = OctreePersistThread::DEFAULT_PERSIST_INTERVAL; + readOptionInt(QString("persistInterval"), settingsSectionObject, _persistInterval); + qDebug() << "persistInterval=" << _persistInterval; + + bool noBackup; + readOptionBool(QString("NoBackup"), settingsSectionObject, noBackup); + _wantBackup = !noBackup; + qDebug() << "wantBackup=" << _wantBackup; + + if (_wantBackup) { + _backupExtensionFormat = OctreePersistThread::DEFAULT_BACKUP_EXTENSION_FORMAT; + readOptionString(QString("backupExtensionFormat"), settingsSectionObject, _backupExtensionFormat); + qDebug() << "backupExtensionFormat=" << _backupExtensionFormat; + + _backupInterval = OctreePersistThread::DEFAULT_BACKUP_INTERVAL; + readOptionInt(QString("backupInterval"), settingsSectionObject, _backupInterval); + qDebug() << "backupInterval=" << _backupInterval; + } + } else { qDebug("persistFilename= DISABLED"); } @@ -1112,7 +1132,8 @@ void OctreeServer::run() { if (_wantPersist) { // now set up PersistThread - _persistThread = new OctreePersistThread(_tree, _persistFilename); + _persistThread = new OctreePersistThread(_tree, _persistFilename, _persistInterval, + _wantBackup, _backupInterval, _backupExtensionFormat); if (_persistThread) { _persistThread->initialize(true); } diff --git a/assignment-client/src/octree/OctreeServer.h b/assignment-client/src/octree/OctreeServer.h index b05896596c..8a91b94da0 100644 --- a/assignment-client/src/octree/OctreeServer.h +++ b/assignment-client/src/octree/OctreeServer.h @@ -167,6 +167,11 @@ protected: JurisdictionSender* _jurisdictionSender; OctreeInboundPacketProcessor* _octreeInboundPacketProcessor; OctreePersistThread* _persistThread; + + int _persistInterval; + bool _wantBackup; + QString _backupExtensionFormat; + int _backupInterval; static OctreeServer* _instance; diff --git a/libraries/octree/src/OctreePersistThread.cpp b/libraries/octree/src/OctreePersistThread.cpp index dd81b3ff4d..f8afb52b85 100644 --- a/libraries/octree/src/OctreePersistThread.cpp +++ b/libraries/octree/src/OctreePersistThread.cpp @@ -15,12 +15,23 @@ #include "OctreePersistThread.h" -OctreePersistThread::OctreePersistThread(Octree* tree, const QString& filename, int persistInterval) : +const int OctreePersistThread::DEFAULT_PERSIST_INTERVAL = 1000 * 30; // every 30 seconds +const int OctreePersistThread::DEFAULT_BACKUP_INTERVAL = 1000 * 60 * 1; // every 1 minutes +const QString OctreePersistThread::DEFAULT_BACKUP_EXTENSION_FORMAT(".backup.%Y-%m-%d.%H:%M:%S.%z"); + + +OctreePersistThread::OctreePersistThread(Octree* tree, const QString& filename, int persistInterval, + bool wantBackup, int backupInterval, const QString& backupExtensionFormat) : _tree(tree), _filename(filename), + _backupExtensionFormat(backupExtensionFormat), _persistInterval(persistInterval), + _backupInterval(backupInterval), _initialLoadComplete(false), - _loadTimeUSecs(0) + _loadTimeUSecs(0), + _lastCheck(0), + _lastBackup(0), + _wantBackup(wantBackup) { } @@ -51,16 +62,22 @@ bool OctreePersistThread::process() { unsigned long leafNodeCount = OctreeElement::getLeafNodeCount(); qDebug("Nodes after loading scene %lu nodes %lu internal %lu leaves", nodeCount, internalNodeCount, leafNodeCount); - double usecPerGet = (double)OctreeElement::getGetChildAtIndexTime() / (double)OctreeElement::getGetChildAtIndexCalls(); - qDebug() << "getChildAtIndexCalls=" << OctreeElement::getGetChildAtIndexCalls() - << " getChildAtIndexTime=" << OctreeElement::getGetChildAtIndexTime() << " perGet=" << usecPerGet; + bool wantDebug = false; + if (wantDebug) { + double usecPerGet = (double)OctreeElement::getGetChildAtIndexTime() + / (double)OctreeElement::getGetChildAtIndexCalls(); + qDebug() << "getChildAtIndexCalls=" << OctreeElement::getGetChildAtIndexCalls() + << " getChildAtIndexTime=" << OctreeElement::getGetChildAtIndexTime() << " perGet=" << usecPerGet; - double usecPerSet = (double)OctreeElement::getSetChildAtIndexTime() / (double)OctreeElement::getSetChildAtIndexCalls(); - qDebug() << "setChildAtIndexCalls=" << OctreeElement::getSetChildAtIndexCalls() - << " setChildAtIndexTime=" << OctreeElement::getSetChildAtIndexTime() << " perset=" << usecPerSet; + double usecPerSet = (double)OctreeElement::getSetChildAtIndexTime() + / (double)OctreeElement::getSetChildAtIndexCalls(); + qDebug() << "setChildAtIndexCalls=" << OctreeElement::getSetChildAtIndexCalls() + << " setChildAtIndexTime=" << OctreeElement::getSetChildAtIndexTime() << " perSet=" << usecPerSet; + } _initialLoadComplete = true; - _lastCheck = usecTimestampNow(); // we just loaded, no need to save again + _lastBackup = _lastCheck = usecTimestampNow(); // we just loaded, no need to save again + time(&_lastPersistTime); emit loadCompleted(); } @@ -79,7 +96,7 @@ bool OctreePersistThread::process() { if (sinceLastSave > intervalToCheck) { _lastCheck = now; - persistOperation(); + persist(); } } return isStillRunning(); // keep running till they terminate us @@ -88,11 +105,11 @@ bool OctreePersistThread::process() { void OctreePersistThread::aboutToFinish() { qDebug() << "Persist thread about to finish..."; - persistOperation(); + persist(); qDebug() << "Persist thread done with about to finish..."; } -void OctreePersistThread::persistOperation() { +void OctreePersistThread::persist() { if (_tree->isDirty()) { _tree->lockForWrite(); { @@ -102,9 +119,38 @@ void OctreePersistThread::persistOperation() { } _tree->unlock(); + backup(); // handle backup if requested + qDebug() << "saving Octree to file " << _filename << "..."; - _tree->writeToSVOFile(_filename.toLocal8Bit().constData()); + _tree->writeToSVOFile(qPrintable(_filename)); + time(&_lastPersistTime); _tree->clearDirtyBit(); // tree is clean after saving - qDebug("DONE saving Octree to file..."); + qDebug() << "DONE saving Octree to file..."; + } +} + +void OctreePersistThread::backup() { + if (_wantBackup) { + quint64 now = usecTimestampNow(); + quint64 sinceLastBackup = now - _lastBackup; + quint64 MSECS_TO_USECS = 1000; + quint64 intervalToBackup = _backupInterval * MSECS_TO_USECS; + + if (sinceLastBackup > intervalToBackup) { + struct tm* localTime = localtime(&_lastPersistTime); + + char backupExtension[256]; + strftime(backupExtension, sizeof(backupExtension), qPrintable(_backupExtensionFormat), localTime); + + QString backupFileName = _filename + backupExtension; + + qDebug() << "backing up persist file " << _filename << "to" << backupFileName << "..."; + int result = rename(qPrintable(_filename), qPrintable(backupFileName)); + if (result == 0) { + qDebug() << "DONE backing up persist file..."; + } else { + qDebug() << "ERROR in backing up persist file..."; + } + } } } diff --git a/libraries/octree/src/OctreePersistThread.h b/libraries/octree/src/OctreePersistThread.h index c4bccd55b9..c02e416e25 100644 --- a/libraries/octree/src/OctreePersistThread.h +++ b/libraries/octree/src/OctreePersistThread.h @@ -22,9 +22,13 @@ class OctreePersistThread : public GenericThread { Q_OBJECT public: - static const int DEFAULT_PERSIST_INTERVAL = 1000 * 30; // every 30 seconds + static const int DEFAULT_PERSIST_INTERVAL; + static const int DEFAULT_BACKUP_INTERVAL; + static const QString DEFAULT_BACKUP_EXTENSION_FORMAT; - OctreePersistThread(Octree* tree, const QString& filename, int persistInterval = DEFAULT_PERSIST_INTERVAL); + OctreePersistThread(Octree* tree, const QString& filename, int persistInterval = DEFAULT_PERSIST_INTERVAL, + bool wantBackup = true, int backupInterval = DEFAULT_BACKUP_INTERVAL, + const QString& backupExtensionFormat = DEFAULT_BACKUP_EXTENSION_FORMAT); bool isInitialLoadComplete() const { return _initialLoadComplete; } quint64 getLoadElapsedTime() const { return _loadTimeUSecs; } @@ -38,15 +42,21 @@ protected: /// Implements generic processing behavior for this thread. virtual bool process(); - void persistOperation(); + void persist(); + void backup(); private: Octree* _tree; QString _filename; + QString _backupExtensionFormat; int _persistInterval; + int _backupInterval; bool _initialLoadComplete; quint64 _loadTimeUSecs; quint64 _lastCheck; + quint64 _lastBackup; + bool _wantBackup; + time_t _lastPersistTime; }; #endif // hifi_OctreePersistThread_h From cc78000641968b24aa3824f78fb1b88dd49c5389 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 14 Nov 2014 11:22:11 -0800 Subject: [PATCH 36/94] introduce the concept of side thorugh out the rendering traversal --- interface/src/Application.cpp | 14 +++++--------- interface/src/Application.h | 13 +------------ interface/src/devices/TV3DManager.cpp | 4 ++-- 3 files changed, 8 insertions(+), 23 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 48fa2413ea..792ad2d62e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -724,7 +724,7 @@ void Application::paintGL() { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); - displaySide(RenderContext(*whichCamera)); + displaySide(*whichCamera); glPopMatrix(); if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { @@ -2874,16 +2874,12 @@ QImage Application::renderAvatarBillboard() { return image; } -//void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { -void Application::displaySide(RenderContext& renderContext) { +void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly, RenderArgs::RenderSide renderSide) { PROFILE_RANGE(__FUNCTION__); PerformanceTimer perfTimer("display"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()"); // transform by eye offset - Camera& whichCamera = renderContext._whichCamera; - bool selfAvatarOnly = renderContext._selfAvatarOnly; - // load the view frustum loadViewFrustum(whichCamera, _displayViewFrustum); @@ -3025,7 +3021,7 @@ void Application::displaySide(RenderContext& renderContext) { PerformanceTimer perfTimer("entities"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... entities..."); - _entities.render(RenderArgs::DEFAULT_RENDER_MODE, renderContext._renderSide); + _entities.render(RenderArgs::DEFAULT_RENDER_MODE, renderSide); } // render JS/scriptable overlays @@ -3270,7 +3266,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { _shadowMatrices[i] = glm::transpose(glm::transpose(_shadowMatrices[i]) * glm::translate(-delta)); } - displaySide(RenderContext(_mirrorCamera, true)); + displaySide(_mirrorCamera, true); // restore absolute translations _myAvatar->getSkeletonModel().setTranslation(absoluteSkeletonTranslation); @@ -3284,7 +3280,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { _shadowMatrices[i] = savedShadowMatrices[i]; } } else { - displaySide(RenderContext(_mirrorCamera, true)); + displaySide(_mirrorCamera, true); } glPopMatrix(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 2cea413dd4..178849eec4 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -262,19 +262,8 @@ public: QImage renderAvatarBillboard(); - struct RenderContext { - Camera& _whichCamera; - bool _selfAvatarOnly; - RenderArgs::RenderSide _renderSide; - - RenderContext(Camera& whichCamera, bool selfAvatarOnly = false, RenderArgs::RenderSide renderSide = RenderArgs::MONO) : - _whichCamera(whichCamera), - _selfAvatarOnly(selfAvatarOnly), - _renderSide(renderSide) { - } - }; // void displaySide(Camera& whichCamera, bool selfAvatarOnly = false); - void displaySide(RenderContext& renderContext); + void displaySide(Camera& whichCamera, bool selfAvatarOnly = false, RenderArgs::RenderSide renderSide = RenderArgs::MONO); /// Stores the current modelview matrix as the untranslated view matrix to use for transforms and the supplied vector as /// the view matrix translation. diff --git a/interface/src/devices/TV3DManager.cpp b/interface/src/devices/TV3DManager.cpp index bd0129f88e..d7d7353b24 100644 --- a/interface/src/devices/TV3DManager.cpp +++ b/interface/src/devices/TV3DManager.cpp @@ -126,7 +126,7 @@ void TV3DManager::display(Camera& whichCamera) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - Application::getInstance()->displaySide(Application::RenderContext(whichCamera, false, RenderArgs::STEREO_LEFT)); + Application::getInstance()->displaySide(whichCamera, false, RenderArgs::STEREO_LEFT); if (displayOverlays) { applicationOverlay.displayOverlayTexture3DTV(whichCamera, _aspect, fov); @@ -156,7 +156,7 @@ void TV3DManager::display(Camera& whichCamera) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - Application::getInstance()->displaySide(Application::RenderContext(whichCamera, false, RenderArgs::STEREO_RIGHT)); + Application::getInstance()->displaySide(whichCamera, false, RenderArgs::STEREO_RIGHT); if (displayOverlays) { applicationOverlay.displayOverlayTexture3DTV(whichCamera, _aspect, fov); From 6ee4e611ac0634c942ef0fc826fdc443f40d7aa5 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Nov 2014 11:31:06 -0800 Subject: [PATCH 37/94] add persist settings to domain settings, make default backup interval 30 minutes --- .../resources/describe-settings.json | 93 ++++++++++++++++++- libraries/octree/src/OctreePersistThread.cpp | 2 +- 2 files changed, 93 insertions(+), 2 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index ba4cfe8dfd..04c48e460e 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -276,6 +276,52 @@ "label": "Entity Server Settings", "assignment-types": [6], "settings": [ + { + "name": "persistFilename", + "label": "Persistant Filename", + "help": "the filename for your entities", + "placeholder": "resources/models.svo", + "default": "resources/models.svo", + "advanced": true + }, + { + "name": "persistInterval", + "label": "Persist Interval", + "help": "Interval between persist checks in msecs.", + "placeholder": "30000", + "default": "30000", + "advanced": true + }, + { + "name": "NoPersist", + "type": "checkbox", + "help": "Don't persist your entities to a file.", + "default": false, + "advanced": true + }, + { + "name": "backupExtensionFormat", + "label": "Backup File Extension Format:", + "help": "Format used to create the extension for the backup of your persisted entities.", + "placeholder": ".backup.%Y-%m-%d.%H:%M:%S.%z", + "default": ".backup.%Y-%m-%d.%H:%M:%S.%z", + "advanced": true + }, + { + "name": "backupInterval", + "label": "Backup Interval", + "help": "Interval between backup checks in msecs.", + "placeholder": "1800000", + "default": "1800000", + "advanced": true + }, + { + "name": "NoBackup", + "type": "checkbox", + "help": "Don't regularly backup your persisted entities to a backup file.", + "default": false, + "advanced": true + }, { "name": "statusHost", "label": "Status Hostname", @@ -330,7 +376,52 @@ "label": "Voxel Server Settings", "assignment-types": [3], "settings": [ - + { + "name": "persistFilename", + "label": "Persistant Filename", + "help": "the filename for your voxels", + "placeholder": "resources/voxels.svo", + "default": "resources/voxels.svo", + "advanced": true + }, + { + "name": "persistInterval", + "label": "Persist Interval", + "help": "Interval between persist checks in msecs.", + "placeholder": "30000", + "default": "30000", + "advanced": true + }, + { + "name": "NoPersist", + "type": "checkbox", + "help": "Don't persist your voxels to a file.", + "default": false, + "advanced": true + }, + { + "name": "backupExtensionFormat", + "label": "Backup File Extension Format:", + "help": "Format used to create the extension for the backup of your persisted voxels.", + "placeholder": ".backup.%Y-%m-%d.%H:%M:%S.%z", + "default": ".backup.%Y-%m-%d.%H:%M:%S.%z", + "advanced": true + }, + { + "name": "backupInterval", + "label": "Backup Interval", + "help": "Interval between backup checks in msecs.", + "placeholder": "1800000", + "default": "1800000", + "advanced": true + }, + { + "name": "NoBackup", + "type": "checkbox", + "help": "Don't regularly backup your persisted voxels to a backup file.", + "default": false, + "advanced": true + }, { "name": "statusHost", "label": "Status Hostname", diff --git a/libraries/octree/src/OctreePersistThread.cpp b/libraries/octree/src/OctreePersistThread.cpp index f8afb52b85..79507eae64 100644 --- a/libraries/octree/src/OctreePersistThread.cpp +++ b/libraries/octree/src/OctreePersistThread.cpp @@ -16,7 +16,7 @@ #include "OctreePersistThread.h" const int OctreePersistThread::DEFAULT_PERSIST_INTERVAL = 1000 * 30; // every 30 seconds -const int OctreePersistThread::DEFAULT_BACKUP_INTERVAL = 1000 * 60 * 1; // every 1 minutes +const int OctreePersistThread::DEFAULT_BACKUP_INTERVAL = 1000 * 60 * 30; // every 30 minutes const QString OctreePersistThread::DEFAULT_BACKUP_EXTENSION_FORMAT(".backup.%Y-%m-%d.%H:%M:%S.%z"); From 899a3985a5ef56c16e54397746880b6c37b92555 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Nov 2014 11:32:18 -0800 Subject: [PATCH 38/94] OctreePersistThread defaults to no backup, server always uses settings --- libraries/octree/src/OctreePersistThread.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/octree/src/OctreePersistThread.h b/libraries/octree/src/OctreePersistThread.h index c02e416e25..06b97b2dcb 100644 --- a/libraries/octree/src/OctreePersistThread.h +++ b/libraries/octree/src/OctreePersistThread.h @@ -27,7 +27,7 @@ public: static const QString DEFAULT_BACKUP_EXTENSION_FORMAT; OctreePersistThread(Octree* tree, const QString& filename, int persistInterval = DEFAULT_PERSIST_INTERVAL, - bool wantBackup = true, int backupInterval = DEFAULT_BACKUP_INTERVAL, + bool wantBackup = false, int backupInterval = DEFAULT_BACKUP_INTERVAL, const QString& backupExtensionFormat = DEFAULT_BACKUP_EXTENSION_FORMAT); bool isInitialLoadComplete() const { return _initialLoadComplete; } From de12b2543dfddedac9d9016aad1b96a74a0d0dca Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Nov 2014 11:50:45 -0800 Subject: [PATCH 39/94] winblows --- libraries/octree/src/OctreePersistThread.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/octree/src/OctreePersistThread.cpp b/libraries/octree/src/OctreePersistThread.cpp index 79507eae64..f74ddfa5f0 100644 --- a/libraries/octree/src/OctreePersistThread.cpp +++ b/libraries/octree/src/OctreePersistThread.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #include #include #include From a1bd5623e1d453e87bd36545bd7e9af6648af458 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 14 Nov 2014 12:04:49 -0800 Subject: [PATCH 40/94] refactor + solved network issues --- examples/entityScripts/chessPiece.js | 226 ++++++++++++++++----------- examples/playChess.js | 189 +++++++++++----------- 2 files changed, 241 insertions(+), 174 deletions(-) diff --git a/examples/entityScripts/chessPiece.js b/examples/entityScripts/chessPiece.js index 17b186d396..f6a2c46d28 100644 --- a/examples/entityScripts/chessPiece.js +++ b/examples/entityScripts/chessPiece.js @@ -1,61 +1,101 @@ (function(){ - this.GRID_POSITION = { x: 1, y: 1, z: 1 }; - this.GRID_SIZE = 1.0; - this.metadata = null; - this.sound = null; + this.FIRST_TILE = null; // Global position of the first tile (1a) + this.TILE_SIZE = null; // Size of one tile + this.whitesDeadPieces = null; + this.blacksDeadPieces = null; + + this.wantDebug = false; + this.active = false; + this.entityID = null; this.properties = null; + this.boardID = null; + this.boardUserData = null; + + this.sound = null; this.startingTile = null; this.pieces = new Array(); + // All callbacks start by updating the properties this.updateProperties = function(entityID) { - if (this.entityID === null) { - this.entityID = entityID; - } - if (!entityID.isKnownID || this.entityID.id !== entityID.id) { - print("Something is very wrong: Bailing!"); - return; + // Piece ID + if (this.entityID === null || !this.entityID.isKnownID) { + this.entityID = Entities.identifyEntity(entityID); } + // Piece Properties this.properties = Entities.getEntityProperties(this.entityID); - if (!this.properties.isKnownID) { - print("Unknown entityID " + this.entityID.id + " should be self.") - } - } - - this.updatePosition = function(mouseEvent) { - var pickRay = Camera.computePickRay(mouseEvent.x, mouseEvent.y) - var upVector = { x: 0, y: 1, z: 0 }; - var intersection = this.rayPlaneIntersection(pickRay.origin, pickRay.direction, - this.properties.position, upVector); - if (this.isOutsideGrid(this.getIndexPosition(intersection))) { - intersection = this.getAbsolutePosition(this.startingTile); - } - Entities.editEntity(this.entityID, { position: intersection }); - //this.moveDeadPiece(); - } - this.isOutsideGrid = function(pos) { - return !(pos.i >= 0 && pos.j >= 0 && pos.i <= 9 && pos.j <= 9); - } - this.getIndexPosition = function(position) { - var tileSize = this.GRID_SIZE / 10.0; - var relative = Vec3.subtract(position, this.GRID_POSITION); - return { - i: Math.floor(relative.x / tileSize), - j: Math.floor(relative.z / tileSize) - } - } - this.getAbsolutePosition = function(pos) { - var tileSize = this.GRID_SIZE / 10.0; - var relative = Vec3.subtract(this.properties.position, this.GRID_POSITION); - relative.x = (pos.i + 0.5) * tileSize; - relative.z = (pos.j + 0.5) * tileSize; - return Vec3.sum(this.GRID_POSITION, relative); + // Board ID + if (this.boardID === null) { + // Read user data string and update boardID + var userData = JSON.parse(this.properties.userData); + var boardID = Entities.identifyEntity(userData.boardID); + if (boardID.isKnownID) { + this.boardID = boardID; + } else { + return; + } + } + + // Board User Data + this.updateUserData(); } - this.snapToGrid = function() { - var pos = this.getIndexPosition(this.properties.position); - var finalPos = this.getAbsolutePosition((this.isOutsideGrid(pos)) ? this.startingTile : pos); - Entities.editEntity(this.entityID, { position: finalPos }); + // Get an entity's user data + this.getEntityUserData = function(entityID) { + var properties = Entities.getEntityProperties(entityID); + + if (properties && properties.userData){ + return JSON.parse(properties.userData); + } else { + print("No user data found."); + return null; + } + } + // Updates user data related objects + this.updateUserData = function() { + // Get board's user data + if (this.boardID !== null && this.boardID.isKnownID) { + this.boardUserData = this.getEntityUserData(this.boardID); + if (!(this.boardUserData && + this.boardUserData.firstTile && + this.boardUserData.tileSize && + this.boardUserData.whitesDeadPieces && + this.boardUserData.blacksDeadPieces)) { + print("Incomplete boardUserData " + this.boardID.id); + } else { + this.FIRST_TILE = this.boardUserData.firstTile; + this.TILE_SIZE = this.boardUserData.tileSize; + this.whitesDeadPieces = this.boardUserData.whitesDeadPieces; + this.blacksDeadPieces = this.boardUserData.blacksDeadPieces; + + this.active = true; + } + } else { + print("Missing boardID:" + JSON.stringify(this.boardID)); + } + } + // Returns whether pos is inside the grid or not + this.isOutsideGrid = function(pos) { + return !(pos.i >= 0 && pos.j >= 0 && pos.i < 8 && pos.j < 8); + } + // Returns the tile coordinate + this.getIndexPosition = function(position) { + var halfTile = this.TILE_SIZE / 2.0; + var corner = Vec3.sum(this.FIRST_TILE, { x: -halfTile, y: 0.0, z: -halfTile }); + var relative = Vec3.subtract(position, corner); + return { + i: Math.floor(relative.x / this.TILE_SIZE), + j: Math.floor(relative.z / this.TILE_SIZE) + } + } + // Returns the world position + this.getAbsolutePosition = function(pos, halfHeight) { + var relative = { + x: pos.i * this.TILE_SIZE, + y: halfHeight, + z: pos.j * this.TILE_SIZE + } + return Vec3.sum(this.FIRST_TILE, relative); } // Pr, Vr are respectively the Ray's Point of origin and Vector director // Pp, Np are respectively the Plane's Point of origin and Normal vector @@ -64,75 +104,87 @@ var t = -(Vec3.dot(Pr, Np) + d) / Vec3.dot(Vr, Np); return Vec3.sum(Pr, Vec3.multiply(t, Vr)); } + // Download sound if needed this.maybeDownloadSound = function() { if (this.sound === null) { - this.sound = new Sound("http://public.highfidelity.io/sounds/Footsteps/FootstepW3Left-12db.wav"); + this.sound = SoundCache.getSound("http://public.highfidelity.io/sounds/Footsteps/FootstepW3Left-12db.wav"); } } - + // Play drop sound this.playSound = function() { - if (this.sound !== null && this.sound.downloaded) { + if (this.sound && this.sound.downloaded) { Audio.playSound(this.sound, { position: this.properties.position }); - print("playing sound"); } } - this.getMetadata = function() { - if (this.properties.animationURL !== "") { - var metadataObject = JSON.parse(this.properties.animationURL); - if (metadataObject.gamePosition) { - this.GRID_POSITION = metadataObject.gamePosition; - } - if (metadataObject.gameSize) { - this.GRID_SIZE = metadataObject.gameSize; - } - if (metadataObject.pieces) { - this.pieces = metadataObject.pieces; - } + // updates the piece position based on mouse input + this.updatePosition = function(mouseEvent) { + var pickRay = Camera.computePickRay(mouseEvent.x, mouseEvent.y) + var upVector = { x: 0, y: 1, z: 0 }; + var intersection = this.rayPlaneIntersection(pickRay.origin, pickRay.direction, + this.properties.position, upVector); + // if piece outside grid then send it back to the starting tile + if (this.isOutsideGrid(this.getIndexPosition(intersection))) { + intersection = this.getAbsolutePosition(this.startingTile, this.properties.dimensions.y / 2.0); } + Entities.editEntity(this.entityID, { position: intersection }); + } + // Snap piece to the center of the tile it is on + this.snapToGrid = function() { + var pos = this.getIndexPosition(this.properties.position); + var finalPos = this.getAbsolutePosition((this.isOutsideGrid(pos)) ? this.startingTile : pos, + this.properties.dimensions.y / 2.0); + Entities.editEntity(this.entityID, { position: finalPos }); + } + this.moveDeadPiece = function() { + return; + var myPos = this.getIndexPosition(this.properties.position); + for (var i = 0; i < this.pieces.length; i++) { + if (this.pieces[i].id != this.entityID.id) { + var piecePos = this.getIndexPosition(Entities.getEntityProperties(this.pieces[i]).position); + if (myPos.i === piecePos.i && myPos.j === piecePos.j) { + Entities.editEntity(this.pieces[i], { position: this.getAbsolutePosition({ i: 0, j: 0 })}); + break; + } + } + } } this.grab = function(mouseEvent) { - this.startingTile = this.getIndexPosition(this.properties.position); - this.updatePosition(mouseEvent); + if (this.active) { + this.startingTile = this.getIndexPosition(this.properties.position); + this.updatePosition(mouseEvent); + } } this.move = function(mouseEvent) { - this.updatePosition(mouseEvent); + if (this.active) { + this.updatePosition(mouseEvent); + } } this.release = function(mouseEvent) { - this.updatePosition(mouseEvent); - this.snapToGrid(); - - this.playSound(); - } - this.moveDeadPiece = function() { - var myPos = this.getIndexPosition(this.properties.position); - for (var i = 0; i < this.pieces.length; i++) { - if (this.pieces[i].id != this.entityID.id) { - var piecePos = this.getIndexPosition(Entities.getEntityProperties(this.pieces[i]).position); - if (myPos.i === piecePos.i && myPos.j === piecePos.j) { - Entities.editEntity(this.pieces[i], { position: this.getAbsolutePosition({ i: 0, j: 0 })}); - break; - } - } + if (this.active) { + this.updatePosition(mouseEvent); + this.snapToGrid(); + //this.moveDeadPiece(); TODO + this.playSound(); } } - this.preload = function() { + this.preload = function(entityID) { + this.updateProperties(entityID); // All callbacks start by updating the properties this.maybeDownloadSound(); } this.clickDownOnEntity = function(entityID, mouseEvent) { - this.maybeDownloadSound(); - this.updateProperties(entityID); - this.getMetadata(); + this.preload(entityID); // TODO : remove + this.updateProperties(entityID); // All callbacks start by updating the properties this.grab(mouseEvent); }; this.holdingClickOnEntity = function(entityID, mouseEvent) { - this.updateProperties(entityID); + this.updateProperties(entityID); // All callbacks start by updating the properties this.move(mouseEvent); }; this.clickReleaseOnEntity = function(entityID, mouseEvent) { - this.updateProperties(entityID); + this.updateProperties(entityID); // All callbacks start by updating the properties this.release(mouseEvent); }; }) \ No newline at end of file diff --git a/examples/playChess.js b/examples/playChess.js index 1ed836b7ca..da66d93677 100644 --- a/examples/playChess.js +++ b/examples/playChess.js @@ -69,16 +69,34 @@ ChessGame.getPieceInfo = function(type, isWhite) { // Board class -ChessGame.Board = (function(position, size) { +ChessGame.Board = (function(position, scale) { this.dimensions = Vec3.multiply(1.0 / ChessGame.BOARD.dimensions.x, ChessGame.BOARD.dimensions); // 1 by 1 - this.dimensions = Vec3.multiply(size, this.dimensions); // size by size - this.position = Vec3.sum(position, Vec3.multiply(0.5, this.dimensions)); - this.tileSize = size / ChessGame.BOARD.numTiles; - + this.dimensions = Vec3.multiply(scale, this.dimensions); // scale by scale + this.position = position + this.tileSize = scale / ChessGame.BOARD.numTiles; + + this.userDataObject = { + firstTile: this.tilePosition(1, 1), + tileSize: this.tileSize, + whitesDeadPieces: this.tilePosition(0,0), + blacksDeadPieces: this.tilePosition(9,9), + pieces: new Array() + } + this.entityProperties = { + type: "Model", + modelURL: ChessGame.BOARD.modelURL, + position: this.position, + dimensions: this.dimensions, + userData: this.buildUserDataString() + } this.entity = null; }); // Returns the top center point of tile i,j ChessGame.Board.prototype.tilePosition = function(i, j) { + if (!(this.position || this.dimensions || this.tileSize || ChessGame.BOARD.numTiles)) { + print("ChessGame.Board.prototype.tilePosition(): Called before proper initialisation, bailing."); + return null; + } return { x: this.position.x + (i - ChessGame.BOARD.numTiles / 2.0 + 0.5) * this.tileSize, y: this.position.y + this.dimensions.y / 2.0, @@ -89,19 +107,22 @@ ChessGame.Board.prototype.tilePosition = function(i, j) { ChessGame.Board.prototype.isWhite = function(i, j) { return (i + j) % 2 != 0; } +// Build the user data string +ChessGame.Board.prototype.buildUserDataString = function() { + return JSON.stringify(this.userDataObject); +} +// Updates the user data stored by the board +ChessGame.Board.prototype.updateUserData = function() { + var userDataString = this.buildUserDataString(); + this.entityProperties.userData = userDataString; + Entities.editEntity(this.entity, { userData: userDataString }); +} // Spawns the board using entities ChessGame.Board.prototype.spawn = function() { if (extraDebug) { print("Spawning board..."); } - - this.entity = Entities.addEntity({ - type: "Model", - modelURL: ChessGame.BOARD.modelURL, - position: this.position, - dimensions: this.dimensions - }); - + this.entity = Entities.addEntity(this.entityProperties); print("Board spawned"); } // Cleans up the entities of the board @@ -118,26 +139,35 @@ ChessGame.Piece = (function(position, dimensions, url, rotation) { this.dimensions = dimensions; this.position = position; this.position.y += this.dimensions.y / 2.0; + this.entityProperties = { type: "Model", position: this.position, rotation: rotation, dimensions: this.dimensions, modelURL: url, - //script: "https://s3.amazonaws.com/hifi-public/scripts/entityScripts/chessPiece.js" - //script: "https://s3-us-west-1.amazonaws.com/highfidelity-dev/scripts/chessPiece.js" - script: "file:/Users/clement/hifi/examples/entityScripts/chessPiece.js" + //script: "https://s3.amazonaws.com/hifi-public/scripts/entityScripts/chessPiece.js", + //script: "https://s3-us-west-1.amazonaws.com/highfidelity-dev/scripts/chessPiece.js", + script: "file:/Users/clement/hifi/examples/entityScripts/chessPiece.js", + userData: this.buildUserDataString() } this.entity = null; }); +// Build the user data string +ChessGame.Piece.prototype.buildUserDataString = function() { + if (!(ChessGame.board !== null || ChessGame.board.entity.isKnownID)) { + print("ChessGame.Piece.prototype.buildUserDataString(): Called before proper initialization, bailing."); + return null; + } + var userDataObject = { + boardID: ChessGame.board.entity, + }; + return JSON.stringify(userDataObject); +} // Spawns the piece ChessGame.Piece.prototype.spawn = function() { this.entity = Entities.addEntity(this.entityProperties); } -// Updates the metadata stored by the piece -ChessGame.Piece.prototype.updateMetadata = function(metadataString) { - Entities.editEntity(this.entity, { animationURL: metadataString }); -} // Cleans up the piece ChessGame.Piece.prototype.cleanup = function() { Entities.deleteEntity(this.entity); @@ -157,91 +187,76 @@ ChessGame.makePiece = function(piece, i, j, isWhite) { return piece; } -ChessGame.buildMetadataString = function() { - var metadataObject = { - gamePosition: gamePosition, - gameSize: gameSize, - pieces: new Array() - }; - for (i in ChessGame.pieces) { - metadataObject.pieces.push(ChessGame.pieces[i].entity); - } - return JSON.stringify(metadataObject); -} - -ChessGame.buildBoard = function() { - // Setup board - ChessGame.board = new ChessGame.Board(gamePosition, gameSize); - ChessGame.board.spawn(); - - // Setup white pieces - var isWhite = true; - var row = 1; - // King - var piece =ChessGame.makePiece(ChessGame.KING, row, 5, isWhite); - // Queen - piece = ChessGame.makePiece(ChessGame.QUEEN, row, 4, isWhite); - // Bishop - piece = ChessGame.makePiece(ChessGame.BISHOP, row, 3, isWhite); - piece = ChessGame.makePiece(ChessGame.BISHOP, row, 6, isWhite); - // Knight - piece = ChessGame.makePiece(ChessGame.KNIGHT, row, 2, isWhite); - piece = ChessGame.makePiece(ChessGame.KNIGHT, row, 7, isWhite); - // Rook - piece = ChessGame.makePiece(ChessGame.ROOK, row, 1, isWhite); - piece = ChessGame.makePiece(ChessGame.ROOK, row, 8, isWhite); - for(var j = 1; j <= 8; j++) { - piece = ChessGame.makePiece(ChessGame.PAWN, row + 1, j, isWhite); - } - - // Setup black pieces - isWhite = false; - row = 8; - // King - piece = ChessGame.makePiece(ChessGame.KING, row, 5, isWhite); - // Queen - piece = ChessGame.makePiece(ChessGame.QUEEN, row, 4, isWhite); - // Bishop - piece = ChessGame.makePiece(ChessGame.BISHOP, row, 3, isWhite); - piece = ChessGame.makePiece(ChessGame.BISHOP, row, 6, isWhite); - // Knight - piece = ChessGame.makePiece(ChessGame.KNIGHT, row, 2, isWhite); - piece = ChessGame.makePiece(ChessGame.KNIGHT, row, 7, isWhite); - // Rook - piece = ChessGame.makePiece(ChessGame.ROOK, row, 1, isWhite); - piece = ChessGame.makePiece(ChessGame.ROOK, row, 8, isWhite); - for(var j = 1; j <= 8; j++) { - piece = ChessGame.makePiece(ChessGame.PAWN, row - 1, j, isWhite); - } - - var metadataString = ChessGame.buildMetadataString(); - for (i in ChessGame.pieces) { - ChessGame.pieces[i].updateMetadata(metadataString); - } -} - - ChessGame.scriptStarting = function() { print("playChess.js started"); gamePosition = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -1 })); - ChessGame.buildBoard(); + // Setup board + ChessGame.board = new ChessGame.Board(gamePosition, gameSize); + ChessGame.board.spawn(); +} + +ChessGame.update = function() { + ChessGame.board.entity = Entities.identifyEntity(ChessGame.board.entity); + print(JSON.stringify(ChessGame.board.entity)); + if (ChessGame.board.entity.isKnownID && ChessGame.pieces.length == 0) { + // Setup white pieces + var isWhite = true; + var row = 1; + // King + ChessGame.makePiece(ChessGame.KING, row, 5, isWhite); + // Queen + ChessGame.makePiece(ChessGame.QUEEN, row, 4, isWhite); + // Bishop + ChessGame.makePiece(ChessGame.BISHOP, row, 3, isWhite); + ChessGame.makePiece(ChessGame.BISHOP, row, 6, isWhite); + // Knight + ChessGame.makePiece(ChessGame.KNIGHT, row, 2, isWhite); + ChessGame.makePiece(ChessGame.KNIGHT, row, 7, isWhite); + // Rook + ChessGame.makePiece(ChessGame.ROOK, row, 1, isWhite); + ChessGame.makePiece(ChessGame.ROOK, row, 8, isWhite); + for(var j = 1; j <= 8; j++) { + ChessGame.makePiece(ChessGame.PAWN, row + 1, j, isWhite); + } + + // Setup black pieces + isWhite = false; + row = 8; + // King + ChessGame.makePiece(ChessGame.KING, row, 5, isWhite); + // Queen + ChessGame.makePiece(ChessGame.QUEEN, row, 4, isWhite); + // Bishop + ChessGame.makePiece(ChessGame.BISHOP, row, 3, isWhite); + ChessGame.makePiece(ChessGame.BISHOP, row, 6, isWhite); + // Knight + ChessGame.makePiece(ChessGame.KNIGHT, row, 2, isWhite); + ChessGame.makePiece(ChessGame.KNIGHT, row, 7, isWhite); + // Rook + ChessGame.makePiece(ChessGame.ROOK, row, 1, isWhite); + ChessGame.makePiece(ChessGame.ROOK, row, 8, isWhite); + for(var j = 1; j <= 8; j++) { + ChessGame.makePiece(ChessGame.PAWN, row - 1, j, isWhite); + } + + Script.update.disconnect(ChessGame.update); + } } ChessGame.scriptEnding = function() { // Cleaning up board ChessGame.board.cleanup(); - delete ChessGame.board; // Cleaning up pieces for(var i in ChessGame.pieces) { ChessGame.pieces[i].cleanup(); } - delete ChessGame.pieces; print("playChess.js finished"); } Script.scriptEnding.connect(ChessGame.scriptEnding); +Script.update.connect(ChessGame.update); ChessGame.scriptStarting(); \ No newline at end of file From d9ae3eb5b61dc0216b900bcef094a8a7f8153545 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 14 Nov 2014 12:07:59 -0800 Subject: [PATCH 41/94] clean version of the simple stereo ack, not available for Occulus yet --- interface/src/renderer/Model.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 28bf1ddd3e..aeff8e9a67 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1505,10 +1505,11 @@ void Model::setupBatchTransform(gpu::Batch& batch) { void Model::endScene(RenderMode mode, RenderArgs* args) { PROFILE_RANGE(__FUNCTION__); - auto side = RenderArgs::MONO; - if (args) side = args->_renderSide; + RenderArgs::RenderSide renderSide = RenderArgs::MONO; + if (args) renderSide = args->_renderSide; - if (side != RenderArgs::STEREO_RIGHT) { + // Do the rendering batch creation for mono or left eye, not for right eye + if (renderSide != RenderArgs::STEREO_RIGHT) { // Let's introduce a gpu::Batch to capture all the calls to the graphics api _sceneRenderBatch.clear(); gpu::Batch& batch = _sceneRenderBatch; From cc35b83d318f4d3fcbaa43721da59423cd4a9742 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 14 Nov 2014 12:19:26 -0800 Subject: [PATCH 42/94] update pieces id --- examples/playChess.js | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/examples/playChess.js b/examples/playChess.js index da66d93677..1b3c643af7 100644 --- a/examples/playChess.js +++ b/examples/playChess.js @@ -199,7 +199,7 @@ ChessGame.scriptStarting = function() { ChessGame.update = function() { ChessGame.board.entity = Entities.identifyEntity(ChessGame.board.entity); - print(JSON.stringify(ChessGame.board.entity)); + if (ChessGame.board.entity.isKnownID && ChessGame.pieces.length == 0) { // Setup white pieces var isWhite = true; @@ -240,8 +240,25 @@ ChessGame.update = function() { for(var j = 1; j <= 8; j++) { ChessGame.makePiece(ChessGame.PAWN, row - 1, j, isWhite); } - - Script.update.disconnect(ChessGame.update); + } + + if (ChessGame.pieces.length > 0) { + var unknown = 0; + ChessGame.board.userDataObject.pieces = new Array(); + for(var i = 1; i < ChessGame.pieces.length; i++) { + ChessGame.pieces[i].entity = Entities.identifyEntity(ChessGame.pieces[i].entity); + if (ChessGame.pieces[i].entity.isKnownID) { + ChessGame.board.userDataObject.pieces.push(ChessGame.pieces[i].entity) + } else { + unknown++; + } + } + ChessGame.board.updateUserData(); + + if (unknown === 0) { + print("Board complete"); + Script.update.disconnect(ChessGame.update); + } } } From 4c40f5e7de1734a109e79b7f9214b212c710e4ef Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 14 Nov 2014 12:20:20 -0800 Subject: [PATCH 43/94] Changed entity scripts debug --- interface/src/entities/EntityTreeRenderer.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/interface/src/entities/EntityTreeRenderer.cpp b/interface/src/entities/EntityTreeRenderer.cpp index 99e4916c62..6357dfc71d 100644 --- a/interface/src/entities/EntityTreeRenderer.cpp +++ b/interface/src/entities/EntityTreeRenderer.cpp @@ -163,10 +163,12 @@ QScriptValue EntityTreeRenderer::loadEntityScript(EntityItem* entity) { QString scriptContents = loadScriptContents(entity->getScript()); - if (QScriptEngine::checkSyntax(scriptContents).state() != QScriptSyntaxCheckResult::Valid) { + QScriptSyntaxCheckResult syntaxCheck = QScriptEngine::checkSyntax(scriptContents); + if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) { qDebug() << "EntityTreeRenderer::loadEntityScript() entity:" << entityID; - qDebug() << " INVALID SYNTAX"; - qDebug() << " SCRIPT:" << scriptContents; + qDebug() << " " << syntaxCheck.errorMessage() << ":" + << syntaxCheck.errorLineNumber() << syntaxCheck.errorColumnNumber(); + qDebug() << " SCRIPT:" << entity->getScript(); return QScriptValue(); // invalid script } @@ -175,7 +177,7 @@ QScriptValue EntityTreeRenderer::loadEntityScript(EntityItem* entity) { if (!entityScriptConstructor.isFunction()) { qDebug() << "EntityTreeRenderer::loadEntityScript() entity:" << entityID; qDebug() << " NOT CONSTRUCTOR"; - qDebug() << " SCRIPT:" << scriptContents; + qDebug() << " SCRIPT:" << entity->getScript(); return QScriptValue(); // invalid script } From 14eb87aefd094c95fcde6c1fdf0d2e83f8df4b08 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 14 Nov 2014 12:23:47 -0800 Subject: [PATCH 44/94] Eliminate wacky scales in favor of newfangled "meters." --- interface/src/MetavoxelSystem.cpp | 3 +-- interface/src/ModelUploader.cpp | 2 +- interface/src/avatar/FaceModel.cpp | 3 +-- interface/src/avatar/SkeletonModel.cpp | 6 ++---- libraries/fbx/src/FBXReader.cpp | 2 +- 5 files changed, 6 insertions(+), 10 deletions(-) diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 4c0acc553a..5d8f77eedc 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -3164,8 +3164,7 @@ void StaticModelRenderer::applyRotation(const glm::quat& rotation) { } void StaticModelRenderer::applyScale(float scale) { - const float SCALE_MULTIPLIER = 0.0006f; - _model->setScale(glm::vec3(scale, scale, scale) * SCALE_MULTIPLIER); + _model->setScale(glm::vec3(scale, scale, scale)); } void StaticModelRenderer::applyURL(const QUrl& url) { diff --git a/interface/src/ModelUploader.cpp b/interface/src/ModelUploader.cpp index b117197f48..2599f39e83 100644 --- a/interface/src/ModelUploader.cpp +++ b/interface/src/ModelUploader.cpp @@ -157,7 +157,7 @@ bool ModelUploader::zip() { // mixamo/autodesk defaults if (!mapping.contains(SCALE_FIELD)) { - mapping.insert(SCALE_FIELD, 15.0); + mapping.insert(SCALE_FIELD, 1.0); } QVariantHash joints = mapping.value(JOINT_FIELD).toHash(); if (!joints.contains("jointEyeLeft")) { diff --git a/interface/src/avatar/FaceModel.cpp b/interface/src/avatar/FaceModel.cpp index 70f59f0661..5a30e8634d 100644 --- a/interface/src/avatar/FaceModel.cpp +++ b/interface/src/avatar/FaceModel.cpp @@ -34,8 +34,7 @@ void FaceModel::simulate(float deltaTime, bool fullUpdate) { neckParentRotation = owningAvatar->getOrientation(); } setRotation(neckParentRotation); - const float MODEL_SCALE = 0.0006f; - setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningHead->getScale() * MODEL_SCALE); + setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningHead->getScale()); setPupilDilation(_owningHead->getPupilDilation()); setBlendshapeCoefficients(_owningHead->getBlendshapeCoefficients()); diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index e760813fe5..7ca105f483 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -36,8 +36,6 @@ SkeletonModel::~SkeletonModel() { _ragdoll = NULL; } -const float MODEL_SCALE = 0.0006f; - void SkeletonModel::setJointStates(QVector states) { Model::setJointStates(states); @@ -57,7 +55,7 @@ void SkeletonModel::setJointStates(QVector states) { _defaultEyeModelPosition.z = -_defaultEyeModelPosition.z; // Skeleton may have already been scaled so unscale it - _defaultEyeModelPosition = MODEL_SCALE * _defaultEyeModelPosition / _scale; + _defaultEyeModelPosition = _defaultEyeModelPosition / _scale; } // the SkeletonModel override of updateJointState() will clear the translation part @@ -80,7 +78,7 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { setTranslation(_owningAvatar->getSkeletonPosition()); static const glm::quat refOrientation = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); setRotation(_owningAvatar->getOrientation() * refOrientation); - setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningAvatar->getScale() * MODEL_SCALE); + setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningAvatar->getScale()); setBlendshapeCoefficients(_owningAvatar->getHead()->getBlendshapeCoefficients()); Model::simulate(deltaTime, fullUpdate); diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 7ba5e7bc24..4ffd3f6286 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1456,7 +1456,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) } // get offset transform from mapping - float offsetScale = mapping.value("scale", 1.0f).toFloat() * unitScaleFactor; + float offsetScale = mapping.value("scale", 1.0f).toFloat() * unitScaleFactor * METERS_PER_CENTIMETER; glm::quat offsetRotation = glm::quat(glm::radians(glm::vec3(mapping.value("rx").toFloat(), mapping.value("ry").toFloat(), mapping.value("rz").toFloat()))); geometry.offset = glm::translate(glm::vec3(mapping.value("tx").toFloat(), mapping.value("ty").toFloat(), From 43a6a0420bdc650f9e10ca01cd34e013648d9a86 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 14 Nov 2014 12:24:38 -0800 Subject: [PATCH 45/94] remove useless comments --- interface/src/Application.h | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/Application.h b/interface/src/Application.h index 178849eec4..8ffad07122 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -262,7 +262,6 @@ public: QImage renderAvatarBillboard(); - // void displaySide(Camera& whichCamera, bool selfAvatarOnly = false); void displaySide(Camera& whichCamera, bool selfAvatarOnly = false, RenderArgs::RenderSide renderSide = RenderArgs::MONO); /// Stores the current modelview matrix as the untranslated view matrix to use for transforms and the supplied vector as From 4f878682a9df73fea04596f68e14021bc05b1a39 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 14 Nov 2014 12:38:50 -0800 Subject: [PATCH 46/94] fix syntax --- interface/src/renderer/Model.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index aeff8e9a67..fc3845d94f 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1506,7 +1506,9 @@ void Model::endScene(RenderMode mode, RenderArgs* args) { PROFILE_RANGE(__FUNCTION__); RenderArgs::RenderSide renderSide = RenderArgs::MONO; - if (args) renderSide = args->_renderSide; + if (args) { + renderSide = args->_renderSide; + } // Do the rendering batch creation for mono or left eye, not for right eye if (renderSide != RenderArgs::STEREO_RIGHT) { From 779f5f76145dd6ff573368e5955de2cadbd59cc8 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 14 Nov 2014 13:02:02 -0800 Subject: [PATCH 47/94] Default avatar fixes. --- interface/resources/meshes/defaultAvatar_body.fst | 2 +- interface/resources/meshes/defaultAvatar_head.fst | 2 +- libraries/avatars/src/AvatarData.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/resources/meshes/defaultAvatar_body.fst b/interface/resources/meshes/defaultAvatar_body.fst index 5874c206db..f061a87726 100644 --- a/interface/resources/meshes/defaultAvatar_body.fst +++ b/interface/resources/meshes/defaultAvatar_body.fst @@ -1,6 +1,6 @@ filename=defaultAvatar/body.fbx texdir=defaultAvatar -scale=130 +scale=8.666 joint = jointRoot = jointRoot joint = jointLean = jointSpine joint = jointNeck = jointNeck diff --git a/interface/resources/meshes/defaultAvatar_head.fst b/interface/resources/meshes/defaultAvatar_head.fst index 34cf44f0e4..c2478ce7d9 100644 --- a/interface/resources/meshes/defaultAvatar_head.fst +++ b/interface/resources/meshes/defaultAvatar_head.fst @@ -2,7 +2,7 @@ name= defaultAvatar_head filename=defaultAvatar/head.fbx texdir=defaultAvatar -scale=80 +scale=5.333 rx=0 ry=0 rz=0 diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 6b882a1389..c8e5e61d49 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -91,8 +91,8 @@ const float MAX_AUDIO_LOUDNESS = 1000.0; // close enough for mouth animation const int AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS = 1000; const int AVATAR_BILLBOARD_PACKET_SEND_INTERVAL_MSECS = 5000; -const QUrl DEFAULT_HEAD_MODEL_URL = QUrl("http://public.highfidelity.io/meshes/defaultAvatar_head.fst"); -const QUrl DEFAULT_BODY_MODEL_URL = QUrl("http://public.highfidelity.io/meshes/defaultAvatar_body.fst"); +const QUrl DEFAULT_HEAD_MODEL_URL = QUrl("http://public.highfidelity.io/models/heads/defaultAvatar_head.fst"); +const QUrl DEFAULT_BODY_MODEL_URL = QUrl("http://public.highfidelity.io/models/skeletons/defaultAvatar_body.fst"); enum KeyState { NO_KEY_DOWN = 0, From ba5491bc8b3233559b2ee944610e63fbb460ae32 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Fri, 14 Nov 2014 22:55:25 +0100 Subject: [PATCH 48/94] moved writeToClone to copy constructor --- interface/src/ui/overlays/Base3DOverlay.cpp | 22 ++++++------ interface/src/ui/overlays/Base3DOverlay.h | 3 +- .../src/ui/overlays/BillboardOverlay.cpp | 24 ++++++------- interface/src/ui/overlays/BillboardOverlay.h | 5 ++- interface/src/ui/overlays/Circle3DOverlay.cpp | 35 +++++++++--------- interface/src/ui/overlays/Circle3DOverlay.h | 3 +- interface/src/ui/overlays/Cube3DOverlay.cpp | 9 +++-- interface/src/ui/overlays/Cube3DOverlay.h | 1 + interface/src/ui/overlays/Grid3DOverlay.cpp | 17 +++++---- interface/src/ui/overlays/Grid3DOverlay.h | 3 +- interface/src/ui/overlays/ImageOverlay.cpp | 23 ++++++------ interface/src/ui/overlays/ImageOverlay.h | 2 +- interface/src/ui/overlays/Line3DOverlay.cpp | 16 ++++----- interface/src/ui/overlays/Line3DOverlay.h | 3 +- .../src/ui/overlays/LocalModelsOverlay.cpp | 11 ++++-- .../src/ui/overlays/LocalModelsOverlay.h | 1 + .../src/ui/overlays/LocalVoxelsOverlay.cpp | 10 ++++-- .../src/ui/overlays/LocalVoxelsOverlay.h | 1 + interface/src/ui/overlays/ModelOverlay.cpp | 32 +++++++++-------- interface/src/ui/overlays/ModelOverlay.h | 4 +-- interface/src/ui/overlays/Overlay.cpp | 36 ++++++++++--------- interface/src/ui/overlays/Overlay.h | 2 +- interface/src/ui/overlays/Overlay2D.cpp | 12 +++---- interface/src/ui/overlays/Overlay2D.h | 4 +-- interface/src/ui/overlays/Planar3DOverlay.cpp | 11 +++--- interface/src/ui/overlays/Planar3DOverlay.h | 2 +- .../src/ui/overlays/Rectangle3DOverlay.cpp | 9 +++-- .../src/ui/overlays/Rectangle3DOverlay.h | 1 + interface/src/ui/overlays/Sphere3DOverlay.cpp | 9 +++-- interface/src/ui/overlays/Sphere3DOverlay.h | 1 + interface/src/ui/overlays/Text3DOverlay.cpp | 30 ++++++++-------- interface/src/ui/overlays/Text3DOverlay.h | 2 +- interface/src/ui/overlays/TextOverlay.cpp | 24 ++++++------- interface/src/ui/overlays/TextOverlay.h | 3 +- interface/src/ui/overlays/Volume3DOverlay.cpp | 10 +++--- interface/src/ui/overlays/Volume3DOverlay.h | 2 +- 36 files changed, 201 insertions(+), 182 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index aae2acf61e..7ed7079795 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -31,6 +31,17 @@ Base3DOverlay::Base3DOverlay() : { } +Base3DOverlay::Base3DOverlay(Base3DOverlay* base3DOverlay) : + Overlay(base3DOverlay), + _position(base3DOverlay->_position), + _lineWidth(base3DOverlay->_lineWidth), + _rotation(base3DOverlay->_rotation), + _isSolid(base3DOverlay->_isSolid), + _isDashedLine(base3DOverlay->_isDashedLine), + _ignoreRayIntersection(base3DOverlay->_ignoreRayIntersection) +{ +} + Base3DOverlay::~Base3DOverlay() { } @@ -178,15 +189,4 @@ void Base3DOverlay::drawDashedLine(const glm::vec3& start, const glm::vec3& end) glVertex3f(end.x, end.y, end.z); glEnd(); - -} - -void Base3DOverlay::writeToClone(Base3DOverlay* clone) { - Overlay::writeToClone(clone); - clone->setPosition(getPosition()); - clone->setLineWidth(getLineWidth()); - clone->setIsSolid(getIsSolid()); - clone->setIsDashedLine(getIsDashedLine()); - clone->setRotation(getRotation()); - clone->setIgnoreRayIntersection(getIgnoreRayIntersection()); } diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index f4032f2015..4422203566 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -23,6 +23,7 @@ class Base3DOverlay : public Overlay { public: Base3DOverlay(); + Base3DOverlay(Base3DOverlay* base3DOverlay); ~Base3DOverlay(); // getters @@ -55,7 +56,6 @@ public: } protected: - virtual void writeToClone(Base3DOverlay* clone); void drawDashedLine(const glm::vec3& start, const glm::vec3& end); glm::vec3 _position; @@ -65,6 +65,5 @@ protected: bool _isDashedLine; bool _ignoreRayIntersection; }; - #endif // hifi_Base3DOverlay_h diff --git a/interface/src/ui/overlays/BillboardOverlay.cpp b/interface/src/ui/overlays/BillboardOverlay.cpp index b570576380..87c8f8bb74 100644 --- a/interface/src/ui/overlays/BillboardOverlay.cpp +++ b/interface/src/ui/overlays/BillboardOverlay.cpp @@ -24,6 +24,17 @@ BillboardOverlay::BillboardOverlay() : _isLoaded = false; } +BillboardOverlay::BillboardOverlay(BillboardOverlay* billboardOverlay) : + Base3DOverlay(billboardOverlay), + _newTextureNeeded(true), + _scale(billboardOverlay->_scale), + _isFacingAvatar(billboardOverlay->_isFacingAvatar), + _fromImage(billboardOverlay->_fromImage), + _url(billboardOverlay->_url), + _billboard(billboardOverlay->_billboard) +{ +} + void BillboardOverlay::render(RenderArgs* args) { if (!_visible || !_isLoaded) { return; @@ -216,16 +227,5 @@ bool BillboardOverlay::findRayIntersection(const glm::vec3& origin, const glm::v } BillboardOverlay* BillboardOverlay::createClone() { - BillboardOverlay* clone = new BillboardOverlay(); - writeToClone(clone); - return clone; -} - -void BillboardOverlay::writeToClone(BillboardOverlay* clone) { - Base3DOverlay::writeToClone(clone); - clone->setScale(_scale); - clone->setIsFacingAvatar(_isFacingAvatar); - clone->setClipFromSource(_fromImage); - clone->_url = _url; - clone->_billboard = _billboard; + return new BillboardOverlay(this); } diff --git a/interface/src/ui/overlays/BillboardOverlay.h b/interface/src/ui/overlays/BillboardOverlay.h index e967aba408..e8c25c8549 100644 --- a/interface/src/ui/overlays/BillboardOverlay.h +++ b/interface/src/ui/overlays/BillboardOverlay.h @@ -22,7 +22,8 @@ class BillboardOverlay : public Base3DOverlay { Q_OBJECT public: BillboardOverlay(); - + BillboardOverlay(BillboardOverlay* billboardOverlay); + virtual void render(RenderArgs* args); // setters @@ -42,8 +43,6 @@ private slots: void replyFinished(); private: - virtual void writeToClone(BillboardOverlay* clone); - void setBillboardURL(const QString& url); QString _url; diff --git a/interface/src/ui/overlays/Circle3DOverlay.cpp b/interface/src/ui/overlays/Circle3DOverlay.cpp index 1258ee56c5..6c0c82f3ec 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.cpp +++ b/interface/src/ui/overlays/Circle3DOverlay.cpp @@ -33,6 +33,22 @@ Circle3DOverlay::Circle3DOverlay() : _minorTickMarksColor.red = _minorTickMarksColor.green = _minorTickMarksColor.blue = (unsigned char)0; } +Circle3DOverlay::Circle3DOverlay(Circle3DOverlay* circle3DOverlay) : + Planar3DOverlay(circle3DOverlay), + _startAt(circle3DOverlay->_startAt), + _endAt(circle3DOverlay->_endAt), + _outerRadius(circle3DOverlay->_outerRadius), + _innerRadius(circle3DOverlay->_innerRadius), + _hasTickMarks(circle3DOverlay->_hasTickMarks), + _majorTickMarksAngle(circle3DOverlay->_majorTickMarksAngle), + _minorTickMarksAngle(circle3DOverlay->_minorTickMarksAngle), + _majorTickMarksLength(circle3DOverlay->_majorTickMarksLength), + _minorTickMarksLength(circle3DOverlay->_minorTickMarksLength), + _majorTickMarksColor(circle3DOverlay->_majorTickMarksColor), + _minorTickMarksColor(circle3DOverlay->_minorTickMarksColor) +{ +} + Circle3DOverlay::~Circle3DOverlay() { } @@ -359,22 +375,5 @@ bool Circle3DOverlay::findRayIntersection(const glm::vec3& origin, } Circle3DOverlay* Circle3DOverlay::createClone() { - Circle3DOverlay* clone = new Circle3DOverlay(); - writeToClone(clone); - return clone; -} - -void Circle3DOverlay::writeToClone(Circle3DOverlay* clone) { - Planar3DOverlay::writeToClone(clone); - clone->setStartAt(getStartAt()); - clone->setEndAt(getEndAt()); - clone->setOuterRadius(getOuterRadius()); - clone->setInnerRadius(getInnerRadius()); - clone->setHasTickMarks(getHasTickMarks()); - clone->setMajorTickMarksAngle(getMajorTickMarksAngle()); - clone->setMinorTickMarksAngle(getMinorTickMarksAngle()); - clone->setMajorTickMarksLength(getMajorTickMarksLength()); - clone->setMinorTickMarksLength(getMinorTickMarksLength()); - clone->setMajorTickMarksColor(getMajorTickMarksColor()); - clone->setMinorTickMarksColor(getMinorTickMarksColor()); + return new Circle3DOverlay(this); } diff --git a/interface/src/ui/overlays/Circle3DOverlay.h b/interface/src/ui/overlays/Circle3DOverlay.h index 85bda28d46..cf9fc8e2fc 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.h +++ b/interface/src/ui/overlays/Circle3DOverlay.h @@ -18,6 +18,7 @@ class Circle3DOverlay : public Planar3DOverlay { public: Circle3DOverlay(); + Circle3DOverlay(Circle3DOverlay* circle3DOverlay); ~Circle3DOverlay(); virtual void render(RenderArgs* args); virtual void setProperties(const QScriptValue& properties); @@ -52,8 +53,6 @@ public: virtual Circle3DOverlay* createClone(); protected: - virtual void writeToClone(Circle3DOverlay* clone); - float _startAt; float _endAt; float _outerRadius; diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 9bf3de90c0..2aa4d29f23 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -22,6 +22,11 @@ Cube3DOverlay::Cube3DOverlay() { } +Cube3DOverlay::Cube3DOverlay(Cube3DOverlay* cube3DOverlay) : + Volume3DOverlay(cube3DOverlay) +{ +} + Cube3DOverlay::~Cube3DOverlay() { } @@ -104,7 +109,5 @@ void Cube3DOverlay::render(RenderArgs* args) { } Cube3DOverlay* Cube3DOverlay::createClone() { - Cube3DOverlay* clone = new Cube3DOverlay(); - writeToClone(clone); - return clone; + return new Cube3DOverlay(this); } diff --git a/interface/src/ui/overlays/Cube3DOverlay.h b/interface/src/ui/overlays/Cube3DOverlay.h index 0b7b9e14a3..4fe137b73c 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.h +++ b/interface/src/ui/overlays/Cube3DOverlay.h @@ -18,6 +18,7 @@ class Cube3DOverlay : public Volume3DOverlay { public: Cube3DOverlay(); + Cube3DOverlay(Cube3DOverlay* cube3DOverlay); ~Cube3DOverlay(); virtual void render(RenderArgs* args); diff --git a/interface/src/ui/overlays/Grid3DOverlay.cpp b/interface/src/ui/overlays/Grid3DOverlay.cpp index 62ba5d1e78..601413226a 100644 --- a/interface/src/ui/overlays/Grid3DOverlay.cpp +++ b/interface/src/ui/overlays/Grid3DOverlay.cpp @@ -20,6 +20,13 @@ Grid3DOverlay::Grid3DOverlay() : Base3DOverlay(), _majorGridEvery(5) { } +Grid3DOverlay::Grid3DOverlay(Grid3DOverlay* grid3DOverlay) : + Base3DOverlay(grid3DOverlay), + _minorGridWidth(grid3DOverlay->_minorGridWidth), + _majorGridEvery(grid3DOverlay->_majorGridEvery) +{ +} + Grid3DOverlay::~Grid3DOverlay() { } @@ -129,13 +136,5 @@ QScriptValue Grid3DOverlay::getProperty(const QString& property) { } Grid3DOverlay* Grid3DOverlay::createClone() { - Grid3DOverlay* clone = new Grid3DOverlay(); - writeToClone(clone); - return clone; -} - -void Grid3DOverlay::writeToClone(Grid3DOverlay* clone) { - Base3DOverlay::writeToClone(clone); - clone->_minorGridWidth = _minorGridWidth; - clone->_majorGridEvery = _majorGridEvery; + return new Grid3DOverlay(this); } diff --git a/interface/src/ui/overlays/Grid3DOverlay.h b/interface/src/ui/overlays/Grid3DOverlay.h index 1a1841cd96..28dfbf9de7 100644 --- a/interface/src/ui/overlays/Grid3DOverlay.h +++ b/interface/src/ui/overlays/Grid3DOverlay.h @@ -29,6 +29,7 @@ class Grid3DOverlay : public Base3DOverlay { public: Grid3DOverlay(); + Grid3DOverlay(Grid3DOverlay* grid3DOverlay); ~Grid3DOverlay(); virtual void render(RenderArgs* args); @@ -38,8 +39,6 @@ public: virtual Grid3DOverlay* createClone(); private: - virtual void writeToClone(Grid3DOverlay* clone); - float _minorGridWidth; int _majorGridEvery; diff --git a/interface/src/ui/overlays/ImageOverlay.cpp b/interface/src/ui/overlays/ImageOverlay.cpp index 7c6d576698..dd06ee4da2 100644 --- a/interface/src/ui/overlays/ImageOverlay.cpp +++ b/interface/src/ui/overlays/ImageOverlay.cpp @@ -27,6 +27,17 @@ ImageOverlay::ImageOverlay() : _isLoaded = false; } +ImageOverlay::ImageOverlay(ImageOverlay* imageOverlay) : + Overlay2D(imageOverlay), + _textureID(0), + _textureBound(false), + _wantClipFromImage(false), + _renderImage(imageOverlay->_renderImage), + _imageURL(imageOverlay->_imageURL), + _textureImage(imageOverlay->_textureImage) +{ +} + ImageOverlay::~ImageOverlay() { if (_parent && _textureID) { // do we need to call this? @@ -162,15 +173,5 @@ QScriptValue ImageOverlay::getProperty(const QString& property) { return Overlay2D::getProperty(property); } ImageOverlay* ImageOverlay::createClone() { - ImageOverlay* clone = new ImageOverlay(); - writeToClone(clone); - return clone; + return new ImageOverlay(this); } - -void ImageOverlay::writeToClone(ImageOverlay* clone) { - Overlay2D::writeToClone(clone); - clone->_imageURL = _imageURL; - clone->_textureImage = _textureImage; - clone->_renderImage = _renderImage; -} - diff --git a/interface/src/ui/overlays/ImageOverlay.h b/interface/src/ui/overlays/ImageOverlay.h index 54f50dad2d..9c8d48a2e2 100644 --- a/interface/src/ui/overlays/ImageOverlay.h +++ b/interface/src/ui/overlays/ImageOverlay.h @@ -33,6 +33,7 @@ class ImageOverlay : public Overlay2D { public: ImageOverlay(); + ImageOverlay(ImageOverlay* imageOverlay); ~ImageOverlay(); virtual void render(RenderArgs* args); @@ -52,7 +53,6 @@ private slots: void replyFinished(); // we actually want to hide this... private: - virtual void writeToClone(ImageOverlay* clone); QUrl _imageURL; QImage _textureImage; diff --git a/interface/src/ui/overlays/Line3DOverlay.cpp b/interface/src/ui/overlays/Line3DOverlay.cpp index 7ecc7eb1f8..aac773f08f 100644 --- a/interface/src/ui/overlays/Line3DOverlay.cpp +++ b/interface/src/ui/overlays/Line3DOverlay.cpp @@ -18,6 +18,12 @@ Line3DOverlay::Line3DOverlay() { } +Line3DOverlay::Line3DOverlay(Line3DOverlay* line3DOverlay) : + Base3DOverlay(line3DOverlay), + _end(line3DOverlay->_end) +{ +} + Line3DOverlay::~Line3DOverlay() { } @@ -89,13 +95,5 @@ QScriptValue Line3DOverlay::getProperty(const QString& property) { } Line3DOverlay* Line3DOverlay::createClone() { - Line3DOverlay* clone = new Line3DOverlay(); - writeToClone(clone); - return clone; + return new Line3DOverlay(this); } - -void Line3DOverlay::writeToClone(Line3DOverlay* clone) { - Base3DOverlay::writeToClone(clone); - clone->setEnd(getEnd()); -} - diff --git a/interface/src/ui/overlays/Line3DOverlay.h b/interface/src/ui/overlays/Line3DOverlay.h index 5d7d9cbe3a..3d481438b9 100644 --- a/interface/src/ui/overlays/Line3DOverlay.h +++ b/interface/src/ui/overlays/Line3DOverlay.h @@ -18,6 +18,7 @@ class Line3DOverlay : public Base3DOverlay { public: Line3DOverlay(); + Line3DOverlay(Line3DOverlay* line3DOverlay); ~Line3DOverlay(); virtual void render(RenderArgs* args); @@ -33,8 +34,6 @@ public: virtual Line3DOverlay* createClone(); protected: - virtual void writeToClone(Line3DOverlay* clone); - glm::vec3 _end; }; diff --git a/interface/src/ui/overlays/LocalModelsOverlay.cpp b/interface/src/ui/overlays/LocalModelsOverlay.cpp index 7f1faf3a39..25cb0ead64 100644 --- a/interface/src/ui/overlays/LocalModelsOverlay.cpp +++ b/interface/src/ui/overlays/LocalModelsOverlay.cpp @@ -18,6 +18,13 @@ LocalModelsOverlay::LocalModelsOverlay(EntityTreeRenderer* entityTreeRenderer) : _entityTreeRenderer(entityTreeRenderer) { } +LocalModelsOverlay::LocalModelsOverlay(EntityTreeRenderer* entityTreeRenderer, LocalModelsOverlay* localModelsOverlay) : + Volume3DOverlay(localModelsOverlay), + _entityTreeRenderer(entityTreeRenderer) +{ + +} + LocalModelsOverlay::~LocalModelsOverlay() { } @@ -50,7 +57,5 @@ void LocalModelsOverlay::render(RenderArgs* args) { } LocalModelsOverlay* LocalModelsOverlay::createClone() { - LocalModelsOverlay* clone = new LocalModelsOverlay(Application::getInstance()->getEntityClipboardRenderer()); - writeToClone(clone); - return clone; + return new LocalModelsOverlay(Application::getInstance()->getEntityClipboardRenderer(), this); } diff --git a/interface/src/ui/overlays/LocalModelsOverlay.h b/interface/src/ui/overlays/LocalModelsOverlay.h index 0659de0ab1..c38bc6b2a3 100644 --- a/interface/src/ui/overlays/LocalModelsOverlay.h +++ b/interface/src/ui/overlays/LocalModelsOverlay.h @@ -20,6 +20,7 @@ class LocalModelsOverlay : public Volume3DOverlay { Q_OBJECT public: LocalModelsOverlay(EntityTreeRenderer* entityTreeRenderer); + LocalModelsOverlay(EntityTreeRenderer* entityTreeRenderer, LocalModelsOverlay* localModelsOverlay); ~LocalModelsOverlay(); virtual void update(float deltatime); diff --git a/interface/src/ui/overlays/LocalVoxelsOverlay.cpp b/interface/src/ui/overlays/LocalVoxelsOverlay.cpp index eab833aea3..4c44fe6dd8 100644 --- a/interface/src/ui/overlays/LocalVoxelsOverlay.cpp +++ b/interface/src/ui/overlays/LocalVoxelsOverlay.cpp @@ -28,6 +28,12 @@ LocalVoxelsOverlay::LocalVoxelsOverlay() : { } +LocalVoxelsOverlay::LocalVoxelsOverlay(LocalVoxelsOverlay* localVoxelsOverlay) : + Volume3DOverlay(localVoxelsOverlay), + _voxelCount(localVoxelsOverlay->_voxelCount) +{ +} + LocalVoxelsOverlay::~LocalVoxelsOverlay() { _voxelSystem->changeTree(new VoxelTree()); _voxelSystem.clear(); @@ -104,9 +110,7 @@ void LocalVoxelsOverlay::setProperties(const QScriptValue &properties) { } LocalVoxelsOverlay* LocalVoxelsOverlay::createClone() { - LocalVoxelsOverlay* clone = new LocalVoxelsOverlay(); - writeToClone(clone); - return clone; + return new LocalVoxelsOverlay(this); } QScriptValue LocalVoxelsOverlay::getProperty(const QString& property) { diff --git a/interface/src/ui/overlays/LocalVoxelsOverlay.h b/interface/src/ui/overlays/LocalVoxelsOverlay.h index 5c75c13db7..3e5bbbc5b6 100644 --- a/interface/src/ui/overlays/LocalVoxelsOverlay.h +++ b/interface/src/ui/overlays/LocalVoxelsOverlay.h @@ -32,6 +32,7 @@ class LocalVoxelsOverlay : public Volume3DOverlay { Q_OBJECT public: LocalVoxelsOverlay(); + LocalVoxelsOverlay(LocalVoxelsOverlay* localVoxelsOverlay); ~LocalVoxelsOverlay(); virtual void update(float deltatime); diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 9edb744b41..f1c588f45d 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -22,6 +22,22 @@ ModelOverlay::ModelOverlay() _isLoaded = false; } +ModelOverlay::ModelOverlay(ModelOverlay* modelOverlay) : + Base3DOverlay(modelOverlay), + _model(), + _modelTextures(QVariantMap()), + _scale(modelOverlay->_scale), + _updateModel(false), + _url(modelOverlay->_url), + _rotation(modelOverlay->_rotation) +{ + _model.init(); + if (_url.isValid()) { + _updateModel = true; + _isLoaded = false; + } +} + void ModelOverlay::update(float deltatime) { if (_updateModel) { _updateModel = false; @@ -167,19 +183,5 @@ bool ModelOverlay::findRayIntersectionExtraInfo(const glm::vec3& origin, const g } ModelOverlay* ModelOverlay::createClone() { - ModelOverlay* clone = new ModelOverlay(); - writeToClone(clone); - return clone; -} - -void ModelOverlay::writeToClone(ModelOverlay* clone) { - Base3DOverlay::writeToClone(clone); - clone->_url = _url; - if (clone->_url.isValid()) { - clone->_updateModel = true; - clone->_isLoaded = false; - } - clone->_rotation = _rotation; - clone->_scale = _scale; - clone->_updateModel = _updateModel; + return new ModelOverlay(this); } diff --git a/interface/src/ui/overlays/ModelOverlay.h b/interface/src/ui/overlays/ModelOverlay.h index 9c59a1ddd8..393e09c78b 100644 --- a/interface/src/ui/overlays/ModelOverlay.h +++ b/interface/src/ui/overlays/ModelOverlay.h @@ -20,7 +20,8 @@ class ModelOverlay : public Base3DOverlay { Q_OBJECT public: ModelOverlay(); - + ModelOverlay(ModelOverlay* modelOverlay); + virtual void update(float deltatime); virtual void render(RenderArgs* args); virtual void setProperties(const QScriptValue& properties); @@ -32,7 +33,6 @@ public: virtual ModelOverlay* createClone(); private: - virtual void writeToClone(ModelOverlay* clone); Model _model; QVariantMap _modelTextures; diff --git a/interface/src/ui/overlays/Overlay.cpp b/interface/src/ui/overlays/Overlay.cpp index 8544eacc39..e67c1572f1 100644 --- a/interface/src/ui/overlays/Overlay.cpp +++ b/interface/src/ui/overlays/Overlay.cpp @@ -39,12 +39,30 @@ Overlay::Overlay() : { } +Overlay::Overlay(Overlay* overlay) : + _parent(NULL), + _alpha(overlay->_alpha), + _lastPulseUpdate(usecTimestampNow()), + _alphaPulse(overlay->_alphaPulse), + _anchor(overlay->_anchor), + _color(overlay->_color), + _colorPulse(overlay->_colorPulse), + _glowLevel(overlay->_glowLevel), + _glowLevelPulse(overlay->_glowLevelPulse), + _pulseDirection(overlay->_pulseDirection), + _pulseMax(overlay->_pulseMax), + _pulseMin(overlay->_pulseMin), + _pulsePeriod(overlay->_pulsePeriod), + _visible(overlay->_visible), + _isLoaded(overlay->_isLoaded) +{ +} + void Overlay::init(QGLWidget* parent, QScriptEngine* scriptEngine) { _parent = parent; _scriptEngine = scriptEngine; } - Overlay::~Overlay() { } @@ -212,19 +230,3 @@ float Overlay::updatePulse() { return _pulse; } - -void Overlay::writeToClone(Overlay* clone) { - clone->setAlpha(getAlpha()); - clone->setAlphaPulse(getAlphaPulse()); - clone->setAnchor(getAnchor()); - clone->setColor(getColor()); - clone->setColorPulse(getColorPulse()); - clone->setGlowLevel(getGlowLevel()); - clone->setGlowLevelPulse(getGlowLevelPulse()); - clone->setPulseDirection(getPulseDirection()); - clone->setPulseMax(getPulseMax()); - clone->setPulseMin(getPulseMin()); - clone->setPulsePeriod(getPulsePeriod()); - clone->setVisible(getVisible()); - clone->_isLoaded = _isLoaded; -} diff --git a/interface/src/ui/overlays/Overlay.h b/interface/src/ui/overlays/Overlay.h index 0efd7174b4..341a7b56a3 100644 --- a/interface/src/ui/overlays/Overlay.h +++ b/interface/src/ui/overlays/Overlay.h @@ -36,6 +36,7 @@ public: }; Overlay(); + Overlay(Overlay* overlay); ~Overlay(); void init(QGLWidget* parent, QScriptEngine* scriptEngine); virtual void update(float deltatime) {} @@ -82,7 +83,6 @@ public: virtual QScriptValue getProperty(const QString& property); protected: - virtual void writeToClone(Overlay* clone); float updatePulse(); QGLWidget* _parent; diff --git a/interface/src/ui/overlays/Overlay2D.cpp b/interface/src/ui/overlays/Overlay2D.cpp index ccbecb31a2..53ef9cdf29 100644 --- a/interface/src/ui/overlays/Overlay2D.cpp +++ b/interface/src/ui/overlays/Overlay2D.cpp @@ -22,6 +22,12 @@ Overlay2D::Overlay2D() { } +Overlay2D::Overlay2D(Overlay2D* overlay2D) : + Overlay(overlay2D), + _bounds(overlay2D->_bounds) +{ +} + Overlay2D::~Overlay2D() { } @@ -84,9 +90,3 @@ QScriptValue Overlay2D::getProperty(const QString& property) { return Overlay::getProperty(property); } - -void Overlay2D::writeToClone(Overlay2D* clone) { - Overlay::writeToClone(clone); - clone->setBounds(getBounds()); -} - diff --git a/interface/src/ui/overlays/Overlay2D.h b/interface/src/ui/overlays/Overlay2D.h index 31b1bd351e..ea3936c2c7 100644 --- a/interface/src/ui/overlays/Overlay2D.h +++ b/interface/src/ui/overlays/Overlay2D.h @@ -28,6 +28,7 @@ class Overlay2D : public Overlay { public: Overlay2D(); + Overlay2D(Overlay2D* overlay2D); ~Overlay2D(); virtual bool is3D() const { return false; } @@ -43,14 +44,13 @@ public: void setX(int x) { _bounds.setX(x); } void setY(int y) { _bounds.setY(y); } void setWidth(int width) { _bounds.setWidth(width); } - void setHeight(int height) { _bounds.setHeight(height); } + void setHeight(int height) { _bounds.setHeight(height); } void setBounds(const QRect& bounds) { _bounds = bounds; } virtual void setProperties(const QScriptValue& properties); virtual QScriptValue getProperty(const QString& property); protected: - virtual void writeToClone(Overlay2D* clone); QRect _bounds; // where on the screen to draw }; diff --git a/interface/src/ui/overlays/Planar3DOverlay.cpp b/interface/src/ui/overlays/Planar3DOverlay.cpp index 08c765c5ee..390b92948c 100644 --- a/interface/src/ui/overlays/Planar3DOverlay.cpp +++ b/interface/src/ui/overlays/Planar3DOverlay.cpp @@ -26,6 +26,12 @@ Planar3DOverlay::Planar3DOverlay() : { } +Planar3DOverlay::Planar3DOverlay(Planar3DOverlay* planar3DOverlay) : + Base3DOverlay(planar3DOverlay), + _dimensions(planar3DOverlay->_dimensions) +{ +} + Planar3DOverlay::~Planar3DOverlay() { } @@ -110,8 +116,3 @@ bool Planar3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::ve } return intersects; } - -void Planar3DOverlay::writeToClone(Planar3DOverlay* clone) { - Base3DOverlay::writeToClone(clone); - clone->setDimensions(getDimensions()); -} diff --git a/interface/src/ui/overlays/Planar3DOverlay.h b/interface/src/ui/overlays/Planar3DOverlay.h index 2f6c4a561b..7de68e24b2 100644 --- a/interface/src/ui/overlays/Planar3DOverlay.h +++ b/interface/src/ui/overlays/Planar3DOverlay.h @@ -26,6 +26,7 @@ class Planar3DOverlay : public Base3DOverlay { public: Planar3DOverlay(); + Planar3DOverlay(Planar3DOverlay* planar3DOverlay); ~Planar3DOverlay(); // getters @@ -41,7 +42,6 @@ public: virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const; protected: - virtual void writeToClone(Planar3DOverlay* clone); glm::vec2 _dimensions; }; diff --git a/interface/src/ui/overlays/Rectangle3DOverlay.cpp b/interface/src/ui/overlays/Rectangle3DOverlay.cpp index 728accfad6..a2043d77c1 100644 --- a/interface/src/ui/overlays/Rectangle3DOverlay.cpp +++ b/interface/src/ui/overlays/Rectangle3DOverlay.cpp @@ -20,6 +20,11 @@ Rectangle3DOverlay::Rectangle3DOverlay() { } +Rectangle3DOverlay::Rectangle3DOverlay(Rectangle3DOverlay* rectangle3DOverlay) : + Planar3DOverlay(rectangle3DOverlay) +{ +} + Rectangle3DOverlay::~Rectangle3DOverlay() { } @@ -107,7 +112,5 @@ void Rectangle3DOverlay::setProperties(const QScriptValue &properties) { } Rectangle3DOverlay* Rectangle3DOverlay::createClone() { - Rectangle3DOverlay* clone = new Rectangle3DOverlay(); - writeToClone(clone); - return clone; + return new Rectangle3DOverlay(this); } diff --git a/interface/src/ui/overlays/Rectangle3DOverlay.h b/interface/src/ui/overlays/Rectangle3DOverlay.h index 0bb805200c..98e04324b4 100644 --- a/interface/src/ui/overlays/Rectangle3DOverlay.h +++ b/interface/src/ui/overlays/Rectangle3DOverlay.h @@ -18,6 +18,7 @@ class Rectangle3DOverlay : public Planar3DOverlay { public: Rectangle3DOverlay(); + Rectangle3DOverlay(Rectangle3DOverlay* rectangle3DOverlay); ~Rectangle3DOverlay(); virtual void render(RenderArgs* args); virtual void setProperties(const QScriptValue& properties); diff --git a/interface/src/ui/overlays/Sphere3DOverlay.cpp b/interface/src/ui/overlays/Sphere3DOverlay.cpp index ef4e2ba51b..30bb7d1c52 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.cpp +++ b/interface/src/ui/overlays/Sphere3DOverlay.cpp @@ -21,6 +21,11 @@ Sphere3DOverlay::Sphere3DOverlay() { } +Sphere3DOverlay::Sphere3DOverlay(Sphere3DOverlay* Sphere3DOverlay) : + Volume3DOverlay(Sphere3DOverlay) +{ +} + Sphere3DOverlay::~Sphere3DOverlay() { } @@ -72,7 +77,5 @@ void Sphere3DOverlay::render(RenderArgs* args) { } Sphere3DOverlay* Sphere3DOverlay::createClone() { - Sphere3DOverlay* clone = new Sphere3DOverlay(); - writeToClone(clone); - return clone; + return new Sphere3DOverlay(this); } diff --git a/interface/src/ui/overlays/Sphere3DOverlay.h b/interface/src/ui/overlays/Sphere3DOverlay.h index f9db6b99af..2f63c4fe48 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.h +++ b/interface/src/ui/overlays/Sphere3DOverlay.h @@ -18,6 +18,7 @@ class Sphere3DOverlay : public Volume3DOverlay { public: Sphere3DOverlay(); + Sphere3DOverlay(Sphere3DOverlay* Sphere3DOverlay); ~Sphere3DOverlay(); virtual void render(RenderArgs* args); diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index 9af96cad7e..0a83ec80f5 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -31,6 +31,19 @@ Text3DOverlay::Text3DOverlay() : { } +Text3DOverlay::Text3DOverlay(Text3DOverlay* text3DOverlay) : + Planar3DOverlay(text3DOverlay), + _text(text3DOverlay->_text), + _backgroundColor(text3DOverlay->_backgroundColor), + _lineHeight(text3DOverlay->_lineHeight), + _leftMargin(text3DOverlay->_leftMargin), + _topMargin(text3DOverlay->_topMargin), + _rightMargin(text3DOverlay->_rightMargin), + _bottomMargin(text3DOverlay->_bottomMargin), + _isFacingAvatar(text3DOverlay->_isFacingAvatar) +{ +} + Text3DOverlay::~Text3DOverlay() { } @@ -172,7 +185,6 @@ void Text3DOverlay::setProperties(const QScriptValue& properties) { setBottomMargin(properties.property("bottomMargin").toVariant().toFloat()); } - QScriptValue isFacingAvatarValue = properties.property("isFacingAvatar"); if (isFacingAvatarValue.isValid()) { _isFacingAvatar = isFacingAvatarValue.toVariant().toBool(); @@ -207,10 +219,9 @@ QScriptValue Text3DOverlay::getProperty(const QString& property) { } return Planar3DOverlay::getProperty(property); } + Text3DOverlay* Text3DOverlay::createClone() { - Text3DOverlay* clone = new Text3DOverlay(); - writeToClone(clone); - return clone; + return new Text3DOverlay(this);; } float Text3DOverlay::textWidth(const QString& text) const { @@ -220,15 +231,4 @@ float Text3DOverlay::textWidth(const QString& text) const { return scaleFactor * (float)fontMetrics.width(qPrintable(text)); } -void Text3DOverlay::writeToClone(Text3DOverlay* clone) { - Planar3DOverlay::writeToClone(clone); - clone->setText(getText()); - clone->setLineHeight(getLineHeight()); - clone->setLeftMargin(getLeftMargin()); - clone->setTopMargin(getTopMargin()); - clone->setRightMargin(getRightMargin()); - clone->setBottomMargin(getBottomMargin()); - clone->setIsFacingAvatar(getIsFacingAvatar()); - clone->_backgroundColor = getBackgroundColor(); -} diff --git a/interface/src/ui/overlays/Text3DOverlay.h b/interface/src/ui/overlays/Text3DOverlay.h index a72efe7564..c459b2eb36 100644 --- a/interface/src/ui/overlays/Text3DOverlay.h +++ b/interface/src/ui/overlays/Text3DOverlay.h @@ -24,6 +24,7 @@ class Text3DOverlay : public Planar3DOverlay { public: Text3DOverlay(); + Text3DOverlay(Text3DOverlay* text3DOverlay); ~Text3DOverlay(); virtual void render(RenderArgs* args); @@ -54,7 +55,6 @@ public: virtual Text3DOverlay* createClone(); private: - virtual void writeToClone(Text3DOverlay* clone); void enableClipPlane(GLenum plane, float x, float y, float z, float w); QString _text; diff --git a/interface/src/ui/overlays/TextOverlay.cpp b/interface/src/ui/overlays/TextOverlay.cpp index 2d98cfc243..368a604c9a 100644 --- a/interface/src/ui/overlays/TextOverlay.cpp +++ b/interface/src/ui/overlays/TextOverlay.cpp @@ -25,6 +25,16 @@ TextOverlay::TextOverlay() : { } +TextOverlay::TextOverlay(TextOverlay* textOverlay) : + Overlay2D(textOverlay), + _text(textOverlay->_text), + _backgroundColor(textOverlay->_backgroundColor), + _leftMargin(textOverlay->_leftMargin), + _topMargin(textOverlay->_topMargin), + _fontSize(textOverlay->_fontSize) +{ +} + TextOverlay::~TextOverlay() { } @@ -125,9 +135,7 @@ void TextOverlay::setProperties(const QScriptValue& properties) { } TextOverlay* TextOverlay::createClone() { - TextOverlay* clone = new TextOverlay(); - writeToClone(clone); - return clone; + return new TextOverlay(this);; } QScriptValue TextOverlay::getProperty(const QString& property) { @@ -152,18 +160,8 @@ QScriptValue TextOverlay::getProperty(const QString& property) { return Overlay2D::getProperty(property); } -void TextOverlay::writeToClone(TextOverlay* clone) { - Overlay2D::writeToClone(clone); - clone->_text = _text; - clone->_backgroundColor = _backgroundColor; - clone->_leftMargin = _leftMargin; - clone->_topMargin = _topMargin; - clone->_fontSize = _fontSize; -} - float TextOverlay::textWidth(const QString& text) const { QFont font(SANS_FONT_FAMILY, _fontSize, DEFAULT_FONT_WEIGHT); // Same font properties as render() QFontMetrics fontMetrics(font); return fontMetrics.width(qPrintable(text)); } - diff --git a/interface/src/ui/overlays/TextOverlay.h b/interface/src/ui/overlays/TextOverlay.h index 30c91d02a3..adfd9bde17 100644 --- a/interface/src/ui/overlays/TextOverlay.h +++ b/interface/src/ui/overlays/TextOverlay.h @@ -37,6 +37,7 @@ class TextOverlay : public Overlay2D { public: TextOverlay(); + TextOverlay(TextOverlay* textOverlay); ~TextOverlay(); virtual void render(RenderArgs* args); @@ -59,8 +60,6 @@ public: float textWidth(const QString& text) const; // Pixels private: - virtual void writeToClone(TextOverlay* clone); - QString _text; xColor _backgroundColor; int _leftMargin; diff --git a/interface/src/ui/overlays/Volume3DOverlay.cpp b/interface/src/ui/overlays/Volume3DOverlay.cpp index 8ceb51bbeb..42e2263a90 100644 --- a/interface/src/ui/overlays/Volume3DOverlay.cpp +++ b/interface/src/ui/overlays/Volume3DOverlay.cpp @@ -28,6 +28,12 @@ Volume3DOverlay::Volume3DOverlay() : { } +Volume3DOverlay::Volume3DOverlay(Volume3DOverlay* volume3DOverlay) : + Base3DOverlay(volume3DOverlay), + _dimensions(volume3DOverlay->_dimensions) +{ +} + Volume3DOverlay::~Volume3DOverlay() { } @@ -116,7 +122,3 @@ bool Volume3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::ve } return false; } - -void Volume3DOverlay::writeToClone(Volume3DOverlay* clone) { - Base3DOverlay::writeToClone(clone); -} diff --git a/interface/src/ui/overlays/Volume3DOverlay.h b/interface/src/ui/overlays/Volume3DOverlay.h index d08a16d708..1bdfc307b5 100644 --- a/interface/src/ui/overlays/Volume3DOverlay.h +++ b/interface/src/ui/overlays/Volume3DOverlay.h @@ -26,6 +26,7 @@ class Volume3DOverlay : public Base3DOverlay { public: Volume3DOverlay(); + Volume3DOverlay(Volume3DOverlay* volume3DOverlay); ~Volume3DOverlay(); // getters @@ -43,7 +44,6 @@ public: virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const; protected: - virtual void writeToClone(Volume3DOverlay* clone); glm::vec3 _dimensions; }; From b948ff2dc88b6bb5da9a0d5abee3cae29117cc66 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 14 Nov 2014 15:13:13 -0800 Subject: [PATCH 49/94] Move dead pieces --- examples/entityScripts/chessPiece.js | 29 +++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/examples/entityScripts/chessPiece.js b/examples/entityScripts/chessPiece.js index f6a2c46d28..0c7c6da8a7 100644 --- a/examples/entityScripts/chessPiece.js +++ b/examples/entityScripts/chessPiece.js @@ -136,19 +136,34 @@ Entities.editEntity(this.entityID, { position: finalPos }); } this.moveDeadPiece = function() { - return; var myPos = this.getIndexPosition(this.properties.position); - for (var i = 0; i < this.pieces.length; i++) { - if (this.pieces[i].id != this.entityID.id) { - var piecePos = this.getIndexPosition(Entities.getEntityProperties(this.pieces[i]).position); + + for (var i = 0; i < this.boardUserData.pieces.length; i++) { + var piece = this.boardUserData.pieces[i]; + + if (piece.id != this.entityID.id) { + var properties = Entities.getEntityProperties(piece); + + var isWhite = properties.modelURL.search("White") !== -1; + var type = (properties.modelURL.search("King") !== -1) ? 4 : + (properties.modelURL.search("Queen") !== -1) ? 3 : + (properties.modelURL.search("Rook") !== -1) ? 2 : + (properties.modelURL.search("Knight") !== -1) ? 1 : + (properties.modelURL.search("Bishop") !== -1) ? 0 : + (properties.modelURL.search("Pawn") !== -1) ? -1 : -2; + + var piecePos = this.getIndexPosition(properties.position); if (myPos.i === piecePos.i && myPos.j === piecePos.j) { - Entities.editEntity(this.pieces[i], { position: this.getAbsolutePosition({ i: 0, j: 0 })}); + var position = this.getAbsolutePosition((isWhite) ? { i: type, j: -1 } : { i: 7 - type, j: 8 }, + properties.dimensions.y / 2.0); + Entities.editEntity(piece, { + position: position + }); break; } } } } - this.grab = function(mouseEvent) { if (this.active) { @@ -165,7 +180,7 @@ if (this.active) { this.updatePosition(mouseEvent); this.snapToGrid(); - //this.moveDeadPiece(); TODO + this.moveDeadPiece(); this.playSound(); } } From a6f57cb7e2bb31218576a8679157a7ccdedea6ea Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 14 Nov 2014 15:13:54 -0800 Subject: [PATCH 50/94] Index error --- examples/playChess.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/playChess.js b/examples/playChess.js index 1b3c643af7..c60e1c6955 100644 --- a/examples/playChess.js +++ b/examples/playChess.js @@ -245,7 +245,7 @@ ChessGame.update = function() { if (ChessGame.pieces.length > 0) { var unknown = 0; ChessGame.board.userDataObject.pieces = new Array(); - for(var i = 1; i < ChessGame.pieces.length; i++) { + for(var i = 0; i < ChessGame.pieces.length; i++) { ChessGame.pieces[i].entity = Entities.identifyEntity(ChessGame.pieces[i].entity); if (ChessGame.pieces[i].entity.isKnownID) { ChessGame.board.userDataObject.pieces.push(ChessGame.pieces[i].entity) From 58796df843b43bc5e340f8f518a8d9d6054fc1a7 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 14 Nov 2014 15:17:09 -0800 Subject: [PATCH 51/94] scriptEntity url --- examples/playChess.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/playChess.js b/examples/playChess.js index c60e1c6955..8a72e1ebb8 100644 --- a/examples/playChess.js +++ b/examples/playChess.js @@ -146,9 +146,11 @@ ChessGame.Piece = (function(position, dimensions, url, rotation) { rotation: rotation, dimensions: this.dimensions, modelURL: url, - //script: "https://s3.amazonaws.com/hifi-public/scripts/entityScripts/chessPiece.js", - //script: "https://s3-us-west-1.amazonaws.com/highfidelity-dev/scripts/chessPiece.js", + /**/ + script: "https://s3.amazonaws.com/hifi-public/scripts/entityScripts/chessPiece.js", + /*/ script: "file:/Users/clement/hifi/examples/entityScripts/chessPiece.js", + /**/ userData: this.buildUserDataString() } this.entity = null; From 94f3f461ce24eb9b93b6389a78749d7e03a5da9b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 14 Nov 2014 15:21:34 -0800 Subject: [PATCH 52/94] Cleanup script for chess boards --- examples/cleanupChessboards.js | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 examples/cleanupChessboards.js diff --git a/examples/cleanupChessboards.js b/examples/cleanupChessboards.js new file mode 100644 index 0000000000..926c02b8cf --- /dev/null +++ b/examples/cleanupChessboards.js @@ -0,0 +1,8 @@ +var entities = Entities.findEntities(MyAvatar.position, 10000); +var URL = "https://s3.amazonaws.com/hifi-public/models/props/chess/"; + +for(var i in entities) { + if (Entities.getEntityProperties(entities[i]).modelURL.slice(0, URL.length) === URL) { + Entities.deleteEntity(entities[i]); + } +} \ No newline at end of file From 38ed1043979c316171e8d75d2fe3b06813770c8c Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Sat, 15 Nov 2014 00:21:50 +0100 Subject: [PATCH 53/94] added const to copy constructors --- interface/src/ui/overlays/Base3DOverlay.cpp | 2 +- interface/src/ui/overlays/Base3DOverlay.h | 2 +- interface/src/ui/overlays/BillboardOverlay.cpp | 4 ++-- interface/src/ui/overlays/BillboardOverlay.h | 4 ++-- interface/src/ui/overlays/Circle3DOverlay.cpp | 4 ++-- interface/src/ui/overlays/Circle3DOverlay.h | 4 ++-- interface/src/ui/overlays/Cube3DOverlay.cpp | 4 ++-- interface/src/ui/overlays/Cube3DOverlay.h | 4 ++-- interface/src/ui/overlays/Grid3DOverlay.cpp | 4 ++-- interface/src/ui/overlays/Grid3DOverlay.h | 4 ++-- interface/src/ui/overlays/ImageOverlay.cpp | 4 ++-- interface/src/ui/overlays/ImageOverlay.h | 4 ++-- interface/src/ui/overlays/Line3DOverlay.cpp | 4 ++-- interface/src/ui/overlays/Line3DOverlay.h | 4 ++-- interface/src/ui/overlays/LocalModelsOverlay.cpp | 8 ++++---- interface/src/ui/overlays/LocalModelsOverlay.h | 4 ++-- interface/src/ui/overlays/LocalVoxelsOverlay.cpp | 4 ++-- interface/src/ui/overlays/LocalVoxelsOverlay.h | 4 ++-- interface/src/ui/overlays/ModelOverlay.cpp | 4 ++-- interface/src/ui/overlays/ModelOverlay.h | 4 ++-- interface/src/ui/overlays/Overlay.cpp | 2 +- interface/src/ui/overlays/Overlay.h | 4 ++-- interface/src/ui/overlays/Overlay2D.cpp | 2 +- interface/src/ui/overlays/Overlay2D.h | 2 +- interface/src/ui/overlays/Planar3DOverlay.cpp | 2 +- interface/src/ui/overlays/Planar3DOverlay.h | 2 +- interface/src/ui/overlays/Rectangle3DOverlay.cpp | 4 ++-- interface/src/ui/overlays/Rectangle3DOverlay.h | 4 ++-- interface/src/ui/overlays/Sphere3DOverlay.cpp | 4 ++-- interface/src/ui/overlays/Sphere3DOverlay.h | 4 ++-- interface/src/ui/overlays/Text3DOverlay.cpp | 4 ++-- interface/src/ui/overlays/Text3DOverlay.h | 4 ++-- interface/src/ui/overlays/TextOverlay.cpp | 6 +++--- interface/src/ui/overlays/TextOverlay.h | 4 ++-- interface/src/ui/overlays/Volume3DOverlay.cpp | 2 +- interface/src/ui/overlays/Volume3DOverlay.h | 2 +- 36 files changed, 66 insertions(+), 66 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 7ed7079795..5a5bfcd937 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -31,7 +31,7 @@ Base3DOverlay::Base3DOverlay() : { } -Base3DOverlay::Base3DOverlay(Base3DOverlay* base3DOverlay) : +Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) : Overlay(base3DOverlay), _position(base3DOverlay->_position), _lineWidth(base3DOverlay->_lineWidth), diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index 4422203566..8304883e3c 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -23,7 +23,7 @@ class Base3DOverlay : public Overlay { public: Base3DOverlay(); - Base3DOverlay(Base3DOverlay* base3DOverlay); + Base3DOverlay(const Base3DOverlay* base3DOverlay); ~Base3DOverlay(); // getters diff --git a/interface/src/ui/overlays/BillboardOverlay.cpp b/interface/src/ui/overlays/BillboardOverlay.cpp index 87c8f8bb74..dee5eceab7 100644 --- a/interface/src/ui/overlays/BillboardOverlay.cpp +++ b/interface/src/ui/overlays/BillboardOverlay.cpp @@ -24,7 +24,7 @@ BillboardOverlay::BillboardOverlay() : _isLoaded = false; } -BillboardOverlay::BillboardOverlay(BillboardOverlay* billboardOverlay) : +BillboardOverlay::BillboardOverlay(const BillboardOverlay* billboardOverlay) : Base3DOverlay(billboardOverlay), _newTextureNeeded(true), _scale(billboardOverlay->_scale), @@ -226,6 +226,6 @@ bool BillboardOverlay::findRayIntersection(const glm::vec3& origin, const glm::v return false; } -BillboardOverlay* BillboardOverlay::createClone() { +BillboardOverlay* BillboardOverlay::createClone() const { return new BillboardOverlay(this); } diff --git a/interface/src/ui/overlays/BillboardOverlay.h b/interface/src/ui/overlays/BillboardOverlay.h index e8c25c8549..be947acf98 100644 --- a/interface/src/ui/overlays/BillboardOverlay.h +++ b/interface/src/ui/overlays/BillboardOverlay.h @@ -22,7 +22,7 @@ class BillboardOverlay : public Base3DOverlay { Q_OBJECT public: BillboardOverlay(); - BillboardOverlay(BillboardOverlay* billboardOverlay); + BillboardOverlay(const BillboardOverlay* billboardOverlay); virtual void render(RenderArgs* args); @@ -37,7 +37,7 @@ public: virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const; - virtual BillboardOverlay* createClone(); + virtual BillboardOverlay* createClone() const; private slots: void replyFinished(); diff --git a/interface/src/ui/overlays/Circle3DOverlay.cpp b/interface/src/ui/overlays/Circle3DOverlay.cpp index 6c0c82f3ec..d19297b589 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.cpp +++ b/interface/src/ui/overlays/Circle3DOverlay.cpp @@ -33,7 +33,7 @@ Circle3DOverlay::Circle3DOverlay() : _minorTickMarksColor.red = _minorTickMarksColor.green = _minorTickMarksColor.blue = (unsigned char)0; } -Circle3DOverlay::Circle3DOverlay(Circle3DOverlay* circle3DOverlay) : +Circle3DOverlay::Circle3DOverlay(const Circle3DOverlay* circle3DOverlay) : Planar3DOverlay(circle3DOverlay), _startAt(circle3DOverlay->_startAt), _endAt(circle3DOverlay->_endAt), @@ -374,6 +374,6 @@ bool Circle3DOverlay::findRayIntersection(const glm::vec3& origin, return intersects; } -Circle3DOverlay* Circle3DOverlay::createClone() { +Circle3DOverlay* Circle3DOverlay::createClone() const { return new Circle3DOverlay(this); } diff --git a/interface/src/ui/overlays/Circle3DOverlay.h b/interface/src/ui/overlays/Circle3DOverlay.h index cf9fc8e2fc..b428be7a43 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.h +++ b/interface/src/ui/overlays/Circle3DOverlay.h @@ -18,7 +18,7 @@ class Circle3DOverlay : public Planar3DOverlay { public: Circle3DOverlay(); - Circle3DOverlay(Circle3DOverlay* circle3DOverlay); + Circle3DOverlay(const Circle3DOverlay* circle3DOverlay); ~Circle3DOverlay(); virtual void render(RenderArgs* args); virtual void setProperties(const QScriptValue& properties); @@ -50,7 +50,7 @@ public: virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const; - virtual Circle3DOverlay* createClone(); + virtual Circle3DOverlay* createClone() const; protected: float _startAt; diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 2aa4d29f23..9c478c4465 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -22,7 +22,7 @@ Cube3DOverlay::Cube3DOverlay() { } -Cube3DOverlay::Cube3DOverlay(Cube3DOverlay* cube3DOverlay) : +Cube3DOverlay::Cube3DOverlay(const Cube3DOverlay* cube3DOverlay) : Volume3DOverlay(cube3DOverlay) { } @@ -108,6 +108,6 @@ void Cube3DOverlay::render(RenderArgs* args) { } } -Cube3DOverlay* Cube3DOverlay::createClone() { +Cube3DOverlay* Cube3DOverlay::createClone() const { return new Cube3DOverlay(this); } diff --git a/interface/src/ui/overlays/Cube3DOverlay.h b/interface/src/ui/overlays/Cube3DOverlay.h index 4fe137b73c..9c199f2b7b 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.h +++ b/interface/src/ui/overlays/Cube3DOverlay.h @@ -18,11 +18,11 @@ class Cube3DOverlay : public Volume3DOverlay { public: Cube3DOverlay(); - Cube3DOverlay(Cube3DOverlay* cube3DOverlay); + Cube3DOverlay(const Cube3DOverlay* cube3DOverlay); ~Cube3DOverlay(); virtual void render(RenderArgs* args); - virtual Cube3DOverlay* createClone(); + virtual Cube3DOverlay* createClone() const; }; diff --git a/interface/src/ui/overlays/Grid3DOverlay.cpp b/interface/src/ui/overlays/Grid3DOverlay.cpp index 601413226a..84610d7981 100644 --- a/interface/src/ui/overlays/Grid3DOverlay.cpp +++ b/interface/src/ui/overlays/Grid3DOverlay.cpp @@ -20,7 +20,7 @@ Grid3DOverlay::Grid3DOverlay() : Base3DOverlay(), _majorGridEvery(5) { } -Grid3DOverlay::Grid3DOverlay(Grid3DOverlay* grid3DOverlay) : +Grid3DOverlay::Grid3DOverlay(const Grid3DOverlay* grid3DOverlay) : Base3DOverlay(grid3DOverlay), _minorGridWidth(grid3DOverlay->_minorGridWidth), _majorGridEvery(grid3DOverlay->_majorGridEvery) @@ -135,6 +135,6 @@ QScriptValue Grid3DOverlay::getProperty(const QString& property) { return Base3DOverlay::getProperty(property); } -Grid3DOverlay* Grid3DOverlay::createClone() { +Grid3DOverlay* Grid3DOverlay::createClone() const { return new Grid3DOverlay(this); } diff --git a/interface/src/ui/overlays/Grid3DOverlay.h b/interface/src/ui/overlays/Grid3DOverlay.h index 28dfbf9de7..b162ff3d74 100644 --- a/interface/src/ui/overlays/Grid3DOverlay.h +++ b/interface/src/ui/overlays/Grid3DOverlay.h @@ -29,14 +29,14 @@ class Grid3DOverlay : public Base3DOverlay { public: Grid3DOverlay(); - Grid3DOverlay(Grid3DOverlay* grid3DOverlay); + Grid3DOverlay(const Grid3DOverlay* grid3DOverlay); ~Grid3DOverlay(); virtual void render(RenderArgs* args); virtual void setProperties(const QScriptValue& properties); virtual QScriptValue getProperty(const QString& property); - virtual Grid3DOverlay* createClone(); + virtual Grid3DOverlay* createClone() const; private: float _minorGridWidth; diff --git a/interface/src/ui/overlays/ImageOverlay.cpp b/interface/src/ui/overlays/ImageOverlay.cpp index dd06ee4da2..fad19be292 100644 --- a/interface/src/ui/overlays/ImageOverlay.cpp +++ b/interface/src/ui/overlays/ImageOverlay.cpp @@ -27,7 +27,7 @@ ImageOverlay::ImageOverlay() : _isLoaded = false; } -ImageOverlay::ImageOverlay(ImageOverlay* imageOverlay) : +ImageOverlay::ImageOverlay(const ImageOverlay* imageOverlay) : Overlay2D(imageOverlay), _textureID(0), _textureBound(false), @@ -172,6 +172,6 @@ QScriptValue ImageOverlay::getProperty(const QString& property) { return Overlay2D::getProperty(property); } -ImageOverlay* ImageOverlay::createClone() { +ImageOverlay* ImageOverlay::createClone() const { return new ImageOverlay(this); } diff --git a/interface/src/ui/overlays/ImageOverlay.h b/interface/src/ui/overlays/ImageOverlay.h index 9c8d48a2e2..cff557654f 100644 --- a/interface/src/ui/overlays/ImageOverlay.h +++ b/interface/src/ui/overlays/ImageOverlay.h @@ -33,7 +33,7 @@ class ImageOverlay : public Overlay2D { public: ImageOverlay(); - ImageOverlay(ImageOverlay* imageOverlay); + ImageOverlay(const ImageOverlay* imageOverlay); ~ImageOverlay(); virtual void render(RenderArgs* args); @@ -47,7 +47,7 @@ public: virtual void setProperties(const QScriptValue& properties); virtual QScriptValue getProperty(const QString& property); - virtual ImageOverlay* createClone(); + virtual ImageOverlay* createClone() const; private slots: void replyFinished(); // we actually want to hide this... diff --git a/interface/src/ui/overlays/Line3DOverlay.cpp b/interface/src/ui/overlays/Line3DOverlay.cpp index aac773f08f..ae67bf9d92 100644 --- a/interface/src/ui/overlays/Line3DOverlay.cpp +++ b/interface/src/ui/overlays/Line3DOverlay.cpp @@ -18,7 +18,7 @@ Line3DOverlay::Line3DOverlay() { } -Line3DOverlay::Line3DOverlay(Line3DOverlay* line3DOverlay) : +Line3DOverlay::Line3DOverlay(const Line3DOverlay* line3DOverlay) : Base3DOverlay(line3DOverlay), _end(line3DOverlay->_end) { @@ -94,6 +94,6 @@ QScriptValue Line3DOverlay::getProperty(const QString& property) { return Base3DOverlay::getProperty(property); } -Line3DOverlay* Line3DOverlay::createClone() { +Line3DOverlay* Line3DOverlay::createClone() const { return new Line3DOverlay(this); } diff --git a/interface/src/ui/overlays/Line3DOverlay.h b/interface/src/ui/overlays/Line3DOverlay.h index 3d481438b9..607fb0e0bb 100644 --- a/interface/src/ui/overlays/Line3DOverlay.h +++ b/interface/src/ui/overlays/Line3DOverlay.h @@ -18,7 +18,7 @@ class Line3DOverlay : public Base3DOverlay { public: Line3DOverlay(); - Line3DOverlay(Line3DOverlay* line3DOverlay); + Line3DOverlay(const Line3DOverlay* line3DOverlay); ~Line3DOverlay(); virtual void render(RenderArgs* args); @@ -31,7 +31,7 @@ public: virtual void setProperties(const QScriptValue& properties); virtual QScriptValue getProperty(const QString& property); - virtual Line3DOverlay* createClone(); + virtual Line3DOverlay* createClone() const; protected: glm::vec3 _end; diff --git a/interface/src/ui/overlays/LocalModelsOverlay.cpp b/interface/src/ui/overlays/LocalModelsOverlay.cpp index 25cb0ead64..d8555c85ba 100644 --- a/interface/src/ui/overlays/LocalModelsOverlay.cpp +++ b/interface/src/ui/overlays/LocalModelsOverlay.cpp @@ -18,9 +18,9 @@ LocalModelsOverlay::LocalModelsOverlay(EntityTreeRenderer* entityTreeRenderer) : _entityTreeRenderer(entityTreeRenderer) { } -LocalModelsOverlay::LocalModelsOverlay(EntityTreeRenderer* entityTreeRenderer, LocalModelsOverlay* localModelsOverlay) : +LocalModelsOverlay::LocalModelsOverlay(const LocalModelsOverlay* localModelsOverlay) : Volume3DOverlay(localModelsOverlay), - _entityTreeRenderer(entityTreeRenderer) + _entityTreeRenderer(localModelsOverlay->_entityTreeRenderer) { } @@ -56,6 +56,6 @@ void LocalModelsOverlay::render(RenderArgs* args) { } } -LocalModelsOverlay* LocalModelsOverlay::createClone() { - return new LocalModelsOverlay(Application::getInstance()->getEntityClipboardRenderer(), this); +LocalModelsOverlay* LocalModelsOverlay::createClone() const { + return new LocalModelsOverlay(this); } diff --git a/interface/src/ui/overlays/LocalModelsOverlay.h b/interface/src/ui/overlays/LocalModelsOverlay.h index c38bc6b2a3..39465de7f9 100644 --- a/interface/src/ui/overlays/LocalModelsOverlay.h +++ b/interface/src/ui/overlays/LocalModelsOverlay.h @@ -20,13 +20,13 @@ class LocalModelsOverlay : public Volume3DOverlay { Q_OBJECT public: LocalModelsOverlay(EntityTreeRenderer* entityTreeRenderer); - LocalModelsOverlay(EntityTreeRenderer* entityTreeRenderer, LocalModelsOverlay* localModelsOverlay); + LocalModelsOverlay(const LocalModelsOverlay* localModelsOverlay); ~LocalModelsOverlay(); virtual void update(float deltatime); virtual void render(RenderArgs* args); - virtual LocalModelsOverlay* createClone(); + virtual LocalModelsOverlay* createClone() const; private: EntityTreeRenderer* _entityTreeRenderer; diff --git a/interface/src/ui/overlays/LocalVoxelsOverlay.cpp b/interface/src/ui/overlays/LocalVoxelsOverlay.cpp index 4c44fe6dd8..9cb3df8bf3 100644 --- a/interface/src/ui/overlays/LocalVoxelsOverlay.cpp +++ b/interface/src/ui/overlays/LocalVoxelsOverlay.cpp @@ -28,7 +28,7 @@ LocalVoxelsOverlay::LocalVoxelsOverlay() : { } -LocalVoxelsOverlay::LocalVoxelsOverlay(LocalVoxelsOverlay* localVoxelsOverlay) : +LocalVoxelsOverlay::LocalVoxelsOverlay(const LocalVoxelsOverlay* localVoxelsOverlay) : Volume3DOverlay(localVoxelsOverlay), _voxelCount(localVoxelsOverlay->_voxelCount) { @@ -109,7 +109,7 @@ void LocalVoxelsOverlay::setProperties(const QScriptValue &properties) { } } -LocalVoxelsOverlay* LocalVoxelsOverlay::createClone() { +LocalVoxelsOverlay* LocalVoxelsOverlay::createClone() const { return new LocalVoxelsOverlay(this); } diff --git a/interface/src/ui/overlays/LocalVoxelsOverlay.h b/interface/src/ui/overlays/LocalVoxelsOverlay.h index 3e5bbbc5b6..4afa44f9be 100644 --- a/interface/src/ui/overlays/LocalVoxelsOverlay.h +++ b/interface/src/ui/overlays/LocalVoxelsOverlay.h @@ -32,7 +32,7 @@ class LocalVoxelsOverlay : public Volume3DOverlay { Q_OBJECT public: LocalVoxelsOverlay(); - LocalVoxelsOverlay(LocalVoxelsOverlay* localVoxelsOverlay); + LocalVoxelsOverlay(const LocalVoxelsOverlay* localVoxelsOverlay); ~LocalVoxelsOverlay(); virtual void update(float deltatime); @@ -41,7 +41,7 @@ public: virtual void setProperties(const QScriptValue& properties); virtual QScriptValue getProperty(const QString& property); - virtual LocalVoxelsOverlay* createClone(); + virtual LocalVoxelsOverlay* createClone() const; private: static QMap _voxelSystemMap; // treeName/voxelSystem diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index f1c588f45d..3594d7e828 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -22,7 +22,7 @@ ModelOverlay::ModelOverlay() _isLoaded = false; } -ModelOverlay::ModelOverlay(ModelOverlay* modelOverlay) : +ModelOverlay::ModelOverlay(const ModelOverlay* modelOverlay) : Base3DOverlay(modelOverlay), _model(), _modelTextures(QVariantMap()), @@ -182,6 +182,6 @@ bool ModelOverlay::findRayIntersectionExtraInfo(const glm::vec3& origin, const g return _model.findRayIntersectionAgainstSubMeshes(origin, direction, distance, face, extraInfo); } -ModelOverlay* ModelOverlay::createClone() { +ModelOverlay* ModelOverlay::createClone() const { return new ModelOverlay(this); } diff --git a/interface/src/ui/overlays/ModelOverlay.h b/interface/src/ui/overlays/ModelOverlay.h index 393e09c78b..80b52ea27e 100644 --- a/interface/src/ui/overlays/ModelOverlay.h +++ b/interface/src/ui/overlays/ModelOverlay.h @@ -20,7 +20,7 @@ class ModelOverlay : public Base3DOverlay { Q_OBJECT public: ModelOverlay(); - ModelOverlay(ModelOverlay* modelOverlay); + ModelOverlay(const ModelOverlay* modelOverlay); virtual void update(float deltatime); virtual void render(RenderArgs* args); @@ -30,7 +30,7 @@ public: virtual bool findRayIntersectionExtraInfo(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face, QString& extraInfo) const; - virtual ModelOverlay* createClone(); + virtual ModelOverlay* createClone() const; private: diff --git a/interface/src/ui/overlays/Overlay.cpp b/interface/src/ui/overlays/Overlay.cpp index e67c1572f1..549152ded0 100644 --- a/interface/src/ui/overlays/Overlay.cpp +++ b/interface/src/ui/overlays/Overlay.cpp @@ -39,7 +39,7 @@ Overlay::Overlay() : { } -Overlay::Overlay(Overlay* overlay) : +Overlay::Overlay(const Overlay* overlay) : _parent(NULL), _alpha(overlay->_alpha), _lastPulseUpdate(usecTimestampNow()), diff --git a/interface/src/ui/overlays/Overlay.h b/interface/src/ui/overlays/Overlay.h index 341a7b56a3..99ab588197 100644 --- a/interface/src/ui/overlays/Overlay.h +++ b/interface/src/ui/overlays/Overlay.h @@ -36,7 +36,7 @@ public: }; Overlay(); - Overlay(Overlay* overlay); + Overlay(const Overlay* overlay); ~Overlay(); void init(QGLWidget* parent, QScriptEngine* scriptEngine); virtual void update(float deltatime) {} @@ -79,7 +79,7 @@ public: void setAlphaPulse(float value) { _alphaPulse = value; } virtual void setProperties(const QScriptValue& properties); - virtual Overlay* createClone() = 0; + virtual Overlay* createClone() const = 0; virtual QScriptValue getProperty(const QString& property); protected: diff --git a/interface/src/ui/overlays/Overlay2D.cpp b/interface/src/ui/overlays/Overlay2D.cpp index 53ef9cdf29..df7df391eb 100644 --- a/interface/src/ui/overlays/Overlay2D.cpp +++ b/interface/src/ui/overlays/Overlay2D.cpp @@ -22,7 +22,7 @@ Overlay2D::Overlay2D() { } -Overlay2D::Overlay2D(Overlay2D* overlay2D) : +Overlay2D::Overlay2D(const Overlay2D* overlay2D) : Overlay(overlay2D), _bounds(overlay2D->_bounds) { diff --git a/interface/src/ui/overlays/Overlay2D.h b/interface/src/ui/overlays/Overlay2D.h index ea3936c2c7..7493add905 100644 --- a/interface/src/ui/overlays/Overlay2D.h +++ b/interface/src/ui/overlays/Overlay2D.h @@ -28,7 +28,7 @@ class Overlay2D : public Overlay { public: Overlay2D(); - Overlay2D(Overlay2D* overlay2D); + Overlay2D(const Overlay2D* overlay2D); ~Overlay2D(); virtual bool is3D() const { return false; } diff --git a/interface/src/ui/overlays/Planar3DOverlay.cpp b/interface/src/ui/overlays/Planar3DOverlay.cpp index 390b92948c..a8288b241c 100644 --- a/interface/src/ui/overlays/Planar3DOverlay.cpp +++ b/interface/src/ui/overlays/Planar3DOverlay.cpp @@ -26,7 +26,7 @@ Planar3DOverlay::Planar3DOverlay() : { } -Planar3DOverlay::Planar3DOverlay(Planar3DOverlay* planar3DOverlay) : +Planar3DOverlay::Planar3DOverlay(const Planar3DOverlay* planar3DOverlay) : Base3DOverlay(planar3DOverlay), _dimensions(planar3DOverlay->_dimensions) { diff --git a/interface/src/ui/overlays/Planar3DOverlay.h b/interface/src/ui/overlays/Planar3DOverlay.h index 7de68e24b2..d34fe44ebc 100644 --- a/interface/src/ui/overlays/Planar3DOverlay.h +++ b/interface/src/ui/overlays/Planar3DOverlay.h @@ -26,7 +26,7 @@ class Planar3DOverlay : public Base3DOverlay { public: Planar3DOverlay(); - Planar3DOverlay(Planar3DOverlay* planar3DOverlay); + Planar3DOverlay(const Planar3DOverlay* planar3DOverlay); ~Planar3DOverlay(); // getters diff --git a/interface/src/ui/overlays/Rectangle3DOverlay.cpp b/interface/src/ui/overlays/Rectangle3DOverlay.cpp index a2043d77c1..bcca759cd4 100644 --- a/interface/src/ui/overlays/Rectangle3DOverlay.cpp +++ b/interface/src/ui/overlays/Rectangle3DOverlay.cpp @@ -20,7 +20,7 @@ Rectangle3DOverlay::Rectangle3DOverlay() { } -Rectangle3DOverlay::Rectangle3DOverlay(Rectangle3DOverlay* rectangle3DOverlay) : +Rectangle3DOverlay::Rectangle3DOverlay(const Rectangle3DOverlay* rectangle3DOverlay) : Planar3DOverlay(rectangle3DOverlay) { } @@ -111,6 +111,6 @@ void Rectangle3DOverlay::setProperties(const QScriptValue &properties) { Planar3DOverlay::setProperties(properties); } -Rectangle3DOverlay* Rectangle3DOverlay::createClone() { +Rectangle3DOverlay* Rectangle3DOverlay::createClone() const { return new Rectangle3DOverlay(this); } diff --git a/interface/src/ui/overlays/Rectangle3DOverlay.h b/interface/src/ui/overlays/Rectangle3DOverlay.h index 98e04324b4..5e75469f2d 100644 --- a/interface/src/ui/overlays/Rectangle3DOverlay.h +++ b/interface/src/ui/overlays/Rectangle3DOverlay.h @@ -18,12 +18,12 @@ class Rectangle3DOverlay : public Planar3DOverlay { public: Rectangle3DOverlay(); - Rectangle3DOverlay(Rectangle3DOverlay* rectangle3DOverlay); + Rectangle3DOverlay(const Rectangle3DOverlay* rectangle3DOverlay); ~Rectangle3DOverlay(); virtual void render(RenderArgs* args); virtual void setProperties(const QScriptValue& properties); - virtual Rectangle3DOverlay* createClone(); + virtual Rectangle3DOverlay* createClone() const; }; diff --git a/interface/src/ui/overlays/Sphere3DOverlay.cpp b/interface/src/ui/overlays/Sphere3DOverlay.cpp index 30bb7d1c52..34064675e5 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.cpp +++ b/interface/src/ui/overlays/Sphere3DOverlay.cpp @@ -21,7 +21,7 @@ Sphere3DOverlay::Sphere3DOverlay() { } -Sphere3DOverlay::Sphere3DOverlay(Sphere3DOverlay* Sphere3DOverlay) : +Sphere3DOverlay::Sphere3DOverlay(const Sphere3DOverlay* Sphere3DOverlay) : Volume3DOverlay(Sphere3DOverlay) { } @@ -76,6 +76,6 @@ void Sphere3DOverlay::render(RenderArgs* args) { } -Sphere3DOverlay* Sphere3DOverlay::createClone() { +Sphere3DOverlay* Sphere3DOverlay::createClone() const { return new Sphere3DOverlay(this); } diff --git a/interface/src/ui/overlays/Sphere3DOverlay.h b/interface/src/ui/overlays/Sphere3DOverlay.h index 2f63c4fe48..3b881e5ba6 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.h +++ b/interface/src/ui/overlays/Sphere3DOverlay.h @@ -18,11 +18,11 @@ class Sphere3DOverlay : public Volume3DOverlay { public: Sphere3DOverlay(); - Sphere3DOverlay(Sphere3DOverlay* Sphere3DOverlay); + Sphere3DOverlay(const Sphere3DOverlay* Sphere3DOverlay); ~Sphere3DOverlay(); virtual void render(RenderArgs* args); - virtual Sphere3DOverlay* createClone(); + virtual Sphere3DOverlay* createClone() const; }; diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index 0a83ec80f5..88ac009ac7 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -31,7 +31,7 @@ Text3DOverlay::Text3DOverlay() : { } -Text3DOverlay::Text3DOverlay(Text3DOverlay* text3DOverlay) : +Text3DOverlay::Text3DOverlay(const Text3DOverlay* text3DOverlay) : Planar3DOverlay(text3DOverlay), _text(text3DOverlay->_text), _backgroundColor(text3DOverlay->_backgroundColor), @@ -220,7 +220,7 @@ QScriptValue Text3DOverlay::getProperty(const QString& property) { return Planar3DOverlay::getProperty(property); } -Text3DOverlay* Text3DOverlay::createClone() { +Text3DOverlay* Text3DOverlay::createClone() const { return new Text3DOverlay(this);; } diff --git a/interface/src/ui/overlays/Text3DOverlay.h b/interface/src/ui/overlays/Text3DOverlay.h index c459b2eb36..c624830ac8 100644 --- a/interface/src/ui/overlays/Text3DOverlay.h +++ b/interface/src/ui/overlays/Text3DOverlay.h @@ -24,7 +24,7 @@ class Text3DOverlay : public Planar3DOverlay { public: Text3DOverlay(); - Text3DOverlay(Text3DOverlay* text3DOverlay); + Text3DOverlay(const Text3DOverlay* text3DOverlay); ~Text3DOverlay(); virtual void render(RenderArgs* args); @@ -52,7 +52,7 @@ public: float textWidth(const QString& text) const; // Meters - virtual Text3DOverlay* createClone(); + virtual Text3DOverlay* createClone() const; private: void enableClipPlane(GLenum plane, float x, float y, float z, float w); diff --git a/interface/src/ui/overlays/TextOverlay.cpp b/interface/src/ui/overlays/TextOverlay.cpp index 368a604c9a..1d72cf7f05 100644 --- a/interface/src/ui/overlays/TextOverlay.cpp +++ b/interface/src/ui/overlays/TextOverlay.cpp @@ -25,7 +25,7 @@ TextOverlay::TextOverlay() : { } -TextOverlay::TextOverlay(TextOverlay* textOverlay) : +TextOverlay::TextOverlay(const TextOverlay* textOverlay) : Overlay2D(textOverlay), _text(textOverlay->_text), _backgroundColor(textOverlay->_backgroundColor), @@ -134,8 +134,8 @@ void TextOverlay::setProperties(const QScriptValue& properties) { } } -TextOverlay* TextOverlay::createClone() { - return new TextOverlay(this);; +TextOverlay* TextOverlay::createClone() const { + return new TextOverlay(this); } QScriptValue TextOverlay::getProperty(const QString& property) { diff --git a/interface/src/ui/overlays/TextOverlay.h b/interface/src/ui/overlays/TextOverlay.h index adfd9bde17..703e15be10 100644 --- a/interface/src/ui/overlays/TextOverlay.h +++ b/interface/src/ui/overlays/TextOverlay.h @@ -37,7 +37,7 @@ class TextOverlay : public Overlay2D { public: TextOverlay(); - TextOverlay(TextOverlay* textOverlay); + TextOverlay(const TextOverlay* textOverlay); ~TextOverlay(); virtual void render(RenderArgs* args); @@ -54,7 +54,7 @@ public: void setFontSize(int fontSize) { _fontSize = fontSize; } virtual void setProperties(const QScriptValue& properties); - virtual TextOverlay* createClone(); + virtual TextOverlay* createClone() const; virtual QScriptValue getProperty(const QString& property); float textWidth(const QString& text) const; // Pixels diff --git a/interface/src/ui/overlays/Volume3DOverlay.cpp b/interface/src/ui/overlays/Volume3DOverlay.cpp index 42e2263a90..c4192a15b2 100644 --- a/interface/src/ui/overlays/Volume3DOverlay.cpp +++ b/interface/src/ui/overlays/Volume3DOverlay.cpp @@ -28,7 +28,7 @@ Volume3DOverlay::Volume3DOverlay() : { } -Volume3DOverlay::Volume3DOverlay(Volume3DOverlay* volume3DOverlay) : +Volume3DOverlay::Volume3DOverlay(const Volume3DOverlay* volume3DOverlay) : Base3DOverlay(volume3DOverlay), _dimensions(volume3DOverlay->_dimensions) { diff --git a/interface/src/ui/overlays/Volume3DOverlay.h b/interface/src/ui/overlays/Volume3DOverlay.h index 1bdfc307b5..005646c036 100644 --- a/interface/src/ui/overlays/Volume3DOverlay.h +++ b/interface/src/ui/overlays/Volume3DOverlay.h @@ -26,7 +26,7 @@ class Volume3DOverlay : public Base3DOverlay { public: Volume3DOverlay(); - Volume3DOverlay(Volume3DOverlay* volume3DOverlay); + Volume3DOverlay(const Volume3DOverlay* volume3DOverlay); ~Volume3DOverlay(); // getters From 62c64479c28841ab6cf241f5d261111544c648a2 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Nov 2014 15:58:12 -0800 Subject: [PATCH 54/94] first cut at text entity --- interface/src/entities/EntityTreeRenderer.cpp | 2 + interface/src/entities/EntityTreeRenderer.h | 3 +- .../src/entities/RenderableTextEntityItem.cpp | 113 ++++++++++++++++++ .../src/entities/RenderableTextEntityItem.h | 44 +++++++ .../entities/src/EntityItemProperties.cpp | 113 +++++++++++++----- libraries/entities/src/EntityItemProperties.h | 16 ++- .../entities/src/EntityItemPropertiesMacros.h | 20 ++++ libraries/entities/src/EntityTypes.cpp | 2 + libraries/entities/src/EntityTypes.h | 3 +- libraries/entities/src/TextEntityItem.cpp | 113 ++++++++++++++++++ libraries/entities/src/TextEntityItem.h | 81 +++++++++++++ 11 files changed, 475 insertions(+), 35 deletions(-) create mode 100644 interface/src/entities/RenderableTextEntityItem.cpp create mode 100644 interface/src/entities/RenderableTextEntityItem.h create mode 100644 libraries/entities/src/TextEntityItem.cpp create mode 100644 libraries/entities/src/TextEntityItem.h diff --git a/interface/src/entities/EntityTreeRenderer.cpp b/interface/src/entities/EntityTreeRenderer.cpp index 2209a992c1..2b657979f4 100644 --- a/interface/src/entities/EntityTreeRenderer.cpp +++ b/interface/src/entities/EntityTreeRenderer.cpp @@ -34,6 +34,7 @@ #include "RenderableLightEntityItem.h" #include "RenderableModelEntityItem.h" #include "RenderableSphereEntityItem.h" +#include "RenderableTextEntityItem.h" QThread* EntityTreeRenderer::getMainThread() { @@ -50,6 +51,7 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts) : REGISTER_ENTITY_TYPE_WITH_FACTORY(Box, RenderableBoxEntityItem::factory) REGISTER_ENTITY_TYPE_WITH_FACTORY(Sphere, RenderableSphereEntityItem::factory) REGISTER_ENTITY_TYPE_WITH_FACTORY(Light, RenderableLightEntityItem::factory) + REGISTER_ENTITY_TYPE_WITH_FACTORY(Text, RenderableTextEntityItem::factory) _currentHoverOverEntityID = EntityItemID::createInvalidEntityID(); // makes it the unknown ID _currentClickingOnEntityID = EntityItemID::createInvalidEntityID(); // makes it the unknown ID diff --git a/interface/src/entities/EntityTreeRenderer.h b/interface/src/entities/EntityTreeRenderer.h index 66107b368a..c94eb78b77 100644 --- a/interface/src/entities/EntityTreeRenderer.h +++ b/interface/src/entities/EntityTreeRenderer.h @@ -56,7 +56,8 @@ public: void processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode); virtual void init(); - virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::RenderSide renderSide = RenderArgs::MONO); + virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, + RenderArgs::RenderSide renderSide = RenderArgs::MONO); virtual const FBXGeometry* getGeometryForEntity(const EntityItem* entityItem); virtual const Model* getModelForEntityItem(const EntityItem* entityItem); diff --git a/interface/src/entities/RenderableTextEntityItem.cpp b/interface/src/entities/RenderableTextEntityItem.cpp new file mode 100644 index 0000000000..601cbb347a --- /dev/null +++ b/interface/src/entities/RenderableTextEntityItem.cpp @@ -0,0 +1,113 @@ +// +// RenderableTextEntityItem.cpp +// interface/src +// +// 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 +// + +#include + +#include "InterfaceConfig.h" + +#include +#include + +#include "Menu.h" +#include "EntityTreeRenderer.h" +#include "RenderableTextEntityItem.h" + +const xColor DEFAULT_BACKGROUND_COLOR = { 0, 0, 0 }; +const float DEFAULT_MARGIN = 0.1f; +const int FIXED_FONT_POINT_SIZE = 40; +const float LINE_SCALE_RATIO = 1.2f; + +EntityItem* RenderableTextEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { + return new RenderableTextEntityItem(entityID, properties); +} + +void RenderableTextEntityItem::render(RenderArgs* args) { + PerformanceTimer perfTimer("RenderableTextEntityItem::render"); + assert(getType() == EntityTypes::Text); + glm::vec3 position = getPositionInMeters(); + glm::vec3 center = getCenter() * (float)TREE_SCALE; + glm::vec3 dimensions = getDimensions() * (float)TREE_SCALE; + glm::vec3 halfDimensions = dimensions / 2.0f; + glm::quat rotation = getRotation(); + float leftMargin = 0.1f; + float rightMargin = 0.1f; + float topMargin = 0.1f; + float bottomMargin = 0.1f; + + //qDebug() << "RenderableTextEntityItem::render() id:" << getEntityItemID() << "text:" << getText(); + + 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); + + const float MAX_COLOR = 255.0f; + xColor backgroundColor = { 255, 0, 0 }; //getBackgroundColorX(); + float alpha = 1.0f; //getBackgroundAlpha(); + glColor4f(backgroundColor.red / MAX_COLOR, backgroundColor.green / MAX_COLOR, backgroundColor.blue / MAX_COLOR, alpha); + + const float SLIGHTLY_BEHIND = -0.005f; + + glBegin(GL_QUADS); + glVertex3f(-halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND); + glVertex3f(halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND); + glVertex3f(halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND); + glVertex3f(-halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND); + glEnd(); + + const int FIXED_FONT_SCALING_RATIO = FIXED_FONT_POINT_SIZE * 40.0f; // this is a ratio determined through experimentation + + // Same font properties as textWidth() + TextRenderer* textRenderer = TextRenderer::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE); + float maxHeight = (float)textRenderer->calculateHeight("Xy") * LINE_SCALE_RATIO; + + float scaleFactor = (maxHeight / FIXED_FONT_SCALING_RATIO) * _lineHeight; + + glTranslatef(-(halfDimensions.x - leftMargin), halfDimensions.y - topMargin, 0.0f); + + glm::vec2 clipMinimum(0.0f, 0.0f); + glm::vec2 clipDimensions((dimensions.x - (leftMargin + rightMargin)) / scaleFactor, + (dimensions.y - (topMargin + bottomMargin)) / scaleFactor); + + glScalef(scaleFactor, -scaleFactor, 1.0); + enableClipPlane(GL_CLIP_PLANE0, -1.0f, 0.0f, 0.0f, clipMinimum.x + clipDimensions.x); + enableClipPlane(GL_CLIP_PLANE1, 1.0f, 0.0f, 0.0f, -clipMinimum.x); + enableClipPlane(GL_CLIP_PLANE2, 0.0f, -1.0f, 0.0f, clipMinimum.y + clipDimensions.y); + enableClipPlane(GL_CLIP_PLANE3, 0.0f, 1.0f, 0.0f, -clipMinimum.y); + + xColor textColor = getTextColorX(); + glColor3f(textColor.red / MAX_COLOR, textColor.green / MAX_COLOR, textColor.blue / MAX_COLOR); + QStringList lines = _text.split("\n"); + int lineOffset = maxHeight; + float textAlpha = 1.0f; // getTextAlpha() + foreach(QString thisLine, lines) { + textRenderer->draw(0, lineOffset, qPrintable(thisLine), textAlpha); + lineOffset += maxHeight; + } + + glDisable(GL_CLIP_PLANE0); + glDisable(GL_CLIP_PLANE1); + glDisable(GL_CLIP_PLANE2); + glDisable(GL_CLIP_PLANE3); + + } + glPopMatrix(); +} + +void RenderableTextEntityItem::enableClipPlane(GLenum plane, float x, float y, float z, float w) { + GLdouble coefficients[] = { x, y, z, w }; + glClipPlane(plane, coefficients); + glEnable(plane); +} + + + diff --git a/interface/src/entities/RenderableTextEntityItem.h b/interface/src/entities/RenderableTextEntityItem.h new file mode 100644 index 0000000000..8760cb9df7 --- /dev/null +++ b/interface/src/entities/RenderableTextEntityItem.h @@ -0,0 +1,44 @@ +// +// RenderableTextEntityItem.h +// interface/src/entities +// +// 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 +// + +#ifndef hifi_RenderableTextEntityItem_h +#define hifi_RenderableTextEntityItem_h + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +class RenderableTextEntityItem : public TextEntityItem { +public: + static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties); + + RenderableTextEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : + TextEntityItem(entityItemID, properties) + { } + + virtual void render(RenderArgs* args); + +private: + void enableClipPlane(GLenum plane, float x, float y, float z, float w); + +}; + + +#endif // hifi_RenderableTextEntityItem_h diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 75fa05032a..d173558711 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -20,6 +20,7 @@ #include "EntityItem.h" #include "EntityItemProperties.h" #include "ModelEntityItem.h" +#include "TextEntityItem.h" EntityItemProperties::EntityItemProperties() : @@ -108,6 +109,11 @@ EntityItemProperties::EntityItemProperties() : _lockedChanged(false), _texturesChanged(false), + CONSTRUCT_PROPERTY(text, TextEntityItem::DEFAULT_TEXT), + CONSTRUCT_PROPERTY(lineHeight, TextEntityItem::DEFAULT_LINE_HEIGHT), + CONSTRUCT_PROPERTY(textColor, TextEntityItem::DEFAULT_TEXT_COLOR), + CONSTRUCT_PROPERTY(backgroundColor, TextEntityItem::DEFAULT_BACKGROUND_COLOR), + _defaultSettings(true), _naturalDimensions(1.0f, 1.0f, 1.0f) { @@ -226,6 +232,10 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_LOCKED, locked); CHECK_PROPERTY_CHANGE(PROP_TEXTURES, textures); CHECK_PROPERTY_CHANGE(PROP_USER_DATA, userData); + CHECK_PROPERTY_CHANGE(PROP_TEXT, text); + CHECK_PROPERTY_CHANGE(PROP_LINE_HEIGHT, lineHeight); + CHECK_PROPERTY_CHANGE(PROP_TEXT_COLOR, textColor); + CHECK_PROPERTY_CHANGE(PROP_BACKGROUND_COLOR, backgroundColor); return changedProperties; } @@ -280,6 +290,10 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine) cons COPY_PROPERTY_TO_QSCRIPTVALUE(locked); COPY_PROPERTY_TO_QSCRIPTVALUE(textures); COPY_PROPERTY_TO_QSCRIPTVALUE(userData); + COPY_PROPERTY_TO_QSCRIPTVALUE(text); + COPY_PROPERTY_TO_QSCRIPTVALUE(lineHeight); + COPY_PROPERTY_TO_QSCRIPTVALUE_COLOR_GETTER(textColor, getTextColor()); + COPY_PROPERTY_TO_QSCRIPTVALUE_COLOR_GETTER(backgroundColor, getBackgroundColor()); // Sitting properties support QScriptValue sittingPoints = engine->newObject(); @@ -355,6 +369,10 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object) { COPY_PROPERTY_FROM_QSCRIPTVALUE_BOOL(locked, setLocked); COPY_PROPERTY_FROM_QSCRIPTVALUE_STRING(textures, setTextures); COPY_PROPERTY_FROM_QSCRIPTVALUE_STRING(userData, setUserData); + COPY_PROPERTY_FROM_QSCRIPTVALUE_STRING(text, setText); + COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(lineHeight, setLineHeight); + COPY_PROPERTY_FROM_QSCRIPTVALUE_COLOR(textColor, setTextColor); + COPY_PROPERTY_FROM_QSCRIPTVALUE_COLOR(backgroundColor, setBackgroundColor); _lastEdited = usecTimestampNow(); } @@ -494,30 +512,43 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem APPEND_ENTITY_PROPERTY(PROP_LIFETIME, appendValue, properties.getLifetime()); APPEND_ENTITY_PROPERTY(PROP_SCRIPT, appendValue, properties.getScript()); APPEND_ENTITY_PROPERTY(PROP_COLOR, appendColor, properties.getColor()); - APPEND_ENTITY_PROPERTY(PROP_MODEL_URL, appendValue, properties.getModelURL()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, appendValue, properties.getAnimationURL()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, appendValue, properties.getAnimationFPS()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, appendValue, properties.getAnimationFrameIndex()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, appendValue, properties.getAnimationIsPlaying()); APPEND_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, appendValue, properties.getRegistrationPoint()); APPEND_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, appendValue, properties.getAngularVelocity()); APPEND_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, appendValue, properties.getAngularDamping()); APPEND_ENTITY_PROPERTY(PROP_VISIBLE, appendValue, properties.getVisible()); APPEND_ENTITY_PROPERTY(PROP_IGNORE_FOR_COLLISIONS, appendValue, properties.getIgnoreForCollisions()); APPEND_ENTITY_PROPERTY(PROP_COLLISIONS_WILL_MOVE, appendValue, properties.getCollisionsWillMove()); - APPEND_ENTITY_PROPERTY(PROP_IS_SPOTLIGHT, appendValue, properties.getIsSpotlight()); - APPEND_ENTITY_PROPERTY(PROP_DIFFUSE_COLOR, appendColor, properties.getDiffuseColor()); - APPEND_ENTITY_PROPERTY(PROP_AMBIENT_COLOR, appendColor, properties.getAmbientColor()); - APPEND_ENTITY_PROPERTY(PROP_SPECULAR_COLOR, appendColor, properties.getSpecularColor()); - APPEND_ENTITY_PROPERTY(PROP_CONSTANT_ATTENUATION, appendValue, properties.getConstantAttenuation()); - APPEND_ENTITY_PROPERTY(PROP_LINEAR_ATTENUATION, appendValue, properties.getLinearAttenuation()); - APPEND_ENTITY_PROPERTY(PROP_QUADRATIC_ATTENUATION, appendValue, properties.getQuadraticAttenuation()); - APPEND_ENTITY_PROPERTY(PROP_EXPONENT, appendValue, properties.getExponent()); - APPEND_ENTITY_PROPERTY(PROP_CUTOFF, appendValue, properties.getCutoff()); APPEND_ENTITY_PROPERTY(PROP_LOCKED, appendValue, properties.getLocked()); - APPEND_ENTITY_PROPERTY(PROP_TEXTURES, appendValue, properties.getTextures()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, appendValue, properties.getAnimationSettings()); APPEND_ENTITY_PROPERTY(PROP_USER_DATA, appendValue, properties.getUserData()); + + if (properties.getType() == EntityTypes::Text) { + APPEND_ENTITY_PROPERTY(PROP_TEXT, appendValue, properties.getText()); + APPEND_ENTITY_PROPERTY(PROP_LINE_HEIGHT, appendValue, properties.getLineHeight()); + APPEND_ENTITY_PROPERTY(PROP_TEXT_COLOR, appendColor, properties.getTextColor()); + APPEND_ENTITY_PROPERTY(PROP_BACKGROUND_COLOR, appendColor, properties.getBackgroundColor()); + } + + if (properties.getType() == EntityTypes::Model) { + APPEND_ENTITY_PROPERTY(PROP_MODEL_URL, appendValue, properties.getModelURL()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, appendValue, properties.getAnimationURL()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, appendValue, properties.getAnimationFPS()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, appendValue, properties.getAnimationFrameIndex()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, appendValue, properties.getAnimationIsPlaying()); + APPEND_ENTITY_PROPERTY(PROP_TEXTURES, appendValue, properties.getTextures()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, appendValue, properties.getAnimationSettings()); + } + + if (properties.getType() == EntityTypes::Light) { + APPEND_ENTITY_PROPERTY(PROP_IS_SPOTLIGHT, appendValue, properties.getIsSpotlight()); + APPEND_ENTITY_PROPERTY(PROP_DIFFUSE_COLOR, appendColor, properties.getDiffuseColor()); + APPEND_ENTITY_PROPERTY(PROP_AMBIENT_COLOR, appendColor, properties.getAmbientColor()); + APPEND_ENTITY_PROPERTY(PROP_SPECULAR_COLOR, appendColor, properties.getSpecularColor()); + APPEND_ENTITY_PROPERTY(PROP_CONSTANT_ATTENUATION, appendValue, properties.getConstantAttenuation()); + APPEND_ENTITY_PROPERTY(PROP_LINEAR_ATTENUATION, appendValue, properties.getLinearAttenuation()); + APPEND_ENTITY_PROPERTY(PROP_QUADRATIC_ATTENUATION, appendValue, properties.getQuadraticAttenuation()); + APPEND_ENTITY_PROPERTY(PROP_EXPONENT, appendValue, properties.getExponent()); + APPEND_ENTITY_PROPERTY(PROP_CUTOFF, appendValue, properties.getCutoff()); + } } if (propertyCount > 0) { int endOfEntityItemData = packetData->getUncompressedByteOffset(); @@ -705,30 +736,43 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LIFETIME, float, setLifetime); READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_SCRIPT,setScript); READ_ENTITY_PROPERTY_COLOR_TO_PROPERTIES(PROP_COLOR, setColor); - READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_MODEL_URL, setModelURL); - READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_ANIMATION_URL, setAnimationURL); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_FPS, float, setAnimationFPS); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_FRAME_INDEX, float, setAnimationFrameIndex); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_REGISTRATION_POINT, glm::vec3, setRegistrationPoint); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANGULAR_VELOCITY, glm::vec3, setAngularVelocity); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANGULAR_DAMPING, float, setAngularDamping); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VISIBLE, bool, setVisible); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_IGNORE_FOR_COLLISIONS, bool, setIgnoreForCollisions); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLLISIONS_WILL_MOVE, bool, setCollisionsWillMove); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_IS_SPOTLIGHT, bool, setIsSpotlight); - READ_ENTITY_PROPERTY_COLOR_TO_PROPERTIES(PROP_DIFFUSE_COLOR, setDiffuseColor); - READ_ENTITY_PROPERTY_COLOR_TO_PROPERTIES(PROP_AMBIENT_COLOR, setAmbientColor); - READ_ENTITY_PROPERTY_COLOR_TO_PROPERTIES(PROP_SPECULAR_COLOR, setSpecularColor); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CONSTANT_ATTENUATION, float, setConstantAttenuation); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINEAR_ATTENUATION, float, setLinearAttenuation); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_QUADRATIC_ATTENUATION, float, setQuadraticAttenuation); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EXPONENT, float, setExponent); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CUTOFF, float, setCutoff); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LOCKED, bool, setLocked); - READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_TEXTURES, setTextures); - READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_ANIMATION_SETTINGS, setAnimationSettings); READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_USER_DATA, setUserData); + + if (properties.getType() == EntityTypes::Text) { + READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_TEXT, setText); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_HEIGHT, float, setLineHeight); + READ_ENTITY_PROPERTY_COLOR_TO_PROPERTIES(PROP_TEXT_COLOR, setTextColor); + READ_ENTITY_PROPERTY_COLOR_TO_PROPERTIES(PROP_BACKGROUND_COLOR, setBackgroundColor); + } + + if (properties.getType() == EntityTypes::Model) { + READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_MODEL_URL, setModelURL); + READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_ANIMATION_URL, setAnimationURL); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_FPS, float, setAnimationFPS); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_FRAME_INDEX, float, setAnimationFrameIndex); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying); + READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_TEXTURES, setTextures); + READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_ANIMATION_SETTINGS, setAnimationSettings); + } + + if (properties.getType() == EntityTypes::Light) { + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_IS_SPOTLIGHT, bool, setIsSpotlight); + READ_ENTITY_PROPERTY_COLOR_TO_PROPERTIES(PROP_DIFFUSE_COLOR, setDiffuseColor); + READ_ENTITY_PROPERTY_COLOR_TO_PROPERTIES(PROP_AMBIENT_COLOR, setAmbientColor); + READ_ENTITY_PROPERTY_COLOR_TO_PROPERTIES(PROP_SPECULAR_COLOR, setSpecularColor); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CONSTANT_ATTENUATION, float, setConstantAttenuation); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINEAR_ATTENUATION, float, setLinearAttenuation); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_QUADRATIC_ATTENUATION, float, setQuadraticAttenuation); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EXPONENT, float, setExponent); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CUTOFF, float, setCutoff); + } return valid; } @@ -800,6 +844,11 @@ void EntityItemProperties::markAllChanged() { _cutoffChanged = true; _lockedChanged = true; _texturesChanged = true; + + _textChanged = true; + _lineHeightChanged = true; + _textColorChanged = true; + _backgroundColorChanged = true; } AACube EntityItemProperties::getMaximumAACubeInTreeUnits() const { diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 273aedb18a..10cb18e244 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -83,7 +83,14 @@ enum EntityPropertyList { PROP_ANIMATION_SETTINGS, PROP_USER_DATA, - PROP_LAST_ITEM = PROP_USER_DATA + PROP_LAST_ITEM = PROP_USER_DATA, + + // These properties of TextEntity piggy back off of properties of ModelEntities, the type doesn't matter + // since the derived class knows how to interpret it's own properties and knows the types it expects + PROP_TEXT_COLOR = PROP_COLOR, + PROP_TEXT = PROP_MODEL_URL, + PROP_LINE_HEIGHT = PROP_ANIMATION_URL, + PROP_BACKGROUND_COLOR = PROP_ANIMATION_FPS, }; typedef PropertyFlags EntityPropertyFlags; @@ -102,6 +109,7 @@ class EntityItemProperties { 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 friend class LightEntityItem; // TODO: consider removing this friend relationship and use public methods + friend class TextEntityItem; // TODO: consider removing this friend relationship and use public methods public: EntityItemProperties(); virtual ~EntityItemProperties(); @@ -393,6 +401,12 @@ private: bool _lockedChanged; bool _texturesChanged; + DEFINE_PROPERTY_REF(PROP_TEXT, Text, text, QString); + DEFINE_PROPERTY(PROP_LINE_HEIGHT, LineHeight, lineHeight, float); + DEFINE_PROPERTY_REF(PROP_TEXT_COLOR, TextColor, textColor, xColor); + DEFINE_PROPERTY_REF(PROP_BACKGROUND_COLOR, BackgroundColor, backgroundColor, xColor); + +private: bool _defaultSettings; // NOTE: The following are pseudo client only properties. They are only used in clients which can access diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index 77782cb90f..f61d89dbd2 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -260,6 +260,26 @@ } \ } \ } + +#define CONSTRUCT_PROPERTY(n, V) \ + _##n(V), \ + _##n##Changed(false) + +#define DEFINE_PROPERTY(P, N, n, T) \ + public: \ + T get##N() const { return _##n; } \ + void set##N(T value) { _##n = value; _##n##Changed = true; } \ + private: \ + T _##n; \ + bool _##n##Changed; + +#define DEFINE_PROPERTY_REF(P, N, n, T) \ + public: \ + const T& get##N() const { return _##n; } \ + void set##N(const T& value) { _##n = value; _##n##Changed = true; } \ + private: \ + T _##n; \ + bool _##n##Changed; diff --git a/libraries/entities/src/EntityTypes.cpp b/libraries/entities/src/EntityTypes.cpp index aaa297f4fd..194df024e0 100644 --- a/libraries/entities/src/EntityTypes.cpp +++ b/libraries/entities/src/EntityTypes.cpp @@ -22,6 +22,7 @@ #include "LightEntityItem.h" #include "ModelEntityItem.h" #include "SphereEntityItem.h" +#include "TextEntityItem.h" QMap EntityTypes::_typeToNameMap; QMap EntityTypes::_nameToTypeMap; @@ -35,6 +36,7 @@ REGISTER_ENTITY_TYPE(Model) REGISTER_ENTITY_TYPE(Box) REGISTER_ENTITY_TYPE(Sphere) REGISTER_ENTITY_TYPE(Light) +REGISTER_ENTITY_TYPE(Text) const QString& EntityTypes::getEntityTypeName(EntityType entityType) { diff --git a/libraries/entities/src/EntityTypes.h b/libraries/entities/src/EntityTypes.h index 85bbff99ef..8ed407f11d 100644 --- a/libraries/entities/src/EntityTypes.h +++ b/libraries/entities/src/EntityTypes.h @@ -34,7 +34,8 @@ public: Box, Sphere, Light, - LAST = Light + Text, + LAST = Text } EntityType; static const QString& getEntityTypeName(EntityType entityType); diff --git a/libraries/entities/src/TextEntityItem.cpp b/libraries/entities/src/TextEntityItem.cpp new file mode 100644 index 0000000000..491240c178 --- /dev/null +++ b/libraries/entities/src/TextEntityItem.cpp @@ -0,0 +1,113 @@ +// +// TextEntityItem.cpp +// libraries/entities/src +// +// Created by Brad Hefta-Gaub on 12/4/13. +// Copyright 2013 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 +// + + +#include + +#include + +#include "EntityTree.h" +#include "EntityTreeElement.h" +#include "TextEntityItem.h" + + +const QString TextEntityItem::DEFAULT_TEXT(""); +const float TextEntityItem::DEFAULT_LINE_HEIGHT = 0.1f; +const xColor TextEntityItem::DEFAULT_TEXT_COLOR = { 255, 255, 255 }; +const xColor TextEntityItem::DEFAULT_BACKGROUND_COLOR = { 0, 0, 0}; + +EntityItem* TextEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { + EntityItem* result = new TextEntityItem(entityID, properties); + return result; +} + +TextEntityItem::TextEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : + EntityItem(entityItemID) +{ + _type = EntityTypes::Text; + _created = properties.getCreated(); + setProperties(properties, true); +} + +EntityItemProperties TextEntityItem::getProperties() const { + EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class + + COPY_ENTITY_PROPERTY_TO_PROPERTIES(text, getText); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineHeight, getLineHeight); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(textColor, getTextColorX); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(backgroundColor, getBackgroundColorX); + return properties; +} + +bool TextEntityItem::setProperties(const EntityItemProperties& properties, bool forceCopy) { + bool somethingChanged = false; + somethingChanged = EntityItem::setProperties(properties, forceCopy); // set the properties in our base class + + SET_ENTITY_PROPERTY_FROM_PROPERTIES(text, setText); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(lineHeight, setLineHeight); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(textColor, setTextColor); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(backgroundColor, setBackgroundColor); + + if (somethingChanged) { + bool wantDebug = false; + if (wantDebug) { + uint64_t now = usecTimestampNow(); + int elapsed = now - getLastEdited(); + qDebug() << "TextEntityItem::setProperties() AFTER update... edited AGO=" << elapsed << + "now=" << now << " getLastEdited()=" << getLastEdited(); + } + setLastEdited(properties._lastEdited); + } + + return somethingChanged; +} + +int TextEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + + int bytesRead = 0; + const unsigned char* dataAt = data; + + READ_ENTITY_PROPERTY_STRING(PROP_TEXT, setText); + READ_ENTITY_PROPERTY(PROP_LINE_HEIGHT, float, _lineHeight); + READ_ENTITY_PROPERTY_COLOR(PROP_TEXT_COLOR, _textColor); + READ_ENTITY_PROPERTY_COLOR(PROP_BACKGROUND_COLOR, _backgroundColor); + + return bytesRead; +} + + +// TODO: eventually only include properties changed since the params.lastViewFrustumSent time +EntityPropertyFlags TextEntityItem::getEntityProperties(EncodeBitstreamParams& params) const { + EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); + requestedProperties += PROP_TEXT; + requestedProperties += PROP_LINE_HEIGHT; + requestedProperties += PROP_TEXT_COLOR; + requestedProperties += PROP_BACKGROUND_COLOR; + return requestedProperties; +} + +void TextEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeData* modelTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const { + + bool successPropertyFits = true; + + APPEND_ENTITY_PROPERTY(PROP_TEXT, appendValue, getText()); + APPEND_ENTITY_PROPERTY(PROP_LINE_HEIGHT, appendValue, getLineHeight()); + APPEND_ENTITY_PROPERTY(PROP_TEXT_COLOR, appendColor, getTextColor()); + APPEND_ENTITY_PROPERTY(PROP_BACKGROUND_COLOR, appendColor, getBackgroundColor()); +} \ No newline at end of file diff --git a/libraries/entities/src/TextEntityItem.h b/libraries/entities/src/TextEntityItem.h new file mode 100644 index 0000000000..019d230c36 --- /dev/null +++ b/libraries/entities/src/TextEntityItem.h @@ -0,0 +1,81 @@ +// +// TextEntityItem.h +// libraries/entities/src +// +// Created by Brad Hefta-Gaub on 12/4/13. +// Copyright 2013 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 +// + +#ifndef hifi_TextEntityItem_h +#define hifi_TextEntityItem_h + +#include "EntityItem.h" + +class TextEntityItem : public EntityItem { +public: + static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties); + + TextEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties); + + ALLOW_INSTANTIATION // This class can be instantiated + + // methods for getting/setting all properties of an entity + virtual EntityItemProperties getProperties() const; + virtual bool setProperties(const EntityItemProperties& properties, bool forceCopy = false); + + // TODO: eventually only include properties changed since the params.lastViewFrustumSent time + virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const; + + virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeData* modelTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const; + + virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + + static const QString DEFAULT_TEXT; + void setText(const QString& value) { _text = value; } + const QString& getText() const { return _text; } + + static const float DEFAULT_LINE_HEIGHT; + void setLineHeight(float value) { _lineHeight = value; } + float getLineHeight() const { return _lineHeight; } + + static const xColor DEFAULT_TEXT_COLOR; + const rgbColor& getTextColor() const { return _textColor; } + xColor getTextColorX() const { xColor color = { _textColor[RED_INDEX], _textColor[GREEN_INDEX], _textColor[BLUE_INDEX] }; return color; } + + void setTextColor(const rgbColor& value) { memcpy(_textColor, value, sizeof(_textColor)); } + void setTextColor(const xColor& value) { + _textColor[RED_INDEX] = value.red; + _textColor[GREEN_INDEX] = value.green; + _textColor[BLUE_INDEX] = value.blue; + } + + static const xColor DEFAULT_BACKGROUND_COLOR; + const rgbColor& getBackgroundColor() const { return _backgroundColor; } + xColor getBackgroundColorX() const { xColor color = { _backgroundColor[RED_INDEX], _backgroundColor[GREEN_INDEX], _backgroundColor[BLUE_INDEX] }; return color; } + + void setBackgroundColor(const rgbColor& value) { memcpy(_backgroundColor, value, sizeof(_backgroundColor)); } + void setBackgroundColor(const xColor& value) { + _backgroundColor[RED_INDEX] = value.red; + _backgroundColor[GREEN_INDEX] = value.green; + _backgroundColor[BLUE_INDEX] = value.blue; + } + +protected: + QString _text; + float _lineHeight; + rgbColor _textColor; + rgbColor _backgroundColor; +}; + +#endif // hifi_TextEntityItem_h From dd349ebfd1725c862fa7dbacd4be550c86d2cfc3 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Nov 2014 16:03:43 -0800 Subject: [PATCH 55/94] coding standard cleanup, fix warning --- interface/src/ui/overlays/Overlays.h | 3 ++- libraries/octree/src/OctreeHeadlessViewer.h | 3 ++- libraries/octree/src/OctreeRenderer.h | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index d49ffcc3d0..312d872eb7 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -51,7 +51,8 @@ public: ~Overlays(); void init(QGLWidget* parent); void update(float deltatime); - void render3D(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::RenderSide renderSide = RenderArgs::MONO); + void render3D(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, + RenderArgs::RenderSide renderSide = RenderArgs::MONO); void render2D(); public slots: diff --git a/libraries/octree/src/OctreeHeadlessViewer.h b/libraries/octree/src/OctreeHeadlessViewer.h index 03b8a204e0..9a6a5c7102 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.h +++ b/libraries/octree/src/OctreeHeadlessViewer.h @@ -33,7 +33,8 @@ public: virtual void renderElement(OctreeElement* element, RenderArgs* args) { /* swallow these */ } virtual void init(); - virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE) { /* swallow these */ } + virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, + RenderArgs::RenderSide renderSide = RenderArgs::MONO) { /* swallow these */ } void setJurisdictionListener(JurisdictionListener* jurisdictionListener) { _jurisdictionListener = jurisdictionListener; } diff --git a/libraries/octree/src/OctreeRenderer.h b/libraries/octree/src/OctreeRenderer.h index e8612b4cb6..2999f34fb6 100644 --- a/libraries/octree/src/OctreeRenderer.h +++ b/libraries/octree/src/OctreeRenderer.h @@ -52,7 +52,8 @@ public: virtual void init(); /// render the content of the octree - virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::RenderSide renderSide = RenderArgs::MONO); + virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, + RenderArgs::RenderSide renderSide = RenderArgs::MONO); ViewFrustum* getViewFrustum() const { return _viewFrustum; } void setViewFrustum(ViewFrustum* viewFrustum) { _viewFrustum = viewFrustum; } From 9657e7a469e47479c35b6c34fbb4fe45af3ae074 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Nov 2014 16:28:47 -0800 Subject: [PATCH 56/94] add text entity editing to editModels and entityPropertyDialogBox --- examples/editModels.js | 35 ++++++++++++++++ examples/libraries/entityPropertyDialogBox.js | 40 +++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/examples/editModels.js b/examples/editModels.js index 7538a83fef..0fc5d4a7f9 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -48,6 +48,9 @@ var RIGHT = 1; var SPAWN_DISTANCE = 1; var DEFAULT_DIMENSION = 0.20; +var DEFAULT_TEXT_DIMENSION_X = 1.0; +var DEFAULT_TEXT_DIMENSION_Y = 1.0; +var DEFAULT_TEXT_DIMENSION_Z = 0.01; var modelURLs = [ HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Alder.fbx", @@ -1122,6 +1125,7 @@ var toolBar = (function () { newModelButton, newCubeButton, newSphereButton, + newTextButton, browseModelsButton, loadURLMenuItem, loadFileMenuItem, @@ -1208,6 +1212,18 @@ var toolBar = (function () { alpha: 0.9, visible: true }); + + print(toolIconUrl + "add-text.svg"); + + newTextButton = toolBar.addTool({ + imageURL: toolIconUrl + "add-text.svg", + subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + width: toolWidth, + height: toolHeight, + alpha: 0.9, + visible: true + }); + } @@ -1372,6 +1388,25 @@ var toolBar = (function () { } + if (newTextButton === toolBar.clicked(clickedOverlay)) { + var position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), SPAWN_DISTANCE)); + + if (position.x > 0 && position.y > 0 && position.z > 0) { + Entities.addEntity({ + type: "Text", + position: position, + dimensions: { x: DEFAULT_TEXT_DIMENSION_X, y: DEFAULT_TEXT_DIMENSION_Y, z: DEFAULT_TEXT_DIMENSION_Z }, + backgroundColor: { red: 255, green: 0, blue: 0 }, + textColor: { red: 255, green: 255, blue: 255 }, + text: "some text", + lineHight: "0.1" + }); + } else { + print("Can't create box: Text would be out of bounds."); + } + return true; + } + return false; }; diff --git a/examples/libraries/entityPropertyDialogBox.js b/examples/libraries/entityPropertyDialogBox.js index da60e0c370..3dae431e9a 100644 --- a/examples/libraries/entityPropertyDialogBox.js +++ b/examples/libraries/entityPropertyDialogBox.js @@ -65,6 +65,30 @@ EntityPropertyDialogBox = (function () { array.push({ label: "Original Textures:\n" + properties.originalTextures, type: "header" }); index++; } + + if (properties.type == "Text") { + array.push({ label: "Text:", value: properties.text }); + index++; + array.push({ label: "Line Height:", value: properties.lineHeight }); + index++; + array.push({ label: "Text Color:", type: "header" }); + index++; + array.push({ label: "Red:", value: properties.textColor.red }); + index++; + array.push({ label: "Green:", value: properties.textColor.green }); + index++; + array.push({ label: "Blue:", value: properties.textColor.blue }); + index++; + array.push({ label: "Background Color:", type: "header" }); + index++; + array.push({ label: "Red:", value: properties.backgroundColor.red }); + index++; + array.push({ label: "Green:", value: properties.backgroundColor.green }); + index++; + array.push({ label: "Blue:", value: properties.backgroundColor.blue }); + index++; + } + array.push({ label: "Position:", type: "header" }); index++; array.push({ label: "X:", value: properties.position.x.toFixed(decimals) }); @@ -271,6 +295,22 @@ EntityPropertyDialogBox = (function () { properties.textures = array[index++].value; index++; // skip textureNames label } + + if (properties.type == "Text") { + properties.text = array[index++].value; + properties.lineHeight = array[index++].value; + + index++; // skip header + properties.textColor.red = array[index++].value; + properties.textColor.green = array[index++].value; + properties.textColor.blue = array[index++].value; + + index++; // skip header + properties.backgroundColor.red = array[index++].value; + properties.backgroundColor.green = array[index++].value; + properties.backgroundColor.blue = array[index++].value; + } + index++; // skip header properties.position.x = array[index++].value; properties.position.y = array[index++].value; From f31b5aba275867e38087604ba87d4f491448e567 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Nov 2014 16:31:50 -0800 Subject: [PATCH 57/94] use actual background color --- interface/src/entities/RenderableTextEntityItem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/entities/RenderableTextEntityItem.cpp b/interface/src/entities/RenderableTextEntityItem.cpp index 601cbb347a..771962ecc6 100644 --- a/interface/src/entities/RenderableTextEntityItem.cpp +++ b/interface/src/entities/RenderableTextEntityItem.cpp @@ -51,7 +51,7 @@ void RenderableTextEntityItem::render(RenderArgs* args) { glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); const float MAX_COLOR = 255.0f; - xColor backgroundColor = { 255, 0, 0 }; //getBackgroundColorX(); + xColor backgroundColor = getBackgroundColorX(); float alpha = 1.0f; //getBackgroundAlpha(); glColor4f(backgroundColor.red / MAX_COLOR, backgroundColor.green / MAX_COLOR, backgroundColor.blue / MAX_COLOR, alpha); From 87d472a5a966da0feaf9a0ffb65412f5125156ac Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 14 Nov 2014 16:15:22 -0800 Subject: [PATCH 58/94] 2 space indent -> 4 space indent --- examples/entityScripts/chessPiece.js | 362 ++++++++++++------------ examples/playChess.js | 394 +++++++++++++-------------- 2 files changed, 379 insertions(+), 377 deletions(-) diff --git a/examples/entityScripts/chessPiece.js b/examples/entityScripts/chessPiece.js index 0c7c6da8a7..ebe2df7e55 100644 --- a/examples/entityScripts/chessPiece.js +++ b/examples/entityScripts/chessPiece.js @@ -1,205 +1,207 @@ (function(){ - this.FIRST_TILE = null; // Global position of the first tile (1a) - this.TILE_SIZE = null; // Size of one tile - this.whitesDeadPieces = null; - this.blacksDeadPieces = null; + this.FIRST_TILE = null; // Global position of the first tile (1a) + this.TILE_SIZE = null; // Size of one tile + this.whitesDeadPieces = null; + this.blacksDeadPieces = null; - this.wantDebug = false; - this.active = false; + this.wantDebug = false; + this.active = false; - this.entityID = null; - this.properties = null; - this.boardID = null; - this.boardUserData = null; + this.entityID = null; + this.properties = null; + this.boardID = null; + this.boardUserData = null; - this.sound = null; - this.startingTile = null; - this.pieces = new Array(); + this.sound = null; + this.startingTile = null; + this.pieces = new Array(); - // All callbacks start by updating the properties - this.updateProperties = function(entityID) { - // Piece ID - if (this.entityID === null || !this.entityID.isKnownID) { - this.entityID = Entities.identifyEntity(entityID); - } - // Piece Properties - this.properties = Entities.getEntityProperties(this.entityID); + // All callbacks start by updating the properties + this.updateProperties = function(entityID) { + // Piece ID + if (this.entityID === null || !this.entityID.isKnownID) { + this.entityID = Entities.identifyEntity(entityID); + } + // Piece Properties + this.properties = Entities.getEntityProperties(this.entityID); - // Board ID - if (this.boardID === null) { - // Read user data string and update boardID - var userData = JSON.parse(this.properties.userData); - var boardID = Entities.identifyEntity(userData.boardID); - if (boardID.isKnownID) { - this.boardID = boardID; - } else { - return; - } - } + // Board ID + if (this.boardID === null) { + // Read user data string and update boardID + var userData = JSON.parse(this.properties.userData); + var boardID = Entities.identifyEntity(userData.boardID); + if (boardID.isKnownID) { + this.boardID = boardID; + } else { + return; + } + } - // Board User Data - this.updateUserData(); - } - // Get an entity's user data - this.getEntityUserData = function(entityID) { - var properties = Entities.getEntityProperties(entityID); - - if (properties && properties.userData){ - return JSON.parse(properties.userData); - } else { - print("No user data found."); - return null; + // Board User Data + this.updateUserData(); } - } - // Updates user data related objects - this.updateUserData = function() { - // Get board's user data - if (this.boardID !== null && this.boardID.isKnownID) { - this.boardUserData = this.getEntityUserData(this.boardID); - if (!(this.boardUserData && - this.boardUserData.firstTile && - this.boardUserData.tileSize && - this.boardUserData.whitesDeadPieces && - this.boardUserData.blacksDeadPieces)) { - print("Incomplete boardUserData " + this.boardID.id); - } else { - this.FIRST_TILE = this.boardUserData.firstTile; - this.TILE_SIZE = this.boardUserData.tileSize; - this.whitesDeadPieces = this.boardUserData.whitesDeadPieces; - this.blacksDeadPieces = this.boardUserData.blacksDeadPieces; + // Get an entity's user data + this.getEntityUserData = function(entityID) { + var properties = Entities.getEntityProperties(entityID); + + if (properties && properties.userData){ + return JSON.parse(properties.userData); + } else { + print("No user data found."); + return null; + } + } + // Updates user data related objects + this.updateUserData = function() { + // Get board's user data + if (this.boardID !== null && this.boardID.isKnownID) { + this.boardUserData = this.getEntityUserData(this.boardID); + + if (!(this.boardUserData && + this.boardUserData.firstTile && + this.boardUserData.tileSize && + this.boardUserData.whitesDeadPieces && + this.boardUserData.blacksDeadPieces && + this.boardUserData.pieces)) { + print("Incomplete boardUserData " + this.boardID.id); + } else { + this.FIRST_TILE = this.boardUserData.firstTile; + this.TILE_SIZE = this.boardUserData.tileSize; + this.whitesDeadPieces = this.boardUserData.whitesDeadPieces; + this.blacksDeadPieces = this.boardUserData.blacksDeadPieces; - this.active = true; - } - } else { - print("Missing boardID:" + JSON.stringify(this.boardID)); + this.active = true; + } + } else { + print("Missing boardID:" + JSON.stringify(this.boardID)); + } } - } - // Returns whether pos is inside the grid or not - this.isOutsideGrid = function(pos) { - return !(pos.i >= 0 && pos.j >= 0 && pos.i < 8 && pos.j < 8); - } - // Returns the tile coordinate - this.getIndexPosition = function(position) { - var halfTile = this.TILE_SIZE / 2.0; - var corner = Vec3.sum(this.FIRST_TILE, { x: -halfTile, y: 0.0, z: -halfTile }); - var relative = Vec3.subtract(position, corner); - return { - i: Math.floor(relative.x / this.TILE_SIZE), - j: Math.floor(relative.z / this.TILE_SIZE) + // Returns whether pos is inside the grid or not + this.isOutsideGrid = function(pos) { + return !(pos.i >= 0 && pos.j >= 0 && pos.i < 8 && pos.j < 8); } - } - // Returns the world position - this.getAbsolutePosition = function(pos, halfHeight) { - var relative = { - x: pos.i * this.TILE_SIZE, - y: halfHeight, - z: pos.j * this.TILE_SIZE + // Returns the tile coordinate + this.getIndexPosition = function(position) { + var halfTile = this.TILE_SIZE / 2.0; + var corner = Vec3.sum(this.FIRST_TILE, { x: -halfTile, y: 0.0, z: -halfTile }); + var relative = Vec3.subtract(position, corner); + return { + i: Math.floor(relative.x / this.TILE_SIZE), + j: Math.floor(relative.z / this.TILE_SIZE) + } } - return Vec3.sum(this.FIRST_TILE, relative); - } - // Pr, Vr are respectively the Ray's Point of origin and Vector director - // Pp, Np are respectively the Plane's Point of origin and Normal vector - this.rayPlaneIntersection = function(Pr, Vr, Pp, Np) { - var d = -Vec3.dot(Pp, Np); - var t = -(Vec3.dot(Pr, Np) + d) / Vec3.dot(Vr, Np); - return Vec3.sum(Pr, Vec3.multiply(t, Vr)); - } - // Download sound if needed - this.maybeDownloadSound = function() { - if (this.sound === null) { - this.sound = SoundCache.getSound("http://public.highfidelity.io/sounds/Footsteps/FootstepW3Left-12db.wav"); + // Returns the world position + this.getAbsolutePosition = function(pos, halfHeight) { + var relative = { + x: pos.i * this.TILE_SIZE, + y: halfHeight, + z: pos.j * this.TILE_SIZE + } + return Vec3.sum(this.FIRST_TILE, relative); } - } - // Play drop sound - this.playSound = function() { - if (this.sound && this.sound.downloaded) { - Audio.playSound(this.sound, { position: this.properties.position }); + // Pr, Vr are respectively the Ray's Point of origin and Vector director + // Pp, Np are respectively the Plane's Point of origin and Normal vector + this.rayPlaneIntersection = function(Pr, Vr, Pp, Np) { + var d = -Vec3.dot(Pp, Np); + var t = -(Vec3.dot(Pr, Np) + d) / Vec3.dot(Vr, Np); + return Vec3.sum(Pr, Vec3.multiply(t, Vr)); } - } - // updates the piece position based on mouse input - this.updatePosition = function(mouseEvent) { - var pickRay = Camera.computePickRay(mouseEvent.x, mouseEvent.y) - var upVector = { x: 0, y: 1, z: 0 }; - var intersection = this.rayPlaneIntersection(pickRay.origin, pickRay.direction, - this.properties.position, upVector); - // if piece outside grid then send it back to the starting tile - if (this.isOutsideGrid(this.getIndexPosition(intersection))) { - intersection = this.getAbsolutePosition(this.startingTile, this.properties.dimensions.y / 2.0); + // Download sound if needed + this.maybeDownloadSound = function() { + if (this.sound === null) { + this.sound = SoundCache.getSound("http://public.highfidelity.io/sounds/Footsteps/FootstepW3Left-12db.wav"); + } } - Entities.editEntity(this.entityID, { position: intersection }); - } - // Snap piece to the center of the tile it is on - this.snapToGrid = function() { - var pos = this.getIndexPosition(this.properties.position); - var finalPos = this.getAbsolutePosition((this.isOutsideGrid(pos)) ? this.startingTile : pos, - this.properties.dimensions.y / 2.0); - Entities.editEntity(this.entityID, { position: finalPos }); - } - this.moveDeadPiece = function() { - var myPos = this.getIndexPosition(this.properties.position); + // Play drop sound + this.playSound = function() { + if (this.sound && this.sound.downloaded) { + Audio.playSound(this.sound, { position: this.properties.position }); + } + } + // updates the piece position based on mouse input + this.updatePosition = function(mouseEvent) { + var pickRay = Camera.computePickRay(mouseEvent.x, mouseEvent.y) + var upVector = { x: 0, y: 1, z: 0 }; + var intersection = this.rayPlaneIntersection(pickRay.origin, pickRay.direction, + this.properties.position, upVector); + // if piece outside grid then send it back to the starting tile + if (this.isOutsideGrid(this.getIndexPosition(intersection))) { + intersection = this.getAbsolutePosition(this.startingTile, this.properties.dimensions.y / 2.0); + } + Entities.editEntity(this.entityID, { position: intersection }); + } + // Snap piece to the center of the tile it is on + this.snapToGrid = function() { + var pos = this.getIndexPosition(this.properties.position); + var finalPos = this.getAbsolutePosition((this.isOutsideGrid(pos)) ? this.startingTile : pos, + this.properties.dimensions.y / 2.0); + Entities.editEntity(this.entityID, { position: finalPos }); + } + this.moveDeadPiece = function() { + var myPos = this.getIndexPosition(this.properties.position); - for (var i = 0; i < this.boardUserData.pieces.length; i++) { - var piece = this.boardUserData.pieces[i]; + for (var i = 0; i < this.boardUserData.pieces.length; i++) { + var piece = this.boardUserData.pieces[i]; - if (piece.id != this.entityID.id) { - var properties = Entities.getEntityProperties(piece); + if (piece.id != this.entityID.id) { + var properties = Entities.getEntityProperties(piece); - var isWhite = properties.modelURL.search("White") !== -1; - var type = (properties.modelURL.search("King") !== -1) ? 4 : - (properties.modelURL.search("Queen") !== -1) ? 3 : - (properties.modelURL.search("Rook") !== -1) ? 2 : - (properties.modelURL.search("Knight") !== -1) ? 1 : - (properties.modelURL.search("Bishop") !== -1) ? 0 : - (properties.modelURL.search("Pawn") !== -1) ? -1 : -2; + var isWhite = properties.modelURL.search("White") !== -1; + var type = (properties.modelURL.search("King") !== -1) ? 4 : + (properties.modelURL.search("Queen") !== -1) ? 3 : + (properties.modelURL.search("Rook") !== -1) ? 2 : + (properties.modelURL.search("Knight") !== -1) ? 1 : + (properties.modelURL.search("Bishop") !== -1) ? 0 : + (properties.modelURL.search("Pawn") !== -1) ? -1 : -2; - var piecePos = this.getIndexPosition(properties.position); - if (myPos.i === piecePos.i && myPos.j === piecePos.j) { - var position = this.getAbsolutePosition((isWhite) ? { i: type, j: -1 } : { i: 7 - type, j: 8 }, - properties.dimensions.y / 2.0); - Entities.editEntity(piece, { - position: position - }); - break; - } - } - } - } + var piecePos = this.getIndexPosition(properties.position); + if (myPos.i === piecePos.i && myPos.j === piecePos.j) { + var position = this.getAbsolutePosition((isWhite) ? { i: type, j: -1 } : { i: 7 - type, j: 8 }, + properties.dimensions.y / 2.0); + Entities.editEntity(piece, { + position: position + }); + break; + } + } + } + } - this.grab = function(mouseEvent) { - if (this.active) { - this.startingTile = this.getIndexPosition(this.properties.position); - this.updatePosition(mouseEvent); + this.grab = function(mouseEvent) { + if (this.active) { + this.startingTile = this.getIndexPosition(this.properties.position); + this.updatePosition(mouseEvent); + } } - } - this.move = function(mouseEvent) { - if (this.active) { - this.updatePosition(mouseEvent); + this.move = function(mouseEvent) { + if (this.active) { + this.updatePosition(mouseEvent); + } } - } - this.release = function(mouseEvent) { - if (this.active) { - this.updatePosition(mouseEvent); - this.snapToGrid(); - this.moveDeadPiece(); - this.playSound(); + this.release = function(mouseEvent) { + if (this.active) { + this.updatePosition(mouseEvent); + this.snapToGrid(); + this.moveDeadPiece(); + this.playSound(); + } } - } - this.preload = function(entityID) { - this.updateProperties(entityID); // All callbacks start by updating the properties - this.maybeDownloadSound(); - } - this.clickDownOnEntity = function(entityID, mouseEvent) { - this.preload(entityID); // TODO : remove - this.updateProperties(entityID); // All callbacks start by updating the properties - this.grab(mouseEvent); - }; - this.holdingClickOnEntity = function(entityID, mouseEvent) { - this.updateProperties(entityID); // All callbacks start by updating the properties - this.move(mouseEvent); - }; - this.clickReleaseOnEntity = function(entityID, mouseEvent) { - this.updateProperties(entityID); // All callbacks start by updating the properties - this.release(mouseEvent); - }; + this.preload = function(entityID) { + this.updateProperties(entityID); // All callbacks start by updating the properties + this.maybeDownloadSound(); + } + this.clickDownOnEntity = function(entityID, mouseEvent) { + this.preload(entityID); // TODO : remove + this.updateProperties(entityID); // All callbacks start by updating the properties + this.grab(mouseEvent); + }; + this.holdingClickOnEntity = function(entityID, mouseEvent) { + this.updateProperties(entityID); // All callbacks start by updating the properties + this.move(mouseEvent); + }; + this.clickReleaseOnEntity = function(entityID, mouseEvent) { + this.updateProperties(entityID); // All callbacks start by updating the properties + this.release(mouseEvent); + }; }) \ No newline at end of file diff --git a/examples/playChess.js b/examples/playChess.js index 8a72e1ebb8..1b6882ed6e 100644 --- a/examples/playChess.js +++ b/examples/playChess.js @@ -14,266 +14,266 @@ var gameSize = 1.0; // Script namespace var extraDebug = extraDebug || true; var ChessGame = ChessGame || { - BOARD: { - modelURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Board.fbx", - dimensions: { x: 773.191, y: 20.010, z: 773.191 }, - rotation: Quat.fromPitchYawRollDegrees(0, 90, 0), - numTiles: 10.0 - }, - KING: 0, QUEEN: 1, BISHOP: 2, KNIGHT: 3, ROOK: 4, PAWN: 5, + BOARD: { + modelURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/Board.fbx", + dimensions: { x: 773.191, y: 20.010, z: 773.191 }, + rotation: Quat.fromPitchYawRollDegrees(0, 90, 0), + numTiles: 10.0 + }, + KING: 0, QUEEN: 1, BISHOP: 2, KNIGHT: 3, ROOK: 4, PAWN: 5, - board: null, - pieces: new Array() + board: null, + pieces: new Array() }; ChessGame.getPieceInfo = function(type, isWhite) { - var info = { - modelURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/", - dimensions: { x: 1.0, y: 1.0, z: 1.0 }, - rotation: Quat.fromPitchYawRollDegrees(0, 0, 0) - } + var info = { + modelURL: "https://s3.amazonaws.com/hifi-public/models/props/chess/", + dimensions: { x: 1.0, y: 1.0, z: 1.0 }, + rotation: Quat.fromPitchYawRollDegrees(0, 0, 0) + } - switch(type) { - case ChessGame.KING: - info.modelURL += "King"; - info.dimensions = { x: 110.496, y: 306.713, z: 110.496 }; - info.rotation = Quat.fromPitchYawRollDegrees(0, 90, 0); - break; - case ChessGame.QUEEN: - info.modelURL += "Queen"; - info.dimensions = { x: 110.496, y: 257.459, z: 110.496 }; - break; - case ChessGame.BISHOP: - info.modelURL += "Bishop"; - info.dimensions = { x: 102.002, y: 213.941, z: 102.002 }; - info.rotation = Quat.fromPitchYawRollDegrees(0, 90, 0); - break; - case ChessGame.KNIGHT: - info.modelURL += "Knight"; - info.dimensions = { x: 95.602, y: 186.939, z: 95.602 }; - info.rotation = Quat.fromPitchYawRollDegrees(0, 180, 0); - break; - case ChessGame.ROOK: - info.modelURL += "Rook"; - info.dimensions = { x: 101.024, y: 167.523, z: 101.024 }; - break; - case ChessGame.PAWN: - info.modelURL += "Pawn"; - info.dimensions = { x: 93.317, y: 138.747, z: 93.317 }; - break; - } - info.modelURL += ((isWhite) ? "_White" : "_Black") + ".fbx" + switch(type) { + case ChessGame.KING: + info.modelURL += "King"; + info.dimensions = { x: 110.496, y: 306.713, z: 110.496 }; + info.rotation = Quat.fromPitchYawRollDegrees(0, 90, 0); + break; + case ChessGame.QUEEN: + info.modelURL += "Queen"; + info.dimensions = { x: 110.496, y: 257.459, z: 110.496 }; + break; + case ChessGame.BISHOP: + info.modelURL += "Bishop"; + info.dimensions = { x: 102.002, y: 213.941, z: 102.002 }; + info.rotation = Quat.fromPitchYawRollDegrees(0, 90, 0); + break; + case ChessGame.KNIGHT: + info.modelURL += "Knight"; + info.dimensions = { x: 95.602, y: 186.939, z: 95.602 }; + info.rotation = Quat.fromPitchYawRollDegrees(0, 180, 0); + break; + case ChessGame.ROOK: + info.modelURL += "Rook"; + info.dimensions = { x: 101.024, y: 167.523, z: 101.024 }; + break; + case ChessGame.PAWN: + info.modelURL += "Pawn"; + info.dimensions = { x: 93.317, y: 138.747, z: 93.317 }; + break; + } + info.modelURL += ((isWhite) ? "_White" : "_Black") + ".fbx" - return info; + return info; } // Board class ChessGame.Board = (function(position, scale) { - this.dimensions = Vec3.multiply(1.0 / ChessGame.BOARD.dimensions.x, ChessGame.BOARD.dimensions); // 1 by 1 - this.dimensions = Vec3.multiply(scale, this.dimensions); // scale by scale - this.position = position - this.tileSize = scale / ChessGame.BOARD.numTiles; + this.dimensions = Vec3.multiply(1.0 / ChessGame.BOARD.dimensions.x, ChessGame.BOARD.dimensions); // 1 by 1 + this.dimensions = Vec3.multiply(scale, this.dimensions); // scale by scale + this.position = position + this.tileSize = scale / ChessGame.BOARD.numTiles; - this.userDataObject = { - firstTile: this.tilePosition(1, 1), - tileSize: this.tileSize, - whitesDeadPieces: this.tilePosition(0,0), - blacksDeadPieces: this.tilePosition(9,9), - pieces: new Array() - } - this.entityProperties = { - type: "Model", - modelURL: ChessGame.BOARD.modelURL, - position: this.position, - dimensions: this.dimensions, - userData: this.buildUserDataString() - } - this.entity = null; + this.userDataObject = { + firstTile: this.tilePosition(1, 1), + tileSize: this.tileSize, + whitesDeadPieces: this.tilePosition(0,0), + blacksDeadPieces: this.tilePosition(9,9), + pieces: new Array() + } + this.entityProperties = { + type: "Model", + modelURL: ChessGame.BOARD.modelURL, + position: this.position, + dimensions: this.dimensions, + userData: this.buildUserDataString() + } + this.entity = null; }); // Returns the top center point of tile i,j ChessGame.Board.prototype.tilePosition = function(i, j) { - if (!(this.position || this.dimensions || this.tileSize || ChessGame.BOARD.numTiles)) { - print("ChessGame.Board.prototype.tilePosition(): Called before proper initialisation, bailing."); - return null; - } - return { - x: this.position.x + (i - ChessGame.BOARD.numTiles / 2.0 + 0.5) * this.tileSize, - y: this.position.y + this.dimensions.y / 2.0, - z: this.position.z + (j - ChessGame.BOARD.numTiles / 2.0 + 0.5) * this.tileSize - }; + if (!(this.position || this.dimensions || this.tileSize || ChessGame.BOARD.numTiles)) { + print("ChessGame.Board.prototype.tilePosition(): Called before proper initialisation, bailing."); + return null; + } + return { + x: this.position.x + (i - ChessGame.BOARD.numTiles / 2.0 + 0.5) * this.tileSize, + y: this.position.y + this.dimensions.y / 2.0, + z: this.position.z + (j - ChessGame.BOARD.numTiles / 2.0 + 0.5) * this.tileSize + }; } // Checks the color of the tile ChessGame.Board.prototype.isWhite = function(i, j) { - return (i + j) % 2 != 0; + return (i + j) % 2 != 0; } // Build the user data string ChessGame.Board.prototype.buildUserDataString = function() { - return JSON.stringify(this.userDataObject); + return JSON.stringify(this.userDataObject); } // Updates the user data stored by the board ChessGame.Board.prototype.updateUserData = function() { - var userDataString = this.buildUserDataString(); - this.entityProperties.userData = userDataString; - Entities.editEntity(this.entity, { userData: userDataString }); + var userDataString = this.buildUserDataString(); + this.entityProperties.userData = userDataString; + Entities.editEntity(this.entity, { userData: userDataString }); } // Spawns the board using entities ChessGame.Board.prototype.spawn = function() { - if (extraDebug) { - print("Spawning board..."); - } - this.entity = Entities.addEntity(this.entityProperties); - print("Board spawned"); + if (extraDebug) { + print("Spawning board..."); + } + this.entity = Entities.addEntity(this.entityProperties); + print("Board spawned"); } // Cleans up the entities of the board ChessGame.Board.prototype.cleanup = function() { - if (extraDebug) { - print("Cleaning up board..."); - } - Entities.deleteEntity(this.entity); - print("Board cleaned up"); + if (extraDebug) { + print("Cleaning up board..."); + } + Entities.deleteEntity(this.entity); + print("Board cleaned up"); } // Piece class ChessGame.Piece = (function(position, dimensions, url, rotation) { - this.dimensions = dimensions; - this.position = position; - this.position.y += this.dimensions.y / 2.0; + this.dimensions = dimensions; + this.position = position; + this.position.y += this.dimensions.y / 2.0; - this.entityProperties = { - type: "Model", - position: this.position, - rotation: rotation, - dimensions: this.dimensions, - modelURL: url, - /**/ - script: "https://s3.amazonaws.com/hifi-public/scripts/entityScripts/chessPiece.js", - /*/ - script: "file:/Users/clement/hifi/examples/entityScripts/chessPiece.js", - /**/ - userData: this.buildUserDataString() - } - this.entity = null; + this.entityProperties = { + type: "Model", + position: this.position, + rotation: rotation, + dimensions: this.dimensions, + modelURL: url, + /**/ + script: "https://s3.amazonaws.com/hifi-public/scripts/entityScripts/chessPiece.js", + /*/ + script: "file:/Users/clement/hifi/examples/entityScripts/chessPiece.js", + /**/ + userData: this.buildUserDataString() + } + this.entity = null; }); // Build the user data string ChessGame.Piece.prototype.buildUserDataString = function() { - if (!(ChessGame.board !== null || ChessGame.board.entity.isKnownID)) { - print("ChessGame.Piece.prototype.buildUserDataString(): Called before proper initialization, bailing."); - return null; - } - var userDataObject = { - boardID: ChessGame.board.entity, - }; - return JSON.stringify(userDataObject); + if (!(ChessGame.board !== null || ChessGame.board.entity.isKnownID)) { + print("ChessGame.Piece.prototype.buildUserDataString(): Called before proper initialization, bailing."); + return null; + } + var userDataObject = { + boardID: ChessGame.board.entity, + }; + return JSON.stringify(userDataObject); } // Spawns the piece ChessGame.Piece.prototype.spawn = function() { - this.entity = Entities.addEntity(this.entityProperties); + this.entity = Entities.addEntity(this.entityProperties); } // Cleans up the piece ChessGame.Piece.prototype.cleanup = function() { - Entities.deleteEntity(this.entity); + Entities.deleteEntity(this.entity); } ChessGame.makePiece = function(piece, i, j, isWhite) { - var info = ChessGame.getPieceInfo(piece, isWhite); - var url = info.modelURL; - var size = Vec3.multiply(0.5 * (1.0 / ChessGame.BOARD.dimensions.x), info.dimensions); - var rotation = (isWhite) ? info.rotation - : Quat.multiply(Quat.fromPitchYawRollDegrees(0, 180, 0), - info.rotation); - var position = ChessGame.board.tilePosition(i, j); + var info = ChessGame.getPieceInfo(piece, isWhite); + var url = info.modelURL; + var size = Vec3.multiply(0.5 * (1.0 / ChessGame.BOARD.dimensions.x), info.dimensions); + var rotation = (isWhite) ? info.rotation + : Quat.multiply(Quat.fromPitchYawRollDegrees(0, 180, 0), + info.rotation); + var position = ChessGame.board.tilePosition(i, j); - var piece = new ChessGame.Piece(position, size, url, rotation); - piece.spawn(); - ChessGame.pieces.push(piece); - return piece; + var piece = new ChessGame.Piece(position, size, url, rotation); + piece.spawn(); + ChessGame.pieces.push(piece); + return piece; } ChessGame.scriptStarting = function() { - print("playChess.js started"); - gamePosition = Vec3.sum(MyAvatar.position, - Vec3.multiplyQbyV(MyAvatar.orientation, - { x: 0, y: 0, z: -1 })); - // Setup board - ChessGame.board = new ChessGame.Board(gamePosition, gameSize); - ChessGame.board.spawn(); + print("playChess.js started"); + gamePosition = Vec3.sum(MyAvatar.position, + Vec3.multiplyQbyV(MyAvatar.orientation, + { x: 0, y: 0, z: -1 })); + // Setup board + ChessGame.board = new ChessGame.Board(gamePosition, gameSize); + ChessGame.board.spawn(); } ChessGame.update = function() { - ChessGame.board.entity = Entities.identifyEntity(ChessGame.board.entity); + ChessGame.board.entity = Entities.identifyEntity(ChessGame.board.entity); - if (ChessGame.board.entity.isKnownID && ChessGame.pieces.length == 0) { - // Setup white pieces - var isWhite = true; - var row = 1; - // King - ChessGame.makePiece(ChessGame.KING, row, 5, isWhite); - // Queen - ChessGame.makePiece(ChessGame.QUEEN, row, 4, isWhite); - // Bishop - ChessGame.makePiece(ChessGame.BISHOP, row, 3, isWhite); - ChessGame.makePiece(ChessGame.BISHOP, row, 6, isWhite); - // Knight - ChessGame.makePiece(ChessGame.KNIGHT, row, 2, isWhite); - ChessGame.makePiece(ChessGame.KNIGHT, row, 7, isWhite); - // Rook - ChessGame.makePiece(ChessGame.ROOK, row, 1, isWhite); - ChessGame.makePiece(ChessGame.ROOK, row, 8, isWhite); - for(var j = 1; j <= 8; j++) { - ChessGame.makePiece(ChessGame.PAWN, row + 1, j, isWhite); + if (ChessGame.board.entity.isKnownID && ChessGame.pieces.length == 0) { + // Setup white pieces + var isWhite = true; + var row = 1; + // King + ChessGame.makePiece(ChessGame.KING, row, 5, isWhite); + // Queen + ChessGame.makePiece(ChessGame.QUEEN, row, 4, isWhite); + // Bishop + ChessGame.makePiece(ChessGame.BISHOP, row, 3, isWhite); + ChessGame.makePiece(ChessGame.BISHOP, row, 6, isWhite); + // Knight + ChessGame.makePiece(ChessGame.KNIGHT, row, 2, isWhite); + ChessGame.makePiece(ChessGame.KNIGHT, row, 7, isWhite); + // Rook + ChessGame.makePiece(ChessGame.ROOK, row, 1, isWhite); + ChessGame.makePiece(ChessGame.ROOK, row, 8, isWhite); + for(var j = 1; j <= 8; j++) { + ChessGame.makePiece(ChessGame.PAWN, row + 1, j, isWhite); + } + + // Setup black pieces + isWhite = false; + row = 8; + // King + ChessGame.makePiece(ChessGame.KING, row, 5, isWhite); + // Queen + ChessGame.makePiece(ChessGame.QUEEN, row, 4, isWhite); + // Bishop + ChessGame.makePiece(ChessGame.BISHOP, row, 3, isWhite); + ChessGame.makePiece(ChessGame.BISHOP, row, 6, isWhite); + // Knight + ChessGame.makePiece(ChessGame.KNIGHT, row, 2, isWhite); + ChessGame.makePiece(ChessGame.KNIGHT, row, 7, isWhite); + // Rook + ChessGame.makePiece(ChessGame.ROOK, row, 1, isWhite); + ChessGame.makePiece(ChessGame.ROOK, row, 8, isWhite); + for(var j = 1; j <= 8; j++) { + ChessGame.makePiece(ChessGame.PAWN, row - 1, j, isWhite); + } } - // Setup black pieces - isWhite = false; - row = 8; - // King - ChessGame.makePiece(ChessGame.KING, row, 5, isWhite); - // Queen - ChessGame.makePiece(ChessGame.QUEEN, row, 4, isWhite); - // Bishop - ChessGame.makePiece(ChessGame.BISHOP, row, 3, isWhite); - ChessGame.makePiece(ChessGame.BISHOP, row, 6, isWhite); - // Knight - ChessGame.makePiece(ChessGame.KNIGHT, row, 2, isWhite); - ChessGame.makePiece(ChessGame.KNIGHT, row, 7, isWhite); - // Rook - ChessGame.makePiece(ChessGame.ROOK, row, 1, isWhite); - ChessGame.makePiece(ChessGame.ROOK, row, 8, isWhite); - for(var j = 1; j <= 8; j++) { - ChessGame.makePiece(ChessGame.PAWN, row - 1, j, isWhite); - } - } - - if (ChessGame.pieces.length > 0) { - var unknown = 0; - ChessGame.board.userDataObject.pieces = new Array(); - for(var i = 0; i < ChessGame.pieces.length; i++) { - ChessGame.pieces[i].entity = Entities.identifyEntity(ChessGame.pieces[i].entity); - if (ChessGame.pieces[i].entity.isKnownID) { - ChessGame.board.userDataObject.pieces.push(ChessGame.pieces[i].entity) - } else { - unknown++; - } - } - ChessGame.board.updateUserData(); + if (ChessGame.pieces.length > 0) { + var unknown = 0; + ChessGame.board.userDataObject.pieces = new Array(); + for(var i = 0; i < ChessGame.pieces.length; i++) { + ChessGame.pieces[i].entity = Entities.identifyEntity(ChessGame.pieces[i].entity); + if (ChessGame.pieces[i].entity.isKnownID) { + ChessGame.board.userDataObject.pieces.push(ChessGame.pieces[i].entity) + } else { + unknown++; + } + } + ChessGame.board.updateUserData(); - if (unknown === 0) { - print("Board complete"); - Script.update.disconnect(ChessGame.update); + if (unknown === 0) { + print("Board complete"); + Script.update.disconnect(ChessGame.update); + } } - } } ChessGame.scriptEnding = function() { - // Cleaning up board - ChessGame.board.cleanup(); + // Cleaning up board + ChessGame.board.cleanup(); - // Cleaning up pieces - for(var i in ChessGame.pieces) { - ChessGame.pieces[i].cleanup(); - } + // Cleaning up pieces + for(var i in ChessGame.pieces) { + ChessGame.pieces[i].cleanup(); + } - print("playChess.js finished"); + print("playChess.js finished"); } Script.scriptEnding.connect(ChessGame.scriptEnding); From 3f18741b158ec3bcaf75d97b518ce9be65a5f680 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Nov 2014 16:40:56 -0800 Subject: [PATCH 59/94] add new text entity tool to newEditEntities.js --- examples/editModels.js | 9 +++------ examples/newEditEntities.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/examples/editModels.js b/examples/editModels.js index 0fc5d4a7f9..69976e03a1 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -1213,18 +1213,15 @@ var toolBar = (function () { visible: true }); - print(toolIconUrl + "add-text.svg"); - newTextButton = toolBar.addTool({ - imageURL: toolIconUrl + "add-text.svg", + //imageURL: toolIconUrl + "add-text.svg", + imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/tools/add-text.svg", // temporarily subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, width: toolWidth, height: toolHeight, alpha: 0.9, visible: true }); - - } function toggleNewModelButton(active) { @@ -1396,7 +1393,7 @@ var toolBar = (function () { type: "Text", position: position, dimensions: { x: DEFAULT_TEXT_DIMENSION_X, y: DEFAULT_TEXT_DIMENSION_Y, z: DEFAULT_TEXT_DIMENSION_Z }, - backgroundColor: { red: 255, green: 0, blue: 0 }, + backgroundColor: { red: 0, green: 0, blue: 0 }, textColor: { red: 255, green: 255, blue: 255 }, text: "some text", lineHight: "0.1" diff --git a/examples/newEditEntities.js b/examples/newEditEntities.js index cc3c0fceda..4d6194880b 100644 --- a/examples/newEditEntities.js +++ b/examples/newEditEntities.js @@ -54,6 +54,9 @@ var wantEntityGlow = false; var SPAWN_DISTANCE = 1; var DEFAULT_DIMENSION = 0.20; +var DEFAULT_TEXT_DIMENSION_X = 1.0; +var DEFAULT_TEXT_DIMENSION_Y = 1.0; +var DEFAULT_TEXT_DIMENSION_Z = 0.01; var MENU_INSPECT_TOOL_ENABLED = "Inspect Tool"; var MENU_EASE_ON_FOCUS = "Ease Orientation on Focus"; @@ -84,6 +87,7 @@ var toolBar = (function () { newCubeButton, newSphereButton, newLightButton, + newTextButton, browseModelsButton, loadURLMenuItem, loadFileMenuItem, @@ -180,6 +184,16 @@ var toolBar = (function () { visible: true }); + newTextButton = toolBar.addTool({ + //imageURL: toolIconUrl + "add-text.svg", + imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/tools/add-text.svg", // temporarily + subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + width: toolWidth, + height: toolHeight, + alpha: 0.9, + visible: true + }); + } function toggleNewModelButton(active) { @@ -378,6 +392,24 @@ var toolBar = (function () { return true; } + if (newTextButton === toolBar.clicked(clickedOverlay)) { + var position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), SPAWN_DISTANCE)); + + if (position.x > 0 && position.y > 0 && position.z > 0) { + Entities.addEntity({ + type: "Text", + position: position, + dimensions: { x: DEFAULT_TEXT_DIMENSION_X, y: DEFAULT_TEXT_DIMENSION_Y, z: DEFAULT_TEXT_DIMENSION_Z }, + backgroundColor: { red: 0, green: 0, blue: 0 }, + textColor: { red: 255, green: 255, blue: 255 }, + text: "some text", + lineHight: "0.1" + }); + } else { + print("Can't create box: Text would be out of bounds."); + } + return true; + } return false; From 0cb95fc82aa02da34dbc190726fd68a15740bda2 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Nov 2014 17:20:05 -0800 Subject: [PATCH 60/94] add support for text properties to new html propety tools --- examples/html/entityProperties.html | 73 ++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index 408e83198f..571eb030a1 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -135,6 +135,16 @@ var elModelAnimationPlaying = document.getElementById("property-model-animation-playing"); var elModelAnimationFPS = document.getElementById("property-model-animation-fps"); + var elTextSection = document.getElementById("text-section"); + var elTextText = document.getElementById("property-text-text"); + var elTextLineHeight = document.getElementById("property-text-line-height"); + var elTextTextColorRed = document.getElementById("property-text-text-color-red"); + var elTextTextColorGreen = document.getElementById("property-text-text-color-green"); + var elTextTextColorBlue = document.getElementById("property-text-text-color-blue"); + var elTextBackgroundColorRed = document.getElementById("property-text-background-color-red"); + var elTextBackgroundColorGreen = document.getElementById("property-text-background-color-green"); + var elTextBackgroundColorBlue = document.getElementById("property-text-background-color-blue"); + if (window.EventBridge !== undefined) { EventBridge.scriptEventReceived.connect(function(data) { data = JSON.parse(data); @@ -201,13 +211,27 @@ elModelSection.style.display = 'none'; } else { elModelSection.style.display = 'block'; - elModelURL.value = properties.modelURL; elModelAnimationURL.value = properties.animationURL; elModelAnimationPlaying.checked = properties.animationPlaying; elModelAnimationFPS.value = properties.animationFPS; } + if (properties.type != "Text") { + elTextSection.style.display = 'none'; + } else { + elTextSection.style.display = 'block'; + + elTextText.value = properties.text; + elTextLineHeight.value = properties.lineHeight; + elTextTextColorRed.value = properties.textColor.red; + elTextTextColorGreen.value = properties.textColor.green; + elTextTextColorBlue.value = properties.textColor.blue; + elTextBackgroundColorRed.value = properties.backgroundColor.red; + elTextBackgroundColorGreen.value = properties.backgroundColor.green; + elTextBackgroundColorBlue.value = properties.backgroundColor.blue; + } + if (properties.type != "Light") { elLightSection.style.display = 'none'; } else { @@ -320,6 +344,22 @@ elModelAnimationPlaying.addEventListener('change', createEmitCheckedPropertyUpdateFunction('animationIsPlaying')); elModelAnimationFPS.addEventListener('change', createEmitNumberPropertyUpdateFunction('animationFPS')); elModelAnimationFrame.addEventListener('change', createEmitNumberPropertyUpdateFunction('animationFrameIndex')); + + elTextText.addEventListener('change', createEmitTextPropertyUpdateFunction('text')); + elTextLineHeight.addEventListener('change', createEmitNumberPropertyUpdateFunction('lineHeight')); + + var textTextColorChangeFunction = createEmitColorPropertyUpdateFunction( + 'textColor', elTextTextColorRed, elTextTextColorGreen, elTextTextColorBlue); + elTextTextColorRed.addEventListener('change', textTextColorChangeFunction); + elTextTextColorGreen.addEventListener('change', textTextColorChangeFunction); + elTextTextColorBlue.addEventListener('change', textTextColorChangeFunction); + + var textBackgroundColorChangeFunction = createEmitColorPropertyUpdateFunction( + 'backgroundColor', elTextBackgroundColorRed, elTextBackgroundColorGreen, elTextBackgroundColorBlue); + elTextBackgroundColorRed.addEventListener('change', textBackgroundColorChangeFunction); + elTextBackgroundColorGreen.addEventListener('change', textBackgroundColorChangeFunction); + elTextBackgroundColorBlue.addEventListener('change', textBackgroundColorChangeFunction); + } @@ -492,6 +532,37 @@
+
+
+ + + + +
+
+ + + + +
+
+ + + Red + Green + Blue + +
+
+ + + Red + Green + Blue + +
+
+
From b1d29cf888745c847e3332b938936464405404f7 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 14 Nov 2014 17:27:33 -0800 Subject: [PATCH 61/94] user data cleanup --- examples/entityScripts/chessPiece.js | 16 +++++----------- examples/playChess.js | 23 ++--------------------- 2 files changed, 7 insertions(+), 32 deletions(-) diff --git a/examples/entityScripts/chessPiece.js b/examples/entityScripts/chessPiece.js index ebe2df7e55..f3e2c2aef3 100644 --- a/examples/entityScripts/chessPiece.js +++ b/examples/entityScripts/chessPiece.js @@ -1,8 +1,6 @@ (function(){ this.FIRST_TILE = null; // Global position of the first tile (1a) this.TILE_SIZE = null; // Size of one tile - this.whitesDeadPieces = null; - this.blacksDeadPieces = null; this.wantDebug = false; this.active = false; @@ -59,16 +57,11 @@ if (!(this.boardUserData && this.boardUserData.firstTile && - this.boardUserData.tileSize && - this.boardUserData.whitesDeadPieces && - this.boardUserData.blacksDeadPieces && - this.boardUserData.pieces)) { + this.boardUserData.tileSize)) { print("Incomplete boardUserData " + this.boardID.id); } else { this.FIRST_TILE = this.boardUserData.firstTile; this.TILE_SIZE = this.boardUserData.tileSize; - this.whitesDeadPieces = this.boardUserData.whitesDeadPieces; - this.blacksDeadPieces = this.boardUserData.blacksDeadPieces; this.active = true; } @@ -139,9 +132,10 @@ } this.moveDeadPiece = function() { var myPos = this.getIndexPosition(this.properties.position); - - for (var i = 0; i < this.boardUserData.pieces.length; i++) { - var piece = this.boardUserData.pieces[i]; + var others = Entities.findEntities(this.properties.position, this.properties.dimensions.y); + + for (var i = 0; i < others.length; i++) { + var piece = others[i]; if (piece.id != this.entityID.id) { var properties = Entities.getEntityProperties(piece); diff --git a/examples/playChess.js b/examples/playChess.js index 1b6882ed6e..57ed24f342 100644 --- a/examples/playChess.js +++ b/examples/playChess.js @@ -79,8 +79,7 @@ ChessGame.Board = (function(position, scale) { firstTile: this.tilePosition(1, 1), tileSize: this.tileSize, whitesDeadPieces: this.tilePosition(0,0), - blacksDeadPieces: this.tilePosition(9,9), - pieces: new Array() + blacksDeadPieces: this.tilePosition(9,9) } this.entityProperties = { type: "Model", @@ -242,25 +241,7 @@ ChessGame.update = function() { for(var j = 1; j <= 8; j++) { ChessGame.makePiece(ChessGame.PAWN, row - 1, j, isWhite); } - } - - if (ChessGame.pieces.length > 0) { - var unknown = 0; - ChessGame.board.userDataObject.pieces = new Array(); - for(var i = 0; i < ChessGame.pieces.length; i++) { - ChessGame.pieces[i].entity = Entities.identifyEntity(ChessGame.pieces[i].entity); - if (ChessGame.pieces[i].entity.isKnownID) { - ChessGame.board.userDataObject.pieces.push(ChessGame.pieces[i].entity) - } else { - unknown++; - } - } - ChessGame.board.updateUserData(); - - if (unknown === 0) { - print("Board complete"); - Script.update.disconnect(ChessGame.update); - } + Script.update.disconnect(ChessGame.update); } } From 4d7c5f2d4f2aca58f66e29576a5ebe6df5e20cc0 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 14 Nov 2014 17:35:20 -0800 Subject: [PATCH 62/94] Protect board from pieces --- examples/entityScripts/chessPiece.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/entityScripts/chessPiece.js b/examples/entityScripts/chessPiece.js index f3e2c2aef3..4d3fc5cc3d 100644 --- a/examples/entityScripts/chessPiece.js +++ b/examples/entityScripts/chessPiece.js @@ -147,9 +147,9 @@ (properties.modelURL.search("Knight") !== -1) ? 1 : (properties.modelURL.search("Bishop") !== -1) ? 0 : (properties.modelURL.search("Pawn") !== -1) ? -1 : -2; - + var piecePos = this.getIndexPosition(properties.position); - if (myPos.i === piecePos.i && myPos.j === piecePos.j) { + if (myPos.i === piecePos.i && myPos.j === piecePos.j && type !== -2) { var position = this.getAbsolutePosition((isWhite) ? { i: type, j: -1 } : { i: 7 - type, j: 8 }, properties.dimensions.y / 2.0); Entities.editEntity(piece, { From 55ac9c8ef7cf82fce8b63ff1a79fd3c0fd908560 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Nov 2014 21:16:50 -0800 Subject: [PATCH 63/94] make sure properties include type for proper encoding --- libraries/entities/src/EntityScriptingInterface.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 1658764c71..29c4a8b19a 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -93,7 +93,6 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(EntityItemID EntityItemID EntityScriptingInterface::editEntity(EntityItemID entityID, const EntityItemProperties& properties) { EntityItemID actualID = entityID; - // if the entity is unknown, attempt to look it up if (!entityID.isKnownID) { actualID = EntityItemID::getIDfromCreatorTokenID(entityID.creatorTokenID); @@ -113,6 +112,18 @@ EntityItemID EntityScriptingInterface::editEntity(EntityItemID entityID, const E // if at this point, we know the id, send the update to the entity server if (entityID.isKnownID) { + // make sure the properties has a type, so that the encode can know which properties to include + if (properties.getType() == EntityTypes::Unknown) { + EntityItem* entity = _entityTree->findEntityByEntityItemID(entityID); + if (entity) { + EntityItemProperties tempProperties = properties; + tempProperties.setType(entity->getType()); + queueEntityMessage(PacketTypeEntityAddOrEdit, entityID, tempProperties); + return entityID; + } + } + + // if the properties already includes the type, then use it as is queueEntityMessage(PacketTypeEntityAddOrEdit, entityID, properties); } From a37275e6b16e303c60f72c0d3b92c1f6aae4433d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Nov 2014 21:17:13 -0800 Subject: [PATCH 64/94] fix animation frame --- examples/html/entityProperties.html | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index 571eb030a1..695879b678 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -134,6 +134,7 @@ var elModelAnimationURL = document.getElementById("property-model-animation-url"); var elModelAnimationPlaying = document.getElementById("property-model-animation-playing"); var elModelAnimationFPS = document.getElementById("property-model-animation-fps"); + var elModelAnimationFrame = document.getElementById("property-model-animation-frame"); var elTextSection = document.getElementById("text-section"); var elTextText = document.getElementById("property-text-text"); @@ -344,7 +345,7 @@ elModelAnimationPlaying.addEventListener('change', createEmitCheckedPropertyUpdateFunction('animationIsPlaying')); elModelAnimationFPS.addEventListener('change', createEmitNumberPropertyUpdateFunction('animationFPS')); elModelAnimationFrame.addEventListener('change', createEmitNumberPropertyUpdateFunction('animationFrameIndex')); - + elTextText.addEventListener('change', createEmitTextPropertyUpdateFunction('text')); elTextLineHeight.addEventListener('change', createEmitNumberPropertyUpdateFunction('lineHeight')); @@ -530,6 +531,12 @@
+
+ + + + +
From 66f519d61386d89a8c94bd0d4c9a51fbb206475f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Nov 2014 22:15:19 -0800 Subject: [PATCH 65/94] dry up EntityItemProperties with macros --- .../entities/src/EntityItemProperties.cpp | 131 +++------ libraries/entities/src/EntityItemProperties.h | 273 ++++-------------- .../entities/src/EntityItemPropertiesMacros.h | 36 ++- 3 files changed, 124 insertions(+), 316 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index d173558711..11c9646cbc 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -24,96 +24,57 @@ EntityItemProperties::EntityItemProperties() : - _id(UNKNOWN_ENTITY_ID), - _idSet(false), - _lastEdited(0), // ???? - _created(UNKNOWN_CREATED_TIME), - _type(EntityTypes::Unknown), - - _position(0), - _dimensions(EntityItem::DEFAULT_DIMENSIONS), - _rotation(EntityItem::DEFAULT_ROTATION), - _mass(EntityItem::DEFAULT_MASS), - _velocity(EntityItem::DEFAULT_VELOCITY), - _gravity(EntityItem::DEFAULT_GRAVITY), - _damping(EntityItem::DEFAULT_DAMPING), - _lifetime(EntityItem::DEFAULT_LIFETIME), - _userData(EntityItem::DEFAULT_USER_DATA), - _script(EntityItem::DEFAULT_SCRIPT), - _registrationPoint(EntityItem::DEFAULT_REGISTRATION_POINT), - _angularVelocity(EntityItem::DEFAULT_ANGULAR_VELOCITY), - _angularDamping(EntityItem::DEFAULT_ANGULAR_DAMPING), - _visible(EntityItem::DEFAULT_VISIBLE), - _ignoreForCollisions(EntityItem::DEFAULT_IGNORE_FOR_COLLISIONS), - _collisionsWillMove(EntityItem::DEFAULT_COLLISIONS_WILL_MOVE), - - _positionChanged(false), - _dimensionsChanged(false), - _rotationChanged(false), - _massChanged(false), - _velocityChanged(false), - _gravityChanged(false), - _dampingChanged(false), - _lifetimeChanged(false), - _userDataChanged(false), - _scriptChanged(false), - _registrationPointChanged(false), - _angularVelocityChanged(false), - _angularDampingChanged(false), - _visibleChanged(false), - _ignoreForCollisionsChanged(false), - _collisionsWillMoveChanged(false), - - _color(), - _modelURL(""), - _animationURL(""), - _animationIsPlaying(ModelEntityItem::DEFAULT_ANIMATION_IS_PLAYING), - _animationFrameIndex(ModelEntityItem::DEFAULT_ANIMATION_FRAME_INDEX), - _animationFPS(ModelEntityItem::DEFAULT_ANIMATION_FPS), - _animationSettings(""), - _glowLevel(0.0f), - _localRenderAlpha(1.0f), - _isSpotlight(false), - - _colorChanged(false), - _modelURLChanged(false), - _animationURLChanged(false), - _animationIsPlayingChanged(false), - _animationFrameIndexChanged(false), - _animationFPSChanged(false), - _animationSettingsChanged(false), - - _glowLevelChanged(false), - _localRenderAlphaChanged(false), - _isSpotlightChanged(false), - - _diffuseColor(), - _ambientColor(), - _specularColor(), - _constantAttenuation(1.0f), - _linearAttenuation(0.0f), - _quadraticAttenuation(0.0f), - _exponent(0.0f), - _cutoff(PI), - _locked(false), - _textures(""), - - _diffuseColorChanged(false), - _ambientColorChanged(false), - _specularColorChanged(false), - _constantAttenuationChanged(false), - _linearAttenuationChanged(false), - _quadraticAttenuationChanged(false), - _exponentChanged(false), - _cutoffChanged(false), - _lockedChanged(false), - _texturesChanged(false), - + CONSTRUCT_PROPERTY(visible, EntityItem::DEFAULT_VISIBLE), + CONSTRUCT_PROPERTY(position, 0), + CONSTRUCT_PROPERTY(dimensions, EntityItem::DEFAULT_DIMENSIONS), + CONSTRUCT_PROPERTY(rotation, EntityItem::DEFAULT_ROTATION), + CONSTRUCT_PROPERTY(mass, EntityItem::DEFAULT_MASS), + CONSTRUCT_PROPERTY(velocity, EntityItem::DEFAULT_VELOCITY), + CONSTRUCT_PROPERTY(gravity, EntityItem::DEFAULT_GRAVITY), + CONSTRUCT_PROPERTY(damping, EntityItem::DEFAULT_DAMPING), + CONSTRUCT_PROPERTY(lifetime, EntityItem::DEFAULT_LIFETIME), + CONSTRUCT_PROPERTY(script, EntityItem::DEFAULT_SCRIPT), + CONSTRUCT_PROPERTY(color, ), + CONSTRUCT_PROPERTY(modelURL, ""), + CONSTRUCT_PROPERTY(animationURL, ""), + CONSTRUCT_PROPERTY(animationFPS, ModelEntityItem::DEFAULT_ANIMATION_FPS), + CONSTRUCT_PROPERTY(animationFrameIndex, ModelEntityItem::DEFAULT_ANIMATION_FRAME_INDEX), + CONSTRUCT_PROPERTY(animationIsPlaying, ModelEntityItem::DEFAULT_ANIMATION_IS_PLAYING), + CONSTRUCT_PROPERTY(registrationPoint, EntityItem::DEFAULT_REGISTRATION_POINT), + CONSTRUCT_PROPERTY(angularVelocity, EntityItem::DEFAULT_ANGULAR_VELOCITY), + CONSTRUCT_PROPERTY(angularDamping, EntityItem::DEFAULT_ANGULAR_DAMPING), + CONSTRUCT_PROPERTY(ignoreForCollisions, EntityItem::DEFAULT_IGNORE_FOR_COLLISIONS), + CONSTRUCT_PROPERTY(collisionsWillMove, EntityItem::DEFAULT_COLLISIONS_WILL_MOVE), + CONSTRUCT_PROPERTY(isSpotlight, false), + CONSTRUCT_PROPERTY(diffuseColor, ), + CONSTRUCT_PROPERTY(ambientColor, ), + CONSTRUCT_PROPERTY(specularColor, ), + CONSTRUCT_PROPERTY(constantAttenuation, 1.0f), + CONSTRUCT_PROPERTY(linearAttenuation, 0.0f), + CONSTRUCT_PROPERTY(quadraticAttenuation, 0.0f), + CONSTRUCT_PROPERTY(exponent, 0.0f), + CONSTRUCT_PROPERTY(cutoff, PI), + CONSTRUCT_PROPERTY(locked, false), + CONSTRUCT_PROPERTY(textures, ""), + CONSTRUCT_PROPERTY(animationSettings, ""), + CONSTRUCT_PROPERTY(userData, EntityItem::DEFAULT_USER_DATA), CONSTRUCT_PROPERTY(text, TextEntityItem::DEFAULT_TEXT), CONSTRUCT_PROPERTY(lineHeight, TextEntityItem::DEFAULT_LINE_HEIGHT), CONSTRUCT_PROPERTY(textColor, TextEntityItem::DEFAULT_TEXT_COLOR), CONSTRUCT_PROPERTY(backgroundColor, TextEntityItem::DEFAULT_BACKGROUND_COLOR), + _id(UNKNOWN_ENTITY_ID), + _idSet(false), + _lastEdited(0), + _created(UNKNOWN_CREATED_TIME), + _type(EntityTypes::Unknown), + + _glowLevel(0.0f), + _localRenderAlpha(1.0f), + + _glowLevelChanged(false), + _localRenderAlphaChanged(false), + _defaultSettings(true), _naturalDimensions(1.0f, 1.0f, 1.0f) { diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 10cb18e244..642e24beec 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -114,6 +114,9 @@ public: EntityItemProperties(); virtual ~EntityItemProperties(); + EntityTypes::EntityType getType() const { return _type; } + void setType(EntityTypes::EntityType type) { _type = type; } + virtual QScriptValue copyToScriptValue(QScriptEngine* engine) const; virtual void copyFromScriptValue(const QScriptValue& object); @@ -131,86 +134,63 @@ public: AABox getAABoxInMeters() const; void debugDump() const; + void setLastEdited(quint64 usecTime) { _lastEdited = usecTime; } + DEFINE_PROPERTY(PROP_VISIBLE, Visible, visible, bool); + DEFINE_PROPERTY_REF_WITH_SETTER(PROP_POSITION, Position, position, glm::vec3); + DEFINE_PROPERTY_REF(PROP_DIMENSIONS, Dimensions, dimensions, glm::vec3); + DEFINE_PROPERTY_REF(PROP_ROTATION, Rotation, rotation, glm::quat); + DEFINE_PROPERTY(PROP_MASS, Mass, mass, float); + DEFINE_PROPERTY_REF(PROP_VELOCITY, Velocity, velocity, glm::vec3); + DEFINE_PROPERTY_REF(PROP_GRAVITY, Gravity, gravity, glm::vec3); + DEFINE_PROPERTY(PROP_DAMPING, Damping, damping, float); + DEFINE_PROPERTY(PROP_LIFETIME, Lifetime, lifetime, float); + DEFINE_PROPERTY_REF(PROP_SCRIPT, Script, script, QString); + DEFINE_PROPERTY_REF(PROP_COLOR, Color, color, xColor); + DEFINE_PROPERTY_REF(PROP_MODEL_URL, ModelURL, modelURL, QString); + DEFINE_PROPERTY_REF(PROP_ANIMATION_URL, AnimationURL, animationURL, QString); + DEFINE_PROPERTY(PROP_ANIMATION_FPS, AnimationFPS, animationFPS, float); + DEFINE_PROPERTY(PROP_ANIMATION_FRAME_INDEX, AnimationFrameIndex, animationFrameIndex, float); + DEFINE_PROPERTY(PROP_ANIMATION_PLAYING, AnimationIsPlaying, animationIsPlaying, bool); + DEFINE_PROPERTY_REF(PROP_REGISTRATION_POINT, RegistrationPoint, registrationPoint, glm::vec3); + DEFINE_PROPERTY_REF(PROP_ANGULAR_VELOCITY, AngularVelocity, angularVelocity, glm::vec3); + DEFINE_PROPERTY(PROP_ANGULAR_DAMPING, AngularDamping, angularDamping, float); + DEFINE_PROPERTY(PROP_IGNORE_FOR_COLLISIONS, IgnoreForCollisions, ignoreForCollisions, bool); + DEFINE_PROPERTY(PROP_COLLISIONS_WILL_MOVE, CollisionsWillMove, collisionsWillMove, bool); + DEFINE_PROPERTY(PROP_IS_SPOTLIGHT, IsSpotlight, isSpotlight, bool); + DEFINE_PROPERTY_REF(PROP_DIFFUSE_COLOR, DiffuseColor, diffuseColor, xColor); + DEFINE_PROPERTY_REF(PROP_AMBIENT_COLOR, AmbientColor, ambientColor, xColor); + DEFINE_PROPERTY_REF(PROP_SPECULAR_COLOR, SpecularColor, specularColor, xColor); + DEFINE_PROPERTY(PROP_CONSTANT_ATTENUATION, ConstantAttenuation, constantAttenuation, float); + DEFINE_PROPERTY(PROP_LINEAR_ATTENUATION, LinearAttenuation, linearAttenuation, float); + DEFINE_PROPERTY(PROP_QUADRATIC_ATTENUATION, QuadraticAttenuation, quadraticAttenuation, float); + DEFINE_PROPERTY(PROP_EXPONENT, Exponent, exponent, float); + DEFINE_PROPERTY(PROP_CUTOFF, Cutoff, cutoff, float); + DEFINE_PROPERTY(PROP_LOCKED, Locked, locked, bool); + DEFINE_PROPERTY_REF(PROP_TEXTURES, Textures, textures, QString); + DEFINE_PROPERTY_REF_WITH_SETTER_AND_GETTER(PROP_ANIMATION_SETTINGS, AnimationSettings, animationSettings, QString); + DEFINE_PROPERTY_REF(PROP_USER_DATA, UserData, userData, QString); + DEFINE_PROPERTY_REF(PROP_TEXT, Text, text, QString); + DEFINE_PROPERTY(PROP_LINE_HEIGHT, LineHeight, lineHeight, float); + DEFINE_PROPERTY_REF(PROP_TEXT_COLOR, TextColor, textColor, xColor); + DEFINE_PROPERTY_REF(PROP_BACKGROUND_COLOR, BackgroundColor, backgroundColor, xColor); - // properties of all entities - EntityTypes::EntityType getType() const { return _type; } - - void setType(EntityTypes::EntityType type) { _type = type; } - - const glm::vec3& getPosition() const { return _position; } - /// set position in meter units, will be clamped to domain bounds - void setPosition(const glm::vec3& value) { _position = glm::clamp(value, 0.0f, (float)TREE_SCALE); _positionChanged = true; } - - - const glm::vec3& getDimensions() const { return _dimensions; } - void setDimensions(const glm::vec3& value) { _dimensions = value; _dimensionsChanged = true; } +public: float getMaxDimension() const { return glm::max(_dimensions.x, _dimensions.y, _dimensions.z); } - const glm::quat& getRotation() const { return _rotation; } - void setRotation(const glm::quat& rotation) { _rotation = rotation; _rotationChanged = true; } - - float getMass() const { return _mass; } - void setMass(float value) { _mass = value; _massChanged = true; } - - /// velocity in meters (0.0-1.0) per second - const glm::vec3& getVelocity() const { return _velocity; } - /// velocity in meters (0.0-1.0) per second - void setVelocity(const glm::vec3& value) { _velocity = value; _velocityChanged = true; } - - /// gravity in meters (0.0-TREE_SCALE) per second squared - const glm::vec3& getGravity() const { return _gravity; } - /// gravity in meters (0.0-TREE_SCALE) 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; } - - float getLifetime() const { return _lifetime; } /// get the lifetime in seconds for the entity - void setLifetime(float value) { _lifetime = value; _lifetimeChanged = true; } /// set the lifetime in seconds for the entity - - const QString& getUserData() const { return _userData; } - void setUserData(const QString& value) { _userData = value; _userDataChanged = true; } - float getAge() const { return (float)(usecTimestampNow() - _created) / (float)USECS_PER_SECOND; } quint64 getCreated() const { return _created; } void setCreated(quint64 usecTime) { _created = usecTime; } bool hasCreatedTime() const { return (_created != UNKNOWN_CREATED_TIME); } - - // NOTE: how do we handle _defaultSettings??? bool containsBoundsProperties() const { return (_positionChanged || _dimensionsChanged); } bool containsPositionChange() const { return _positionChanged; } bool containsDimensionsChange() const { return _dimensionsChanged; } - // TODO: this need to be more generic. for now, we're going to have the properties class support these as - // named getter/setters, but we want to move them to generic types... - // properties we want to move to just models and particles - xColor getColor() const { return _color; } - const QString& getModelURL() const { return _modelURL; } - const QString& getAnimationURL() const { return _animationURL; } - float getAnimationFrameIndex() const { return _animationFrameIndex; } - bool getAnimationIsPlaying() const { return _animationIsPlaying; } - float getAnimationFPS() const { return _animationFPS; } - QString getAnimationSettings() const; - float getGlowLevel() const { return _glowLevel; } float getLocalRenderAlpha() const { return _localRenderAlpha; } - const QString& getScript() const { return _script; } - - // model related properties - void setColor(const xColor& value) { _color = value; _colorChanged = true; } - void setModelURL(const QString& url) { _modelURL = url; _modelURLChanged = true; } - void setAnimationURL(const QString& url) { _animationURL = url; _animationURLChanged = true; } - void setAnimationFrameIndex(float value) { _animationFrameIndex = value; _animationFrameIndexChanged = true; } - void setAnimationIsPlaying(bool value) { _animationIsPlaying = value; _animationIsPlayingChanged = true; } - void setAnimationFPS(float value) { _animationFPS = value; _animationFPSChanged = true; } - void setAnimationSettings(const QString& value); - void setGlowLevel(float value) { _glowLevel = value; _glowLevelChanged = true; } void setLocalRenderAlpha(float value) { _localRenderAlpha = value; _localRenderAlphaChanged = true; } - void setScript(const QString& value) { _script = value; _scriptChanged = true; } - static bool encodeEntityEditPacket(PacketType command, EntityItemID id, const EntityItemProperties& properties, unsigned char* bufferOut, int sizeIn, int& sizeOut); @@ -222,23 +202,6 @@ public: static bool decodeEntityEditPacket(const unsigned char* data, int bytesToRead, int& processedBytes, EntityItemID& entityID, EntityItemProperties& properties); - bool positionChanged() const { return _positionChanged; } - bool rotationChanged() const { return _rotationChanged; } - bool massChanged() const { return _massChanged; } - bool velocityChanged() const { return _velocityChanged; } - bool gravityChanged() const { return _gravityChanged; } - bool dampingChanged() const { return _dampingChanged; } - bool lifetimeChanged() const { return _lifetimeChanged; } - bool userDataChanged() const { return _userDataChanged; } - bool scriptChanged() const { return _scriptChanged; } - bool dimensionsChanged() const { return _dimensionsChanged; } - bool registrationPointChanged() const { return _registrationPointChanged; } - bool colorChanged() const { return _colorChanged; } - bool modelURLChanged() const { return _modelURLChanged; } - bool animationURLChanged() const { return _animationURLChanged; } - bool animationIsPlayingChanged() const { return _animationIsPlayingChanged; } - bool animationFrameIndexChanged() const { return _animationFrameIndexChanged; } - bool animationFPSChanged() const { return _animationFPSChanged; } bool glowLevelChanged() const { return _glowLevelChanged; } bool localRenderAlphaChanged() const { return _localRenderAlphaChanged; } @@ -246,167 +209,26 @@ public: void markAllChanged(); void setSittingPoints(const QVector& sittingPoints); - + const glm::vec3& getNaturalDimensions() const { return _naturalDimensions; } void setNaturalDimensions(const glm::vec3& value) { _naturalDimensions = value; } - const glm::vec3& getRegistrationPoint() const { return _registrationPoint; } - void setRegistrationPoint(const glm::vec3& value) { _registrationPoint = value; _registrationPointChanged = true; } - - const glm::vec3& getAngularVelocity() const { return _angularVelocity; } - void setAngularVelocity(const glm::vec3& value) { _angularVelocity = value; _angularVelocityChanged = true; } - - float getAngularDamping() const { return _angularDamping; } - void setAngularDamping(float value) { _angularDamping = value; _angularDampingChanged = true; } - - bool getVisible() const { return _visible; } - void setVisible(bool value) { _visible = value; _visibleChanged = true; } - - bool getIgnoreForCollisions() const { return _ignoreForCollisions; } - void setIgnoreForCollisions(bool value) { _ignoreForCollisions = value; _ignoreForCollisionsChanged = true; } - - bool getCollisionsWillMove() const { return _collisionsWillMove; } - void setCollisionsWillMove(bool value) { _collisionsWillMove = value; _collisionsWillMoveChanged = true; } - - bool getIsSpotlight() const { return _isSpotlight; } - void setIsSpotlight(bool value) { _isSpotlight = value; _isSpotlightChanged = true; } - - xColor getDiffuseColor() const { return _diffuseColor; } - xColor getAmbientColor() const { return _ambientColor; } - xColor getSpecularColor() const { return _specularColor; } - - void setDiffuseColor(const xColor& value) { _diffuseColor = value; _diffuseColorChanged = true; } - void setAmbientColor(const xColor& value) { _ambientColor = value; _ambientColorChanged = true; } - void setSpecularColor(const xColor& value) { _specularColor = value; _specularColorChanged = true; } - - bool diffuseColorChanged() const { return _colorChanged; } - bool ambientColorChanged() const { return _ambientColorChanged; } - bool specularColorChanged() const { return _specularColorChanged; } - - float getConstantAttenuation() const { return _constantAttenuation; } - void setConstantAttenuation(float value) { _constantAttenuation = value; _constantAttenuationChanged = true; } - - float getLinearAttenuation() const { return _linearAttenuation; } - void setLinearAttenuation(float value) { _linearAttenuation = value; _linearAttenuationChanged = true; } - - float getQuadraticAttenuation() const { return _quadraticAttenuation; } - void setQuadraticAttenuation(float value) { _quadraticAttenuation = value; _quadraticAttenuationChanged = true; } - - float getExponent() const { return _exponent; } - void setExponent(float value) { _exponent = value; _exponentChanged = true; } - - float getCutoff() const { return _cutoff; } - void setCutoff(float value) { _cutoff = value; _cutoffChanged = true; } - - bool getLocked() const { return _locked; } - void setLocked(bool value) { _locked = value; _lockedChanged = true; } - bool lockedChanged() const { return _lockedChanged; } - - const QString& getTextures() const { return _textures; } - void setTextures(const QString& value) { _textures = value; _texturesChanged = true; } - const QStringList& getTextureNames() const { return _textureNames; } void setTextureNames(const QStringList& value) { _textureNames = value; } - - void setLastEdited(quint64 usecTime) { _lastEdited = usecTime; } + private: - QUuid _id; bool _idSet; quint64 _lastEdited; quint64 _created; - EntityTypes::EntityType _type; - void setType(const QString& typeName) { _type = EntityTypes::getEntityTypeFromName(typeName); } - - glm::vec3 _position; - glm::vec3 _dimensions; - glm::quat _rotation; - float _mass; - glm::vec3 _velocity; - glm::vec3 _gravity; - float _damping; - float _lifetime; - QString _userData; - QString _script; - glm::vec3 _registrationPoint; - glm::vec3 _angularVelocity; - float _angularDamping; - bool _visible; - bool _ignoreForCollisions; - bool _collisionsWillMove; - bool _positionChanged; - bool _dimensionsChanged; - bool _rotationChanged; - bool _massChanged; - bool _velocityChanged; - bool _gravityChanged; - bool _dampingChanged; - bool _lifetimeChanged; - bool _userDataChanged; - bool _scriptChanged; - bool _registrationPointChanged; - bool _angularVelocityChanged; - bool _angularDampingChanged; - bool _visibleChanged; - bool _ignoreForCollisionsChanged; - bool _collisionsWillMoveChanged; - - // TODO: this need to be more generic. for now, we're going to have the properties class support these as - // named getter/setters, but we want to move them to generic types... - xColor _color; - QString _modelURL; - QString _animationURL; - bool _animationIsPlaying; - float _animationFrameIndex; - float _animationFPS; - QString _animationSettings; float _glowLevel; float _localRenderAlpha; - bool _isSpotlight; - - bool _colorChanged; - bool _modelURLChanged; - bool _animationURLChanged; - bool _animationIsPlayingChanged; - bool _animationFrameIndexChanged; - bool _animationFPSChanged; - bool _animationSettingsChanged; bool _glowLevelChanged; bool _localRenderAlphaChanged; - bool _isSpotlightChanged; - - xColor _diffuseColor; - xColor _ambientColor; - xColor _specularColor; - float _constantAttenuation; - float _linearAttenuation; - float _quadraticAttenuation; - float _exponent; - float _cutoff; - bool _locked; - QString _textures; - - bool _diffuseColorChanged; - bool _ambientColorChanged; - bool _specularColorChanged; - bool _constantAttenuationChanged; - bool _linearAttenuationChanged; - bool _quadraticAttenuationChanged; - bool _exponentChanged; - bool _cutoffChanged; - bool _lockedChanged; - bool _texturesChanged; - - DEFINE_PROPERTY_REF(PROP_TEXT, Text, text, QString); - DEFINE_PROPERTY(PROP_LINE_HEIGHT, LineHeight, lineHeight, float); - DEFINE_PROPERTY_REF(PROP_TEXT_COLOR, TextColor, textColor, xColor); - DEFINE_PROPERTY_REF(PROP_BACKGROUND_COLOR, BackgroundColor, backgroundColor, xColor); - -private: bool _defaultSettings; // NOTE: The following are pseudo client only properties. They are only used in clients which can access @@ -420,6 +242,11 @@ QScriptValue EntityItemPropertiesToScriptValue(QScriptEngine* engine, const Enti void EntityItemPropertiesFromScriptValue(const QScriptValue &object, EntityItemProperties& properties); +// define these inline here so the macros work +inline void EntityItemProperties::setPosition(const glm::vec3& value) + { _position = glm::clamp(value, 0.0f, (float)TREE_SCALE); _positionChanged = true; } + + inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { debug << "EntityItemProperties[" << "\n" << " position:" << properties.getPosition() << "in meters" << "\n" diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index f61d89dbd2..8ad444a975 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -267,19 +267,39 @@ #define DEFINE_PROPERTY(P, N, n, T) \ public: \ - T get##N() const { return _##n; } \ - void set##N(T value) { _##n = value; _##n##Changed = true; } \ + T get##N() const { return _##n; } \ + void set##N(T value) { _##n = value; _##n##Changed = true; } \ + bool n##Changed() const { return _##n##Changed; } \ private: \ - T _##n; \ - bool _##n##Changed; + T _##n; \ + bool _##n##Changed; #define DEFINE_PROPERTY_REF(P, N, n, T) \ public: \ - const T& get##N() const { return _##n; } \ - void set##N(const T& value) { _##n = value; _##n##Changed = true; } \ + const T& get##N() const { return _##n; } \ + void set##N(const T& value) { _##n = value; _##n##Changed = true; } \ + bool n##Changed() const { return _##n##Changed; } \ private: \ - T _##n; \ - bool _##n##Changed; + T _##n; \ + bool _##n##Changed; + +#define DEFINE_PROPERTY_REF_WITH_SETTER(P, N, n, T) \ + public: \ + const T& get##N() const { return _##n; } \ + void set##N(const T& value); \ + bool n##Changed() const; \ + private: \ + T _##n; \ + bool _##n##Changed; + +#define DEFINE_PROPERTY_REF_WITH_SETTER_AND_GETTER(P, N, n, T) \ + public: \ + T get##N() const; \ + void set##N(const T& value); \ + bool n##Changed() const; \ + private: \ + T _##n; \ + bool _##n##Changed; From 60908ef0403ca42b07d167570d3987e8d43073ce Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Nov 2014 22:15:28 -0800 Subject: [PATCH 66/94] fix some warnings --- interface/src/entities/RenderableTextEntityItem.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/interface/src/entities/RenderableTextEntityItem.cpp b/interface/src/entities/RenderableTextEntityItem.cpp index 771962ecc6..f790f6fa35 100644 --- a/interface/src/entities/RenderableTextEntityItem.cpp +++ b/interface/src/entities/RenderableTextEntityItem.cpp @@ -20,8 +20,6 @@ #include "EntityTreeRenderer.h" #include "RenderableTextEntityItem.h" -const xColor DEFAULT_BACKGROUND_COLOR = { 0, 0, 0 }; -const float DEFAULT_MARGIN = 0.1f; const int FIXED_FONT_POINT_SIZE = 40; const float LINE_SCALE_RATIO = 1.2f; @@ -33,7 +31,6 @@ void RenderableTextEntityItem::render(RenderArgs* args) { PerformanceTimer perfTimer("RenderableTextEntityItem::render"); assert(getType() == EntityTypes::Text); glm::vec3 position = getPositionInMeters(); - glm::vec3 center = getCenter() * (float)TREE_SCALE; glm::vec3 dimensions = getDimensions() * (float)TREE_SCALE; glm::vec3 halfDimensions = dimensions / 2.0f; glm::quat rotation = getRotation(); From f0cd258a13e4947ec13e9c96299f3baa7068047b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Nov 2014 22:51:04 -0800 Subject: [PATCH 67/94] test --- libraries/entities/src/EntityItemProperties.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 642e24beec..5984ae9c65 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -110,6 +110,15 @@ class EntityItemProperties { friend class SphereEntityItem; // TODO: consider removing this friend relationship and use public methods friend class LightEntityItem; // TODO: consider removing this friend relationship and use public methods friend class TextEntityItem; // TODO: consider removing this friend relationship and use public methods +private: + QUuid _id; + bool _idSet; + quint64 _lastEdited; + quint64 _created; + EntityTypes::EntityType _type; + void setType(const QString& typeName) { _type = EntityTypes::getEntityTypeFromName(typeName); } + + public: EntityItemProperties(); virtual ~EntityItemProperties(); @@ -218,13 +227,6 @@ public: private: - QUuid _id; - bool _idSet; - quint64 _lastEdited; - quint64 _created; - EntityTypes::EntityType _type; - void setType(const QString& typeName) { _type = EntityTypes::getEntityTypeFromName(typeName); } - float _glowLevel; float _localRenderAlpha; bool _glowLevelChanged; From 28fc6d15f49d137f1e1f0d2afceb48b1a9e9fe23 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Nov 2014 22:53:29 -0800 Subject: [PATCH 68/94] test --- libraries/entities/src/EntityItemProperties.h | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 5984ae9c65..642e24beec 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -110,15 +110,6 @@ class EntityItemProperties { friend class SphereEntityItem; // TODO: consider removing this friend relationship and use public methods friend class LightEntityItem; // TODO: consider removing this friend relationship and use public methods friend class TextEntityItem; // TODO: consider removing this friend relationship and use public methods -private: - QUuid _id; - bool _idSet; - quint64 _lastEdited; - quint64 _created; - EntityTypes::EntityType _type; - void setType(const QString& typeName) { _type = EntityTypes::getEntityTypeFromName(typeName); } - - public: EntityItemProperties(); virtual ~EntityItemProperties(); @@ -227,6 +218,13 @@ public: private: + QUuid _id; + bool _idSet; + quint64 _lastEdited; + quint64 _created; + EntityTypes::EntityType _type; + void setType(const QString& typeName) { _type = EntityTypes::getEntityTypeFromName(typeName); } + float _glowLevel; float _localRenderAlpha; bool _glowLevelChanged; From bb15fc138c5012a7e4afb0c89e57d7df4e5b8581 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 15 Nov 2014 09:28:40 -0800 Subject: [PATCH 69/94] Fix Bandwidth Details dialog opening if click meter's pos when UI hidden --- interface/src/Application.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f890baff3d..31be016380 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1555,6 +1555,8 @@ void Application::checkBandwidthMeterClick() { // ... to be called upon button release if (Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth) && + Menu::getInstance()->isOptionChecked(MenuOption::Stats) && + Menu::getInstance()->isOptionChecked(MenuOption::UserInterface) && glm::compMax(glm::abs(glm::ivec2(_mouseX - _mouseDragStartedX, _mouseY - _mouseDragStartedY))) <= BANDWIDTH_METER_CLICK_MAX_DRAG_LENGTH && _bandwidthMeter.isWithinArea(_mouseX, _mouseY, _glWidget->width(), _glWidget->height())) { From 42e8d4d3778b260a1226ad640db12d453049effd Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 15 Nov 2014 20:24:00 -0800 Subject: [PATCH 70/94] fix warnings in overlays --- interface/src/ui/overlays/BillboardOverlay.cpp | 12 +++++++----- interface/src/ui/overlays/ImageOverlay.cpp | 11 ++++++----- interface/src/ui/overlays/ModelOverlay.cpp | 6 +++--- interface/src/ui/overlays/Overlay.cpp | 18 ++++++++++-------- 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/interface/src/ui/overlays/BillboardOverlay.cpp b/interface/src/ui/overlays/BillboardOverlay.cpp index dee5eceab7..5fbad7839a 100644 --- a/interface/src/ui/overlays/BillboardOverlay.cpp +++ b/interface/src/ui/overlays/BillboardOverlay.cpp @@ -26,12 +26,14 @@ BillboardOverlay::BillboardOverlay() : BillboardOverlay::BillboardOverlay(const BillboardOverlay* billboardOverlay) : Base3DOverlay(billboardOverlay), - _newTextureNeeded(true), - _scale(billboardOverlay->_scale), - _isFacingAvatar(billboardOverlay->_isFacingAvatar), - _fromImage(billboardOverlay->_fromImage), _url(billboardOverlay->_url), - _billboard(billboardOverlay->_billboard) + _billboard(billboardOverlay->_billboard), + _size(), + _billboardTexture(), + _newTextureNeeded(true), + _fromImage(billboardOverlay->_fromImage), + _scale(billboardOverlay->_scale), + _isFacingAvatar(billboardOverlay->_isFacingAvatar) { } diff --git a/interface/src/ui/overlays/ImageOverlay.cpp b/interface/src/ui/overlays/ImageOverlay.cpp index fad19be292..f903dfe19c 100644 --- a/interface/src/ui/overlays/ImageOverlay.cpp +++ b/interface/src/ui/overlays/ImageOverlay.cpp @@ -29,12 +29,13 @@ ImageOverlay::ImageOverlay() : ImageOverlay::ImageOverlay(const ImageOverlay* imageOverlay) : Overlay2D(imageOverlay), - _textureID(0), - _textureBound(false), - _wantClipFromImage(false), - _renderImage(imageOverlay->_renderImage), _imageURL(imageOverlay->_imageURL), - _textureImage(imageOverlay->_textureImage) + _textureImage(imageOverlay->_textureImage), + _textureID(0), + _fromImage(), + _renderImage(imageOverlay->_renderImage), + _textureBound(false), + _wantClipFromImage(false) { } diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 3594d7e828..60049e0b3b 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -26,10 +26,10 @@ ModelOverlay::ModelOverlay(const ModelOverlay* modelOverlay) : Base3DOverlay(modelOverlay), _model(), _modelTextures(QVariantMap()), - _scale(modelOverlay->_scale), - _updateModel(false), _url(modelOverlay->_url), - _rotation(modelOverlay->_rotation) + _rotation(modelOverlay->_rotation), + _scale(modelOverlay->_scale), + _updateModel(false) { _model.init(); if (_url.isValid()) { diff --git a/interface/src/ui/overlays/Overlay.cpp b/interface/src/ui/overlays/Overlay.cpp index 549152ded0..fd7aaca717 100644 --- a/interface/src/ui/overlays/Overlay.cpp +++ b/interface/src/ui/overlays/Overlay.cpp @@ -41,20 +41,22 @@ Overlay::Overlay() : Overlay::Overlay(const Overlay* overlay) : _parent(NULL), + _isLoaded(overlay->_isLoaded), _alpha(overlay->_alpha), - _lastPulseUpdate(usecTimestampNow()), - _alphaPulse(overlay->_alphaPulse), - _anchor(overlay->_anchor), - _color(overlay->_color), - _colorPulse(overlay->_colorPulse), _glowLevel(overlay->_glowLevel), - _glowLevelPulse(overlay->_glowLevelPulse), - _pulseDirection(overlay->_pulseDirection), + _pulse(overlay->_pulse), _pulseMax(overlay->_pulseMax), _pulseMin(overlay->_pulseMin), _pulsePeriod(overlay->_pulsePeriod), + _pulseDirection(overlay->_pulseDirection), + _lastPulseUpdate(usecTimestampNow()), + _glowLevelPulse(overlay->_glowLevelPulse), + _alphaPulse(overlay->_alphaPulse), + _colorPulse(overlay->_colorPulse), + _color(overlay->_color), _visible(overlay->_visible), - _isLoaded(overlay->_isLoaded) + _anchor(overlay->_anchor), + _scriptEngine(NULL) { } From 56dd90db4098bcba64eba8c1cf6aec84a8f3e152 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 15 Nov 2014 20:24:00 -0800 Subject: [PATCH 71/94] fix warnings in overlays --- interface/src/ui/overlays/BillboardOverlay.cpp | 12 +++++++----- interface/src/ui/overlays/ImageOverlay.cpp | 11 ++++++----- interface/src/ui/overlays/ModelOverlay.cpp | 6 +++--- interface/src/ui/overlays/Overlay.cpp | 18 ++++++++++-------- 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/interface/src/ui/overlays/BillboardOverlay.cpp b/interface/src/ui/overlays/BillboardOverlay.cpp index dee5eceab7..5fbad7839a 100644 --- a/interface/src/ui/overlays/BillboardOverlay.cpp +++ b/interface/src/ui/overlays/BillboardOverlay.cpp @@ -26,12 +26,14 @@ BillboardOverlay::BillboardOverlay() : BillboardOverlay::BillboardOverlay(const BillboardOverlay* billboardOverlay) : Base3DOverlay(billboardOverlay), - _newTextureNeeded(true), - _scale(billboardOverlay->_scale), - _isFacingAvatar(billboardOverlay->_isFacingAvatar), - _fromImage(billboardOverlay->_fromImage), _url(billboardOverlay->_url), - _billboard(billboardOverlay->_billboard) + _billboard(billboardOverlay->_billboard), + _size(), + _billboardTexture(), + _newTextureNeeded(true), + _fromImage(billboardOverlay->_fromImage), + _scale(billboardOverlay->_scale), + _isFacingAvatar(billboardOverlay->_isFacingAvatar) { } diff --git a/interface/src/ui/overlays/ImageOverlay.cpp b/interface/src/ui/overlays/ImageOverlay.cpp index fad19be292..f903dfe19c 100644 --- a/interface/src/ui/overlays/ImageOverlay.cpp +++ b/interface/src/ui/overlays/ImageOverlay.cpp @@ -29,12 +29,13 @@ ImageOverlay::ImageOverlay() : ImageOverlay::ImageOverlay(const ImageOverlay* imageOverlay) : Overlay2D(imageOverlay), - _textureID(0), - _textureBound(false), - _wantClipFromImage(false), - _renderImage(imageOverlay->_renderImage), _imageURL(imageOverlay->_imageURL), - _textureImage(imageOverlay->_textureImage) + _textureImage(imageOverlay->_textureImage), + _textureID(0), + _fromImage(), + _renderImage(imageOverlay->_renderImage), + _textureBound(false), + _wantClipFromImage(false) { } diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 3594d7e828..60049e0b3b 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -26,10 +26,10 @@ ModelOverlay::ModelOverlay(const ModelOverlay* modelOverlay) : Base3DOverlay(modelOverlay), _model(), _modelTextures(QVariantMap()), - _scale(modelOverlay->_scale), - _updateModel(false), _url(modelOverlay->_url), - _rotation(modelOverlay->_rotation) + _rotation(modelOverlay->_rotation), + _scale(modelOverlay->_scale), + _updateModel(false) { _model.init(); if (_url.isValid()) { diff --git a/interface/src/ui/overlays/Overlay.cpp b/interface/src/ui/overlays/Overlay.cpp index 549152ded0..fd7aaca717 100644 --- a/interface/src/ui/overlays/Overlay.cpp +++ b/interface/src/ui/overlays/Overlay.cpp @@ -41,20 +41,22 @@ Overlay::Overlay() : Overlay::Overlay(const Overlay* overlay) : _parent(NULL), + _isLoaded(overlay->_isLoaded), _alpha(overlay->_alpha), - _lastPulseUpdate(usecTimestampNow()), - _alphaPulse(overlay->_alphaPulse), - _anchor(overlay->_anchor), - _color(overlay->_color), - _colorPulse(overlay->_colorPulse), _glowLevel(overlay->_glowLevel), - _glowLevelPulse(overlay->_glowLevelPulse), - _pulseDirection(overlay->_pulseDirection), + _pulse(overlay->_pulse), _pulseMax(overlay->_pulseMax), _pulseMin(overlay->_pulseMin), _pulsePeriod(overlay->_pulsePeriod), + _pulseDirection(overlay->_pulseDirection), + _lastPulseUpdate(usecTimestampNow()), + _glowLevelPulse(overlay->_glowLevelPulse), + _alphaPulse(overlay->_alphaPulse), + _colorPulse(overlay->_colorPulse), + _color(overlay->_color), _visible(overlay->_visible), - _isLoaded(overlay->_isLoaded) + _anchor(overlay->_anchor), + _scriptEngine(NULL) { } From c70a7e055348ded84b4100ddfb51601477958263 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Nov 2014 16:03:43 -0800 Subject: [PATCH 72/94] coding standard cleanup, fix warning --- interface/src/ui/overlays/Overlays.h | 3 ++- libraries/octree/src/OctreeHeadlessViewer.h | 3 ++- libraries/octree/src/OctreeRenderer.h | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 295412cdbd..2cd80041cd 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -51,7 +51,8 @@ public: ~Overlays(); void init(QGLWidget* parent); void update(float deltatime); - void render3D(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::RenderSide renderSide = RenderArgs::MONO); + void render3D(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, + RenderArgs::RenderSide renderSide = RenderArgs::MONO); void render2D(); public slots: diff --git a/libraries/octree/src/OctreeHeadlessViewer.h b/libraries/octree/src/OctreeHeadlessViewer.h index 03b8a204e0..9a6a5c7102 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.h +++ b/libraries/octree/src/OctreeHeadlessViewer.h @@ -33,7 +33,8 @@ public: virtual void renderElement(OctreeElement* element, RenderArgs* args) { /* swallow these */ } virtual void init(); - virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE) { /* swallow these */ } + virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, + RenderArgs::RenderSide renderSide = RenderArgs::MONO) { /* swallow these */ } void setJurisdictionListener(JurisdictionListener* jurisdictionListener) { _jurisdictionListener = jurisdictionListener; } diff --git a/libraries/octree/src/OctreeRenderer.h b/libraries/octree/src/OctreeRenderer.h index e8612b4cb6..2999f34fb6 100644 --- a/libraries/octree/src/OctreeRenderer.h +++ b/libraries/octree/src/OctreeRenderer.h @@ -52,7 +52,8 @@ public: virtual void init(); /// render the content of the octree - virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::RenderSide renderSide = RenderArgs::MONO); + virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, + RenderArgs::RenderSide renderSide = RenderArgs::MONO); ViewFrustum* getViewFrustum() const { return _viewFrustum; } void setViewFrustum(ViewFrustum* viewFrustum) { _viewFrustum = viewFrustum; } From 4adb4787cd18222b907a8828512a5b3a58633e06 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 15 Nov 2014 21:50:42 -0800 Subject: [PATCH 73/94] added debugging of usecTimestampNow() in octree server to better understand flight times --- assignment-client/src/octree/OctreeServer.cpp | 5 ++- assignment-client/src/octree/OctreeServer.h | 1 + .../resources/describe-settings.json | 7 ++++ libraries/octree/src/OctreePersistThread.cpp | 20 +++++++++-- libraries/octree/src/OctreePersistThread.h | 6 +++- libraries/shared/src/SharedUtil.cpp | 33 ++++++++++++++++--- libraries/shared/src/SharedUtil.h | 2 +- 7 files changed, 64 insertions(+), 10 deletions(-) diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index f78a9a2b30..da37e66aaa 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -1017,6 +1017,9 @@ void OctreeServer::readConfiguration() { readOptionBool(QString("debugReceiving"), settingsSectionObject, _debugReceiving); qDebug("debugReceiving=%s", debug::valueOf(_debugReceiving)); + readOptionBool(QString("debugTimestampNow"), settingsSectionObject, _debugTimestampNow); + qDebug() << "debugTimestampNow=" << _debugTimestampNow; + bool noPersist; readOptionBool(QString("NoPersist"), settingsSectionObject, noPersist); _wantPersist = !noPersist; @@ -1133,7 +1136,7 @@ void OctreeServer::run() { // now set up PersistThread _persistThread = new OctreePersistThread(_tree, _persistFilename, _persistInterval, - _wantBackup, _backupInterval, _backupExtensionFormat); + _wantBackup, _backupInterval, _backupExtensionFormat, _debugTimestampNow); if (_persistThread) { _persistThread->initialize(true); } diff --git a/assignment-client/src/octree/OctreeServer.h b/assignment-client/src/octree/OctreeServer.h index 8a91b94da0..69fc3b0852 100644 --- a/assignment-client/src/octree/OctreeServer.h +++ b/assignment-client/src/octree/OctreeServer.h @@ -162,6 +162,7 @@ protected: bool _wantPersist; bool _debugSending; bool _debugReceiving; + bool _debugTimestampNow; bool _verboseDebug; JurisdictionMap* _jurisdiction; JurisdictionSender* _jurisdictionSender; diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 04c48e460e..ccd12a30ed 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -359,6 +359,13 @@ "default": false, "advanced": true }, + { + "name": "debugTimestampNow", + "type": "checkbox", + "help": "extra debugging for usecTimestampNow() function", + "default": false, + "advanced": true + }, { "name": "clockSkew", "label": "Clock Skew", diff --git a/libraries/octree/src/OctreePersistThread.cpp b/libraries/octree/src/OctreePersistThread.cpp index f74ddfa5f0..c7e769c20b 100644 --- a/libraries/octree/src/OctreePersistThread.cpp +++ b/libraries/octree/src/OctreePersistThread.cpp @@ -22,8 +22,8 @@ const int OctreePersistThread::DEFAULT_BACKUP_INTERVAL = 1000 * 60 * 30; // ever const QString OctreePersistThread::DEFAULT_BACKUP_EXTENSION_FORMAT(".backup.%Y-%m-%d.%H:%M:%S.%z"); -OctreePersistThread::OctreePersistThread(Octree* tree, const QString& filename, int persistInterval, - bool wantBackup, int backupInterval, const QString& backupExtensionFormat) : +OctreePersistThread::OctreePersistThread(Octree* tree, const QString& filename, int persistInterval, bool wantBackup, + int backupInterval, const QString& backupExtensionFormat, bool debugTimestampNow) : _tree(tree), _filename(filename), _backupExtensionFormat(backupExtensionFormat), @@ -33,7 +33,9 @@ OctreePersistThread::OctreePersistThread(Octree* tree, const QString& filename, _loadTimeUSecs(0), _lastCheck(0), _lastBackup(0), - _wantBackup(wantBackup) + _wantBackup(wantBackup), + _debugTimestampNow(debugTimestampNow), + _lastTimeDebug(0) { } @@ -101,6 +103,18 @@ bool OctreePersistThread::process() { persist(); } } + + // if we were asked to debugTimestampNow do that now... + if (_debugTimestampNow) { + quint64 now = usecTimestampNow(); + quint64 sinceLastDebug = now - _lastTimeDebug; + quint64 DEBUG_TIMESTAMP_INTERVAL = 600000000; // every 10 minutes + + if (sinceLastDebug > DEBUG_TIMESTAMP_INTERVAL) { + _lastTimeDebug = usecTimestampNow(true); // ask for debug output + } + + } return isStillRunning(); // keep running till they terminate us } diff --git a/libraries/octree/src/OctreePersistThread.h b/libraries/octree/src/OctreePersistThread.h index 06b97b2dcb..13597268c8 100644 --- a/libraries/octree/src/OctreePersistThread.h +++ b/libraries/octree/src/OctreePersistThread.h @@ -28,7 +28,8 @@ public: OctreePersistThread(Octree* tree, const QString& filename, int persistInterval = DEFAULT_PERSIST_INTERVAL, bool wantBackup = false, int backupInterval = DEFAULT_BACKUP_INTERVAL, - const QString& backupExtensionFormat = DEFAULT_BACKUP_EXTENSION_FORMAT); + const QString& backupExtensionFormat = DEFAULT_BACKUP_EXTENSION_FORMAT, + bool debugTimestampNow = false); bool isInitialLoadComplete() const { return _initialLoadComplete; } quint64 getLoadElapsedTime() const { return _loadTimeUSecs; } @@ -57,6 +58,9 @@ private: quint64 _lastBackup; bool _wantBackup; time_t _lastPersistTime; + + bool _debugTimestampNow; + quint64 _lastTimeDebug; }; #endif // hifi_OctreePersistThread_h diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index 05d208c2f8..595d7078f8 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -37,7 +37,7 @@ void usecTimestampNowForceClockSkew(int clockSkew) { ::usecTimestampNowAdjust = clockSkew; } -quint64 usecTimestampNow() { +quint64 usecTimestampNow(bool wantDebug) { static bool usecTimestampNowIsInitialized = false; static qint64 TIME_REFERENCE = 0; // in usec static QElapsedTimer timestampTimer; @@ -57,7 +57,6 @@ quint64 usecTimestampNow() { quint64 msecsElapsed = timestampTimer.restart(); quint64 usecsElapsed = nsecsElapsed / 1000; // nsec to usec TIME_REFERENCE += usecsElapsed; - const bool wantDebug = false; if (wantDebug) { qDebug() << "usecTimestampNow() - resetting QElapsedTimer. "; qDebug() << " RESET_AFTER_ELAPSED_NSECS:" << RESET_AFTER_ELAPSED_NSECS; @@ -68,8 +67,34 @@ quint64 usecTimestampNow() { } } - // usec nsec to usec usec - return TIME_REFERENCE + timestampTimer.nsecsElapsed() / 1000 + ::usecTimestampNowAdjust; + quint64 nsecsElapsed = timestampTimer.nsecsElapsed(); + quint64 usecsElapsed = nsecsElapsed / 1000; // nsec to usec + quint64 now = TIME_REFERENCE + usecsElapsed + ::usecTimestampNowAdjust; + + if (wantDebug) { + QDateTime currentLocalTime = QDateTime::currentDateTime(); + + quint64 msecsNow = now / 1000; // usecs to msecs + QDateTime nowAsString; + nowAsString.setMSecsSinceEpoch(msecsNow); + + quint64 msecsTimeReference = TIME_REFERENCE / 1000; // usecs to msecs + QDateTime timeReferenceAsString; + timeReferenceAsString.setMSecsSinceEpoch(msecsTimeReference); + + qDebug() << "usecTimestampNow() - details... "; + qDebug() << " TIME_REFERENCE:" << TIME_REFERENCE; + qDebug() << " timeReferenceAsString:" << timeReferenceAsString.toString("yyyy-MM-dd hh:mm:ss.zzz"); + qDebug() << " usecTimestampNowAdjust:" << usecTimestampNowAdjust; + qDebug() << " nsecsElapsed:" << nsecsElapsed; + qDebug() << " usecsElapsed:" << usecsElapsed; + qDebug() << " now:" << now; + qDebug() << " msecsNow:" << msecsNow; + qDebug() << " nowAsString:" << nowAsString.toString("yyyy-MM-dd hh:mm:ss.zzz"); + qDebug() << " currentLocalTime:" << currentLocalTime.toString("yyyy-MM-dd hh:mm:ss.zzz"); + } + + return now; } float randFloat() { diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index 69dfb4db35..3fe3c3d1ec 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -67,7 +67,7 @@ static const quint64 USECS_PER_SECOND = USECS_PER_MSEC * MSECS_PER_SECOND; const int BITS_IN_BYTE = 8; -quint64 usecTimestampNow(); +quint64 usecTimestampNow(bool wantDebug = false); void usecTimestampNowForceClockSkew(int clockSkew); float randFloat(); From 59c13f3c38bf67661a6ec576e1dbb3fac92c2adc Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Nov 2014 16:03:43 -0800 Subject: [PATCH 74/94] coding standard cleanup, fix warning --- interface/src/ui/overlays/Overlays.h | 3 ++- libraries/octree/src/OctreeHeadlessViewer.h | 3 ++- libraries/octree/src/OctreeRenderer.h | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 295412cdbd..2cd80041cd 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -51,7 +51,8 @@ public: ~Overlays(); void init(QGLWidget* parent); void update(float deltatime); - void render3D(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::RenderSide renderSide = RenderArgs::MONO); + void render3D(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, + RenderArgs::RenderSide renderSide = RenderArgs::MONO); void render2D(); public slots: diff --git a/libraries/octree/src/OctreeHeadlessViewer.h b/libraries/octree/src/OctreeHeadlessViewer.h index 03b8a204e0..9a6a5c7102 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.h +++ b/libraries/octree/src/OctreeHeadlessViewer.h @@ -33,7 +33,8 @@ public: virtual void renderElement(OctreeElement* element, RenderArgs* args) { /* swallow these */ } virtual void init(); - virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE) { /* swallow these */ } + virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, + RenderArgs::RenderSide renderSide = RenderArgs::MONO) { /* swallow these */ } void setJurisdictionListener(JurisdictionListener* jurisdictionListener) { _jurisdictionListener = jurisdictionListener; } diff --git a/libraries/octree/src/OctreeRenderer.h b/libraries/octree/src/OctreeRenderer.h index e8612b4cb6..2999f34fb6 100644 --- a/libraries/octree/src/OctreeRenderer.h +++ b/libraries/octree/src/OctreeRenderer.h @@ -52,7 +52,8 @@ public: virtual void init(); /// render the content of the octree - virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::RenderSide renderSide = RenderArgs::MONO); + virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, + RenderArgs::RenderSide renderSide = RenderArgs::MONO); ViewFrustum* getViewFrustum() const { return _viewFrustum; } void setViewFrustum(ViewFrustum* viewFrustum) { _viewFrustum = viewFrustum; } From b511f868d522e9f86cbbbdea38ebda83e756b0dd Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 15 Nov 2014 20:24:00 -0800 Subject: [PATCH 75/94] fix warnings in overlays --- interface/src/ui/overlays/BillboardOverlay.cpp | 12 +++++++----- interface/src/ui/overlays/ImageOverlay.cpp | 11 ++++++----- interface/src/ui/overlays/ModelOverlay.cpp | 6 +++--- interface/src/ui/overlays/Overlay.cpp | 18 ++++++++++-------- 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/interface/src/ui/overlays/BillboardOverlay.cpp b/interface/src/ui/overlays/BillboardOverlay.cpp index dee5eceab7..5fbad7839a 100644 --- a/interface/src/ui/overlays/BillboardOverlay.cpp +++ b/interface/src/ui/overlays/BillboardOverlay.cpp @@ -26,12 +26,14 @@ BillboardOverlay::BillboardOverlay() : BillboardOverlay::BillboardOverlay(const BillboardOverlay* billboardOverlay) : Base3DOverlay(billboardOverlay), - _newTextureNeeded(true), - _scale(billboardOverlay->_scale), - _isFacingAvatar(billboardOverlay->_isFacingAvatar), - _fromImage(billboardOverlay->_fromImage), _url(billboardOverlay->_url), - _billboard(billboardOverlay->_billboard) + _billboard(billboardOverlay->_billboard), + _size(), + _billboardTexture(), + _newTextureNeeded(true), + _fromImage(billboardOverlay->_fromImage), + _scale(billboardOverlay->_scale), + _isFacingAvatar(billboardOverlay->_isFacingAvatar) { } diff --git a/interface/src/ui/overlays/ImageOverlay.cpp b/interface/src/ui/overlays/ImageOverlay.cpp index fad19be292..f903dfe19c 100644 --- a/interface/src/ui/overlays/ImageOverlay.cpp +++ b/interface/src/ui/overlays/ImageOverlay.cpp @@ -29,12 +29,13 @@ ImageOverlay::ImageOverlay() : ImageOverlay::ImageOverlay(const ImageOverlay* imageOverlay) : Overlay2D(imageOverlay), - _textureID(0), - _textureBound(false), - _wantClipFromImage(false), - _renderImage(imageOverlay->_renderImage), _imageURL(imageOverlay->_imageURL), - _textureImage(imageOverlay->_textureImage) + _textureImage(imageOverlay->_textureImage), + _textureID(0), + _fromImage(), + _renderImage(imageOverlay->_renderImage), + _textureBound(false), + _wantClipFromImage(false) { } diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 3594d7e828..60049e0b3b 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -26,10 +26,10 @@ ModelOverlay::ModelOverlay(const ModelOverlay* modelOverlay) : Base3DOverlay(modelOverlay), _model(), _modelTextures(QVariantMap()), - _scale(modelOverlay->_scale), - _updateModel(false), _url(modelOverlay->_url), - _rotation(modelOverlay->_rotation) + _rotation(modelOverlay->_rotation), + _scale(modelOverlay->_scale), + _updateModel(false) { _model.init(); if (_url.isValid()) { diff --git a/interface/src/ui/overlays/Overlay.cpp b/interface/src/ui/overlays/Overlay.cpp index 549152ded0..fd7aaca717 100644 --- a/interface/src/ui/overlays/Overlay.cpp +++ b/interface/src/ui/overlays/Overlay.cpp @@ -41,20 +41,22 @@ Overlay::Overlay() : Overlay::Overlay(const Overlay* overlay) : _parent(NULL), + _isLoaded(overlay->_isLoaded), _alpha(overlay->_alpha), - _lastPulseUpdate(usecTimestampNow()), - _alphaPulse(overlay->_alphaPulse), - _anchor(overlay->_anchor), - _color(overlay->_color), - _colorPulse(overlay->_colorPulse), _glowLevel(overlay->_glowLevel), - _glowLevelPulse(overlay->_glowLevelPulse), - _pulseDirection(overlay->_pulseDirection), + _pulse(overlay->_pulse), _pulseMax(overlay->_pulseMax), _pulseMin(overlay->_pulseMin), _pulsePeriod(overlay->_pulsePeriod), + _pulseDirection(overlay->_pulseDirection), + _lastPulseUpdate(usecTimestampNow()), + _glowLevelPulse(overlay->_glowLevelPulse), + _alphaPulse(overlay->_alphaPulse), + _colorPulse(overlay->_colorPulse), + _color(overlay->_color), _visible(overlay->_visible), - _isLoaded(overlay->_isLoaded) + _anchor(overlay->_anchor), + _scriptEngine(NULL) { } From f44513ebe7df295587867a0ab9f7bf0ac31b247f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 15 Nov 2014 22:55:12 -0800 Subject: [PATCH 76/94] added support for rolling version numbers in backups --- assignment-client/src/octree/OctreeServer.cpp | 6 +- assignment-client/src/octree/OctreeServer.h | 1 + .../resources/describe-settings.json | 14 ++++- libraries/octree/src/OctreePersistThread.cpp | 58 +++++++++++++++++-- libraries/octree/src/OctreePersistThread.h | 6 +- 5 files changed, 74 insertions(+), 11 deletions(-) diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index f78a9a2b30..35b706d5f2 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -1047,6 +1047,10 @@ void OctreeServer::readConfiguration() { _backupInterval = OctreePersistThread::DEFAULT_BACKUP_INTERVAL; readOptionInt(QString("backupInterval"), settingsSectionObject, _backupInterval); qDebug() << "backupInterval=" << _backupInterval; + + _maxBackupVersions = OctreePersistThread::DEFAULT_MAX_BACKUP_VERSIONS; + readOptionInt(QString("maxBackupVersions"), settingsSectionObject, _maxBackupVersions); + qDebug() << "maxBackupVersions=" << _maxBackupVersions; } } else { @@ -1133,7 +1137,7 @@ void OctreeServer::run() { // now set up PersistThread _persistThread = new OctreePersistThread(_tree, _persistFilename, _persistInterval, - _wantBackup, _backupInterval, _backupExtensionFormat); + _wantBackup, _backupInterval, _backupExtensionFormat, _maxBackupVersions); if (_persistThread) { _persistThread->initialize(true); } diff --git a/assignment-client/src/octree/OctreeServer.h b/assignment-client/src/octree/OctreeServer.h index 8a91b94da0..b2a452ae52 100644 --- a/assignment-client/src/octree/OctreeServer.h +++ b/assignment-client/src/octree/OctreeServer.h @@ -172,6 +172,7 @@ protected: bool _wantBackup; QString _backupExtensionFormat; int _backupInterval; + int _maxBackupVersions; static OctreeServer* _instance; diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 04c48e460e..d698fc3454 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -302,9 +302,9 @@ { "name": "backupExtensionFormat", "label": "Backup File Extension Format:", - "help": "Format used to create the extension for the backup of your persisted entities.", - "placeholder": ".backup.%Y-%m-%d.%H:%M:%S.%z", - "default": ".backup.%Y-%m-%d.%H:%M:%S.%z", + "help": "Format used to create the extension for the backup of your persisted entities. Use a format with %N to get rolling. Or use date formatting like %Y-%m-%d.%H:%M:%S.%z", + "placeholder": ".backup.%N", + "default": ".backup.%N", "advanced": true }, { @@ -315,6 +315,14 @@ "default": "1800000", "advanced": true }, + { + "name": "maxBackupVersions", + "label": "Max Rolled Backup Versions", + "help": "If your backup extension format uses 'rolling', how many versions do you want us to keep?", + "placeholder": "5", + "default": "5", + "advanced": true + }, { "name": "NoBackup", "type": "checkbox", diff --git a/libraries/octree/src/OctreePersistThread.cpp b/libraries/octree/src/OctreePersistThread.cpp index f74ddfa5f0..53de80660c 100644 --- a/libraries/octree/src/OctreePersistThread.cpp +++ b/libraries/octree/src/OctreePersistThread.cpp @@ -12,21 +12,26 @@ #include #include +#include + #include #include #include "OctreePersistThread.h" const int OctreePersistThread::DEFAULT_PERSIST_INTERVAL = 1000 * 30; // every 30 seconds -const int OctreePersistThread::DEFAULT_BACKUP_INTERVAL = 1000 * 60 * 30; // every 30 minutes -const QString OctreePersistThread::DEFAULT_BACKUP_EXTENSION_FORMAT(".backup.%Y-%m-%d.%H:%M:%S.%z"); +const int OctreePersistThread::DEFAULT_BACKUP_INTERVAL = 1000 * 60 * 1; // 30; // every 30 minutes +const QString OctreePersistThread::DEFAULT_BACKUP_EXTENSION_FORMAT(".backup.%N"); +const int OctreePersistThread::DEFAULT_MAX_BACKUP_VERSIONS = 5; OctreePersistThread::OctreePersistThread(Octree* tree, const QString& filename, int persistInterval, - bool wantBackup, int backupInterval, const QString& backupExtensionFormat) : + bool wantBackup, int backupInterval, const QString& backupExtensionFormat, + int maxBackupVersions) : _tree(tree), _filename(filename), _backupExtensionFormat(backupExtensionFormat), + _maxBackupVersions(maxBackupVersions), _persistInterval(persistInterval), _backupInterval(backupInterval), _initialLoadComplete(false), @@ -131,6 +136,37 @@ void OctreePersistThread::persist() { } } +void OctreePersistThread::rollOldBackupVersions() { + if (!_backupExtensionFormat.contains("%N")) { + return; // this backup extension format doesn't support rolling + } + + qDebug() << "Rolling old backup versions..."; + for(int n = _maxBackupVersions - 1; n > 0; n--) { + QString backupExtensionN = _backupExtensionFormat; + QString backupExtensionNplusOne = _backupExtensionFormat; + backupExtensionN.replace(QString("%N"), QString::number(n)); + backupExtensionNplusOne.replace(QString("%N"), QString::number(n+1)); + + QString backupFilenameN = _filename + backupExtensionN; + QString backupFilenameNplusOne = _filename + backupExtensionNplusOne; + + QFile backupFileN(backupFilenameN); + + if (backupFileN.exists()) { + qDebug() << "rolling backup file " << backupFilenameN << "to" << backupFilenameNplusOne << "..."; + int result = rename(qPrintable(backupFilenameN), qPrintable(backupFilenameNplusOne)); + if (result == 0) { + qDebug() << "DONE rolling backup file " << backupFilenameN << "to" << backupFilenameNplusOne << "..."; + } else { + qDebug() << "ERROR in rolling backup file " << backupFilenameN << "to" << backupFilenameNplusOne << "..."; + } + } + } + qDebug() << "Done rolling old backup versions..."; +} + + void OctreePersistThread::backup() { if (_wantBackup) { quint64 now = usecTimestampNow(); @@ -141,10 +177,20 @@ void OctreePersistThread::backup() { if (sinceLastBackup > intervalToBackup) { struct tm* localTime = localtime(&_lastPersistTime); - char backupExtension[256]; - strftime(backupExtension, sizeof(backupExtension), qPrintable(_backupExtensionFormat), localTime); + QString backupFileName; + + // check to see if they asked for version rolling format + if (_backupExtensionFormat.contains("%N")) { + rollOldBackupVersions(); // rename all the old backup files accordingly + QString backupExtension = _backupExtensionFormat; + backupExtension.replace(QString("%N"), QString("1")); + backupFileName = _filename + backupExtension; + } else { + char backupExtension[256]; + strftime(backupExtension, sizeof(backupExtension), qPrintable(_backupExtensionFormat), localTime); + backupFileName = _filename + backupExtension; + } - QString backupFileName = _filename + backupExtension; qDebug() << "backing up persist file " << _filename << "to" << backupFileName << "..."; int result = rename(qPrintable(_filename), qPrintable(backupFileName)); diff --git a/libraries/octree/src/OctreePersistThread.h b/libraries/octree/src/OctreePersistThread.h index 06b97b2dcb..5aac67844f 100644 --- a/libraries/octree/src/OctreePersistThread.h +++ b/libraries/octree/src/OctreePersistThread.h @@ -25,10 +25,12 @@ public: static const int DEFAULT_PERSIST_INTERVAL; static const int DEFAULT_BACKUP_INTERVAL; static const QString DEFAULT_BACKUP_EXTENSION_FORMAT; + static const int DEFAULT_MAX_BACKUP_VERSIONS; OctreePersistThread(Octree* tree, const QString& filename, int persistInterval = DEFAULT_PERSIST_INTERVAL, bool wantBackup = false, int backupInterval = DEFAULT_BACKUP_INTERVAL, - const QString& backupExtensionFormat = DEFAULT_BACKUP_EXTENSION_FORMAT); + const QString& backupExtensionFormat = DEFAULT_BACKUP_EXTENSION_FORMAT, + int maxBackupVersions = DEFAULT_MAX_BACKUP_VERSIONS); bool isInitialLoadComplete() const { return _initialLoadComplete; } quint64 getLoadElapsedTime() const { return _loadTimeUSecs; } @@ -44,10 +46,12 @@ protected: void persist(); void backup(); + void rollOldBackupVersions(); private: Octree* _tree; QString _filename; QString _backupExtensionFormat; + int _maxBackupVersions; int _persistInterval; int _backupInterval; bool _initialLoadComplete; From 25850136155dfb0126b85a83c212d20dcd93a7c0 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 17 Nov 2014 09:54:43 -0800 Subject: [PATCH 77/94] JS signal when AM mutes client --- interface/src/DatagramProcessor.cpp | 1 + libraries/audio/src/AudioScriptingInterface.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/interface/src/DatagramProcessor.cpp b/interface/src/DatagramProcessor.cpp index 6f9f4cae68..5d034c1c17 100644 --- a/interface/src/DatagramProcessor.cpp +++ b/interface/src/DatagramProcessor.cpp @@ -152,6 +152,7 @@ void DatagramProcessor::processDatagrams() { if (glm::distance(Application::getInstance()->getAvatar()->getPosition(), position) < radius && !Application::getInstance()->getAudio()->getMuted()) { Application::getInstance()->getAudio()->toggleMute(); + AudioScriptingInterface::getInstance().mutedByMixer(); } break; } diff --git a/libraries/audio/src/AudioScriptingInterface.h b/libraries/audio/src/AudioScriptingInterface.h index 0017806b40..7a60577042 100644 --- a/libraries/audio/src/AudioScriptingInterface.h +++ b/libraries/audio/src/AudioScriptingInterface.h @@ -37,6 +37,9 @@ public slots: void injectorStopped(); +signals: + void mutedByMixer(); + private: AudioScriptingInterface(); QList< QPointer > _activeInjectors; From 46eebe9d40a3b270bcdae8277a500fcc2e5325d4 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 17 Nov 2014 10:26:47 -0800 Subject: [PATCH 78/94] Give noisy mutes their own packet type --- assignment-client/src/audio/AudioMixer.cpp | 16 ++--------- interface/src/DatagramProcessor.cpp | 27 +++++++++++++------ libraries/audio/src/AudioScriptingInterface.h | 1 + libraries/networking/src/PacketHeaders.h | 2 +- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 6c8a4fd1c2..81bfe7a734 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -779,21 +779,9 @@ void AudioMixer::run() { static const int TIME_BETWEEN_MUTES = 5; // in secs if (usecTimestampNow() - nodeData->getAvatarAudioStream()->getLastMuted() > TIME_BETWEEN_MUTES * USECS_PER_SECOND) { - int headerSize = numBytesForPacketHeaderGivenPacketType(PacketTypeMuteEnvironment); - int packetSize = headerSize + sizeof(glm::vec3) + sizeof(float); - - // Fake data to force mute - glm::vec3 position = nodeData->getAvatarAudioStream()->getPosition(); - float radius = 1.0f; - - char* packet = (char*)malloc(packetSize); - populatePacketHeader(packet, PacketTypeMuteEnvironment); - memcpy(packet + headerSize, &position, sizeof(glm::vec3)); - memcpy(packet + headerSize + sizeof(glm::vec3), &radius, sizeof(float)); - - nodeList->writeDatagram(packet, packetSize, node); + QByteArray packet = byteArrayWithPopulatedHeader(PacketTypeNoisyMute); + nodeList->writeDatagram(packet, node); nodeData->getAvatarAudioStream()->setLastMutedNow(); - free(packet); } } diff --git a/interface/src/DatagramProcessor.cpp b/interface/src/DatagramProcessor.cpp index 5d034c1c17..96680423ed 100644 --- a/interface/src/DatagramProcessor.cpp +++ b/interface/src/DatagramProcessor.cpp @@ -141,18 +141,29 @@ void DatagramProcessor::processDatagrams() { AccountManager::getInstance().checkAndSignalForAccessToken(); break; } + case PacketTypeNoisyMute: case PacketTypeMuteEnvironment: { - glm::vec3 position; - float radius; + bool mute = !Application::getInstance()->getAudio()->getMuted(); - int headerSize = numBytesForPacketHeaderGivenPacketType(PacketTypeMuteEnvironment); - memcpy(&position, incomingPacket.constData() + headerSize, sizeof(glm::vec3)); - memcpy(&radius, incomingPacket.constData() + headerSize + sizeof(glm::vec3), sizeof(float)); + if (incomingType == PacketTypeMuteEnvironment) { + glm::vec3 position; + float radius, distance; + + int headerSize = numBytesForPacketHeaderGivenPacketType(PacketTypeMuteEnvironment); + memcpy(&position, incomingPacket.constData() + headerSize, sizeof(glm::vec3)); + memcpy(&radius, incomingPacket.constData() + headerSize + sizeof(glm::vec3), sizeof(float)); + distance = glm::distance(Application::getInstance()->getAvatar()->getPosition(), position); + + mute = mute && (distance < radius); + } - if (glm::distance(Application::getInstance()->getAvatar()->getPosition(), position) < radius - && !Application::getInstance()->getAudio()->getMuted()) { + if (mute) { Application::getInstance()->getAudio()->toggleMute(); - AudioScriptingInterface::getInstance().mutedByMixer(); + if (incomingType == PacketTypeMuteEnvironment) { + AudioScriptingInterface::getInstance().environmentMuted(); + } else { + AudioScriptingInterface::getInstance().mutedByMixer(); + } } break; } diff --git a/libraries/audio/src/AudioScriptingInterface.h b/libraries/audio/src/AudioScriptingInterface.h index 7a60577042..5b67666a97 100644 --- a/libraries/audio/src/AudioScriptingInterface.h +++ b/libraries/audio/src/AudioScriptingInterface.h @@ -39,6 +39,7 @@ public slots: signals: void mutedByMixer(); + void environmentMuted(); private: AudioScriptingInterface(); diff --git a/libraries/networking/src/PacketHeaders.h b/libraries/networking/src/PacketHeaders.h index d617f2243a..6cca5b505d 100644 --- a/libraries/networking/src/PacketHeaders.h +++ b/libraries/networking/src/PacketHeaders.h @@ -54,7 +54,7 @@ enum PacketType { UNUSED_2, UNUSED_3, UNUSED_4, - UNUSED_5, + PacketTypeNoisyMute, PacketTypeMetavoxelData, PacketTypeAvatarIdentity, PacketTypeAvatarBillboard, From 4615afe034577dcdd1db6463dd99f6c6a0b85171 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 17 Nov 2014 10:32:28 -0800 Subject: [PATCH 79/94] Remove lastMuted member in AvatarAudioStream --- assignment-client/src/audio/AudioMixer.cpp | 10 +++------- assignment-client/src/audio/AvatarAudioStream.cpp | 3 +-- assignment-client/src/audio/AvatarAudioStream.h | 5 ----- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 81bfe7a734..ab4524cb71 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -776,13 +776,9 @@ void AudioMixer::run() { // if the stream should be muted, send mute packet if (nodeData->getAvatarAudioStream() && shouldMute(nodeData->getAvatarAudioStream()->getQuietestFrameLoudness())) { - static const int TIME_BETWEEN_MUTES = 5; // in secs - if (usecTimestampNow() - nodeData->getAvatarAudioStream()->getLastMuted() > - TIME_BETWEEN_MUTES * USECS_PER_SECOND) { - QByteArray packet = byteArrayWithPopulatedHeader(PacketTypeNoisyMute); - nodeList->writeDatagram(packet, node); - nodeData->getAvatarAudioStream()->setLastMutedNow(); - } + QByteArray packet = byteArrayWithPopulatedHeader(PacketTypeNoisyMute); + nodeList->writeDatagram(packet, node); + nodeData->getAvatarAudioStream()->setLastMutedNow(); } if (node->getType() == NodeType::Agent && node->getActiveSocket() diff --git a/assignment-client/src/audio/AvatarAudioStream.cpp b/assignment-client/src/audio/AvatarAudioStream.cpp index cd67722a2e..90dcefa09d 100644 --- a/assignment-client/src/audio/AvatarAudioStream.cpp +++ b/assignment-client/src/audio/AvatarAudioStream.cpp @@ -14,8 +14,7 @@ #include "AvatarAudioStream.h" AvatarAudioStream::AvatarAudioStream(bool isStereo, const InboundAudioStream::Settings& settings) : - PositionalAudioStream(PositionalAudioStream::Microphone, isStereo, settings), - _lastMuted(usecTimestampNow()) + PositionalAudioStream(PositionalAudioStream::Microphone, isStereo, settings) { } diff --git a/assignment-client/src/audio/AvatarAudioStream.h b/assignment-client/src/audio/AvatarAudioStream.h index e1fb6dd486..482c6fd538 100644 --- a/assignment-client/src/audio/AvatarAudioStream.h +++ b/assignment-client/src/audio/AvatarAudioStream.h @@ -20,17 +20,12 @@ class AvatarAudioStream : public PositionalAudioStream { public: AvatarAudioStream(bool isStereo, const InboundAudioStream::Settings& settings); - qint64 getLastMuted() const { return _lastMuted; } - void setLastMutedNow() { _lastMuted = usecTimestampNow(); } - private: // disallow copying of AvatarAudioStream objects AvatarAudioStream(const AvatarAudioStream&); AvatarAudioStream& operator= (const AvatarAudioStream&); int parseStreamProperties(PacketType type, const QByteArray& packetAfterSeqNum, int& numAudioSamples); - - qint64 _lastMuted; }; #endif // hifi_AvatarAudioStream_h From 0528a9ff9b21009f95661ca71496ded5f21e1646 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 17 Nov 2014 10:49:35 -0800 Subject: [PATCH 80/94] Remove forgotten setLastMuted --- assignment-client/src/audio/AudioMixer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index ab4524cb71..32447d1d61 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -778,7 +778,6 @@ void AudioMixer::run() { && shouldMute(nodeData->getAvatarAudioStream()->getQuietestFrameLoudness())) { QByteArray packet = byteArrayWithPopulatedHeader(PacketTypeNoisyMute); nodeList->writeDatagram(packet, node); - nodeData->getAvatarAudioStream()->setLastMutedNow(); } if (node->getType() == NodeType::Agent && node->getActiveSocket() From ec64bef951ca3a93bc502e70824ed26642235dac Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 17 Nov 2014 11:18:38 -0800 Subject: [PATCH 81/94] revert debugging change --- libraries/octree/src/OctreePersistThread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/octree/src/OctreePersistThread.cpp b/libraries/octree/src/OctreePersistThread.cpp index 53de80660c..2684b76d2f 100644 --- a/libraries/octree/src/OctreePersistThread.cpp +++ b/libraries/octree/src/OctreePersistThread.cpp @@ -20,7 +20,7 @@ #include "OctreePersistThread.h" const int OctreePersistThread::DEFAULT_PERSIST_INTERVAL = 1000 * 30; // every 30 seconds -const int OctreePersistThread::DEFAULT_BACKUP_INTERVAL = 1000 * 60 * 1; // 30; // every 30 minutes +const int OctreePersistThread::DEFAULT_BACKUP_INTERVAL = 1000 * 60 * 30; // every 30 minutes const QString OctreePersistThread::DEFAULT_BACKUP_EXTENSION_FORMAT(".backup.%N"); const int OctreePersistThread::DEFAULT_MAX_BACKUP_VERSIONS = 5; From 18faa78aa3f2d6808ee9458f5e5411bf33961a71 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 17 Nov 2014 11:22:32 -0800 Subject: [PATCH 82/94] New text for reverb settings --- domain-server/resources/describe-settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 04c48e460e..b95ff4a020 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -167,7 +167,7 @@ "name": "reverb", "type": "table", "label": "Reverb Settings", - "help": "In this table you can set custom reverb values for each audio zones", + "help": "In this table you can set reverb levels for audio zones. For a medium-sized (e.g., 100 square meter) meeting room, try a decay time of around 1.5 seconds and a wet level of -10 db. For an airplane hangar or cathedral, try a decay time of 4 seconds and a wet level of -5 db.", "numbered": true, "columns": [ { From 3f3eae9350498bc25e0fd821557f5581482c3e64 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 17 Nov 2014 12:02:09 -0800 Subject: [PATCH 83/94] Adjusted distances for new avatar sizes. --- interface/src/Application.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.h b/interface/src/Application.h index dc1ec96321..2c70249b32 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -115,15 +115,15 @@ static const float NODE_KILLED_BLUE = 0.0f; static const QString SNAPSHOT_EXTENSION = ".jpg"; static const float BILLBOARD_FIELD_OF_VIEW = 30.0f; // degrees -static const float BILLBOARD_DISTANCE = 5.0f; // meters +static const float BILLBOARD_DISTANCE = 5.56f; // meters static const int MIRROR_VIEW_TOP_PADDING = 5; static const int MIRROR_VIEW_LEFT_PADDING = 10; static const int MIRROR_VIEW_WIDTH = 265; static const int MIRROR_VIEW_HEIGHT = 215; -static const float MIRROR_FULLSCREEN_DISTANCE = 0.35f; -static const float MIRROR_REARVIEW_DISTANCE = 0.65f; -static const float MIRROR_REARVIEW_BODY_DISTANCE = 2.3f; +static const float MIRROR_FULLSCREEN_DISTANCE = 0.389f; +static const float MIRROR_REARVIEW_DISTANCE = 0.722f; +static const float MIRROR_REARVIEW_BODY_DISTANCE = 2.56f; static const float MIRROR_FIELD_OF_VIEW = 30.0f; static const quint64 TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS = 1 * USECS_PER_SECOND; From de2b86957b4af5dc9b5cf7a82d7ba40cd4a79e2e Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 17 Nov 2014 12:04:45 -0800 Subject: [PATCH 84/94] Proportional dry fraction --- interface/src/Audio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 2dc94e6027..c7de0788a3 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -566,8 +566,8 @@ void Audio::setReverbOptions(const AudioEffectOptions* options) { } void Audio::addReverb(int16_t* samplesData, int numSamples, QAudioFormat& audioFormat) { - float dryFraction = DB_CO(_reverbOptions->getDryLevel()); float wetFraction = DB_CO(_reverbOptions->getWetLevel()); + float dryFraction = 1.0f - wetFraction; float lValue,rValue; for (int sample = 0; sample < numSamples; sample += audioFormat.channelCount()) { From 9fac84a9378371468a8ba1415080116a7ed8608d Mon Sep 17 00:00:00 2001 From: Chris Collins Date: Mon, 17 Nov 2014 12:58:54 -0800 Subject: [PATCH 85/94] Changed the Alpha on the editmodels overlay Changed the Alpha on the editmodels overlay --- examples/editModels.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/editModels.js b/examples/editModels.js index 69976e03a1..3f1863fef2 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -2479,7 +2479,7 @@ function Tooltip() { margin: this.margin, text: "", color: { red: 228, green: 228, blue: 228 }, - alpha: 0.5, + alpha: 0.8, visible: false }); this.show = function (doShow) { From 082b9ff59f3aa8c590a9d26104e3c555f922d25f Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 17 Nov 2014 13:43:55 -0800 Subject: [PATCH 86/94] Faster and better Local reverb / no echo --- interface/src/Audio.cpp | 25 ++++++++----------------- interface/src/Audio.h | 2 +- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index c7de0788a3..99039829e7 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -565,7 +565,7 @@ void Audio::setReverbOptions(const AudioEffectOptions* options) { } } -void Audio::addReverb(int16_t* samplesData, int numSamples, QAudioFormat& audioFormat) { +void Audio::addReverb(int16_t* samplesData, int numSamples, QAudioFormat& audioFormat, bool noEcho) { float wetFraction = DB_CO(_reverbOptions->getWetLevel()); float dryFraction = 1.0f - wetFraction; @@ -579,11 +579,15 @@ void Audio::addReverb(int16_t* samplesData, int numSamples, QAudioFormat& audioF for (int j = sample; j < sample + audioFormat.channelCount(); j++) { if (j == sample) { // left channel - int lResult = glm::clamp((int)(samplesData[j] * dryFraction + lValue * wetFraction), MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); + int lResult = glm::clamp((int)(samplesData[j] * ((noEcho) ? 0.0f : dryFraction) + + lValue * wetFraction), + MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); samplesData[j] = (int16_t)lResult; } else if (j == (sample + 1)) { // right channel - int rResult = glm::clamp((int)(samplesData[j] * dryFraction + rValue * wetFraction), MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); + int rResult = glm::clamp((int)(samplesData[j] * ((noEcho) ? 0.0f : dryFraction) + + rValue * wetFraction), + MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); samplesData[j] = (int16_t)rResult; } else { // ignore channels above 2 @@ -622,23 +626,10 @@ void Audio::handleLocalEchoAndReverb(QByteArray& inputByteArray) { } if (hasLocalReverb) { - QByteArray loopbackCopy; - if (!hasEcho) { - loopbackCopy = loopBackByteArray; - } - int16_t* loopbackSamples = reinterpret_cast(loopBackByteArray.data()); int numLoopbackSamples = loopBackByteArray.size() / sizeof(int16_t); updateGverbOptions(); - addReverb(loopbackSamples, numLoopbackSamples, _outputFormat); - - if (!hasEcho) { - int16_t* loopbackCopySamples = reinterpret_cast(loopbackCopy.data()); - for (int i = 0; i < numLoopbackSamples; ++i) { - loopbackSamples[i] = glm::clamp((int)loopbackSamples[i] - loopbackCopySamples[i], - MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); - } - } + addReverb(loopbackSamples, numLoopbackSamples, _outputFormat, !hasEcho); } if (_loopbackOutputDevice) { diff --git a/interface/src/Audio.h b/interface/src/Audio.h index d8e5c5386c..913524d8e5 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -269,7 +269,7 @@ private: // Adds Reverb void initGverb(); void updateGverbOptions(); - void addReverb(int16_t* samples, int numSamples, QAudioFormat& format); + void addReverb(int16_t* samples, int numSamples, QAudioFormat& format, bool noEcho = false); void handleLocalEchoAndReverb(QByteArray& inputByteArray); From a8c38aab64f5c30d3185be17021ec270b978c3da Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 17 Nov 2014 14:47:20 -0800 Subject: [PATCH 87/94] dryFraction factorisation --- interface/src/Audio.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 99039829e7..2eb751868e 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -567,7 +567,7 @@ void Audio::setReverbOptions(const AudioEffectOptions* options) { void Audio::addReverb(int16_t* samplesData, int numSamples, QAudioFormat& audioFormat, bool noEcho) { float wetFraction = DB_CO(_reverbOptions->getWetLevel()); - float dryFraction = 1.0f - wetFraction; + float dryFraction = (noEcho) ? 0.0f : (1.0f - wetFraction); float lValue,rValue; for (int sample = 0; sample < numSamples; sample += audioFormat.channelCount()) { @@ -579,14 +579,12 @@ void Audio::addReverb(int16_t* samplesData, int numSamples, QAudioFormat& audioF for (int j = sample; j < sample + audioFormat.channelCount(); j++) { if (j == sample) { // left channel - int lResult = glm::clamp((int)(samplesData[j] * ((noEcho) ? 0.0f : dryFraction) + - lValue * wetFraction), + int lResult = glm::clamp((int)(samplesData[j] * dryFraction + lValue * wetFraction), MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); samplesData[j] = (int16_t)lResult; } else if (j == (sample + 1)) { // right channel - int rResult = glm::clamp((int)(samplesData[j] * ((noEcho) ? 0.0f : dryFraction) + - rValue * wetFraction), + int rResult = glm::clamp((int)(samplesData[j] * dryFraction + rValue * wetFraction), MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); samplesData[j] = (int16_t)rResult; } else { From 1ac9f2f5633070f456ac73da2f64f6cc867e2065 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 17 Nov 2014 14:51:46 -0800 Subject: [PATCH 88/94] first cut at movable entities script --- examples/entityScripts/movable.js | 80 +++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 examples/entityScripts/movable.js diff --git a/examples/entityScripts/movable.js b/examples/entityScripts/movable.js new file mode 100644 index 0000000000..432a0be3f0 --- /dev/null +++ b/examples/entityScripts/movable.js @@ -0,0 +1,80 @@ +// +// movable.js +// examples/entityScripts +// +// Created by Brad Hefta-Gaub on 11/17/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 +// +(function(){ + + this.entityID = null; + this.properties = null; + this.graboffset = null; + + // Pr, Vr are respectively the Ray's Point of origin and Vector director + // Pp, Np are respectively the Plane's Point of origin and Normal vector + this.rayPlaneIntersection = function(Pr, Vr, Pp, Np) { + var d = -Vec3.dot(Pp, Np); + var t = -(Vec3.dot(Pr, Np) + d) / Vec3.dot(Vr, Np); + return Vec3.sum(Pr, Vec3.multiply(t, Vr)); + }; + + // updates the piece position based on mouse input + this.updatePosition = function(mouseEvent) { + var pickRay = Camera.computePickRay(mouseEvent.x, mouseEvent.y) + var upVector = { x: 0, y: 1, z: 0 }; + var intersection = this.rayPlaneIntersection(pickRay.origin, pickRay.direction, + this.properties.position, upVector); + + var newPosition = Vec3.sum(intersection, this.graboffset); + Entities.editEntity(this.entityID, { position: newPosition }); + }; + + this.grab = function(mouseEvent) { + // first calculate the offset + var pickRay = Camera.computePickRay(mouseEvent.x, mouseEvent.y) + var upVector = { x: 0, y: 1, z: 0 }; + var intersection = this.rayPlaneIntersection(pickRay.origin, pickRay.direction, + this.properties.position, upVector); + this.graboffset = Vec3.subtract(this.properties.position, intersection); + this.updatePosition(mouseEvent); + }; + + this.move = function(mouseEvent) { + this.updatePosition(mouseEvent); + }; + + this.release = function(mouseEvent) { + this.updatePosition(mouseEvent); + }; + + // All callbacks start by updating the properties + this.updateProperties = function(entityID) { + if (this.entityID === null || !this.entityID.isKnownID) { + this.entityID = Entities.identifyEntity(entityID); + } + this.properties = Entities.getEntityProperties(this.entityID); + }; + + this.preload = function(entityID) { + this.updateProperties(entityID); // All callbacks start by updating the properties + }; + + this.clickDownOnEntity = function(entityID, mouseEvent) { + this.updateProperties(entityID); // All callbacks start by updating the properties + this.grab(mouseEvent); + }; + + this.holdingClickOnEntity = function(entityID, mouseEvent) { + this.updateProperties(entityID); // All callbacks start by updating the properties + this.move(mouseEvent); + }; + this.clickReleaseOnEntity = function(entityID, mouseEvent) { + this.updateProperties(entityID); // All callbacks start by updating the properties + this.release(mouseEvent); + }; + +}) From 971804b98eeace4aad6f1fe0bbe859bedabac918 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 17 Nov 2014 16:14:49 -0800 Subject: [PATCH 89/94] name change shinkIfNeeded() -> shrinkIfNeeded() --- libraries/shared/src/PropertyFlags.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/shared/src/PropertyFlags.h b/libraries/shared/src/PropertyFlags.h index 7614ad7b7c..de05edc076 100644 --- a/libraries/shared/src/PropertyFlags.h +++ b/libraries/shared/src/PropertyFlags.h @@ -92,7 +92,7 @@ public: PropertyFlags operator<<(Enum flag) const; // NOTE: due to the nature of the compact storage of these property flags, and the fact that the upper bound of the - // enum is not know, these operators will only perform their bitwise operations on the set of properties that have + // enum is not known, these operators will only perform their bitwise operations on the set of properties that have // been previously set PropertyFlags& operator^=(const PropertyFlags& other); PropertyFlags& operator^=(Enum flag); @@ -106,7 +106,7 @@ public: private: - void shinkIfNeeded(); + void shrinkIfNeeded(); QBitArray _flags; int _maxFlag; @@ -142,7 +142,7 @@ template inline void PropertyFlags::setHasProperty(Enum fla _flags.setBit(flag, value); if (flag == _maxFlag && !value) { - shinkIfNeeded(); + shrinkIfNeeded(); } } @@ -274,27 +274,27 @@ template inline PropertyFlags& PropertyFlags::operato template inline PropertyFlags& PropertyFlags::operator&=(const PropertyFlags& other) { _flags &= other._flags; - shinkIfNeeded(); + shrinkIfNeeded(); return *this; } template inline PropertyFlags& PropertyFlags::operator&=(Enum flag) { PropertyFlags other(flag); _flags &= other._flags; - shinkIfNeeded(); + shrinkIfNeeded(); return *this; } template inline PropertyFlags& PropertyFlags::operator^=(const PropertyFlags& other) { _flags ^= other._flags; - shinkIfNeeded(); + shrinkIfNeeded(); return *this; } template inline PropertyFlags& PropertyFlags::operator^=(Enum flag) { PropertyFlags other(flag); _flags ^= other._flags; - shinkIfNeeded(); + shrinkIfNeeded(); return *this; } @@ -422,7 +422,7 @@ template inline PropertyFlags PropertyFlags::operator return result; } -template inline void PropertyFlags::shinkIfNeeded() { +template inline void PropertyFlags::shrinkIfNeeded() { int maxFlagWas = _maxFlag; while (_maxFlag >= 0) { if (_flags.testBit(_maxFlag)) { From 114364e37a11e0a9b221a6b76db2a13842ea82a1 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 17 Nov 2014 16:39:26 -0800 Subject: [PATCH 90/94] cleanup/optimization of Octree::readElementData() --- libraries/octree/src/Octree.cpp | 40 +++++++++++++-------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index e9cf1158fa..f13f832920 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -289,36 +289,26 @@ int Octree::readElementData(OctreeElement* destinationElement, const unsigned ch for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { // check the colors mask to see if we have a child to color in if (oneAtBit(colorInPacketMask, i)) { - // create the child if it doesn't exist - if (!destinationElement->getChildAtIndex(i)) { - destinationElement->addChildAtIndex(i); - if (destinationElement->isDirty()) { - _isDirty = true; - } - } + // addChildAtIndex() should actually be called getOrAddChildAtIndex(). + // When it adds the child it automatically sets the detinationElement dirty. + OctreeElement* childElementAt = destinationElement->addChildAtIndex(i); - OctreeElement* childElementAt = destinationElement->getChildAtIndex(i); - bool nodeIsDirty = false; - if (childElementAt) { + int childElementDataRead = childElementAt->readElementDataFromBuffer(nodeData + bytesRead, bytesLeftToRead, args); + childElementAt->setSourceUUID(args.sourceUUID); + + bytesRead += childElementDataRead; + bytesLeftToRead -= childElementDataRead; - int childElementDataRead = childElementAt->readElementDataFromBuffer(nodeData + bytesRead, bytesLeftToRead, args); - childElementAt->setSourceUUID(args.sourceUUID); - - bytesRead += childElementDataRead; - bytesLeftToRead -= childElementDataRead; - - // if we had a local version of the element already, it's possible that we have it already but - // with the same color data, so this won't count as a change. To address this we check the following - if (!childElementAt->isDirty() && childElementAt->getShouldRender() && !childElementAt->isRendered()) { - childElementAt->setDirtyBit(); // force dirty! - } - - nodeIsDirty = childElementAt->isDirty(); - } - if (nodeIsDirty) { + // It's possible that we already had this version of element data, in which case the unpacking of the data + // wouldn't flag childElementAt as dirty, so we manually flag it here... if the element is to be rendered. + if (childElementAt->getShouldRender() && !childElementAt->isRendered()) { + childElementAt->setDirtyBit(); // force dirty! _isDirty = true; } } + if (destinationElement->isDirty()) { + _isDirty = true; + } } unsigned char childrenInTreeMask = ALL_CHILDREN_ASSUMED_TO_EXIST; From 5eac93dcfd72cff6ba7e6cfb14d656e6c6da4c27 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 17 Nov 2014 16:59:23 -0800 Subject: [PATCH 91/94] User separate gverb instance for local reverb --- interface/src/Audio.cpp | 22 +++++++++++++++++----- interface/src/Audio.h | 3 ++- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 2eb751868e..b7076b6c1a 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -99,6 +99,7 @@ Audio::Audio(QObject* parent) : _muted(false), _reverb(false), _reverbOptions(&_scriptReverbOptions), + _gverbLocal(NULL), _gverb(NULL), _iconColor(1.0f), _iconPulseTimeReference(usecTimestampNow()), @@ -504,12 +505,23 @@ bool Audio::switchOutputToAudioDevice(const QString& outputDeviceName) { void Audio::initGverb() { // Initialize a new gverb instance + _gverbLocal = gverb_new(_outputFormat.sampleRate(), _reverbOptions->getMaxRoomSize(), _reverbOptions->getRoomSize(), + _reverbOptions->getReverbTime(), _reverbOptions->getDamping(), _reverbOptions->getSpread(), + _reverbOptions->getInputBandwidth(), _reverbOptions->getEarlyLevel(), + _reverbOptions->getTailLevel()); _gverb = gverb_new(_outputFormat.sampleRate(), _reverbOptions->getMaxRoomSize(), _reverbOptions->getRoomSize(), _reverbOptions->getReverbTime(), _reverbOptions->getDamping(), _reverbOptions->getSpread(), _reverbOptions->getInputBandwidth(), _reverbOptions->getEarlyLevel(), _reverbOptions->getTailLevel()); - + // Configure the instance (these functions are not super well named - they actually set several internal variables) + gverb_set_roomsize(_gverbLocal, _reverbOptions->getRoomSize()); + gverb_set_revtime(_gverbLocal, _reverbOptions->getReverbTime()); + gverb_set_damping(_gverbLocal, _reverbOptions->getDamping()); + gverb_set_inputbandwidth(_gverbLocal, _reverbOptions->getInputBandwidth()); + gverb_set_earlylevel(_gverbLocal, DB_CO(_reverbOptions->getEarlyLevel())); + gverb_set_taillevel(_gverbLocal, DB_CO(_reverbOptions->getTailLevel())); + gverb_set_roomsize(_gverb, _reverbOptions->getRoomSize()); gverb_set_revtime(_gverb, _reverbOptions->getReverbTime()); gverb_set_damping(_gverb, _reverbOptions->getDamping()); @@ -565,7 +577,7 @@ void Audio::setReverbOptions(const AudioEffectOptions* options) { } } -void Audio::addReverb(int16_t* samplesData, int numSamples, QAudioFormat& audioFormat, bool noEcho) { +void Audio::addReverb(ty_gverb* gverb, int16_t* samplesData, int numSamples, QAudioFormat& audioFormat, bool noEcho) { float wetFraction = DB_CO(_reverbOptions->getWetLevel()); float dryFraction = (noEcho) ? 0.0f : (1.0f - wetFraction); @@ -573,7 +585,7 @@ void Audio::addReverb(int16_t* samplesData, int numSamples, QAudioFormat& audioF for (int sample = 0; sample < numSamples; sample += audioFormat.channelCount()) { // Run GVerb float value = (float)samplesData[sample]; - gverb_do(_gverb, value, &lValue, &rValue); + gverb_do(gverb, value, &lValue, &rValue); // Mix, accounting for clipping, the left and right channels. Ignore the rest. for (int j = sample; j < sample + audioFormat.channelCount(); j++) { @@ -627,7 +639,7 @@ void Audio::handleLocalEchoAndReverb(QByteArray& inputByteArray) { int16_t* loopbackSamples = reinterpret_cast(loopBackByteArray.data()); int numLoopbackSamples = loopBackByteArray.size() / sizeof(int16_t); updateGverbOptions(); - addReverb(loopbackSamples, numLoopbackSamples, _outputFormat, !hasEcho); + addReverb(_gverbLocal, loopbackSamples, numLoopbackSamples, _outputFormat, !hasEcho); } if (_loopbackOutputDevice) { @@ -1018,7 +1030,7 @@ void Audio::processReceivedSamples(const QByteArray& inputBuffer, QByteArray& ou if(_reverb || _receivedAudioStream.hasReverb()) { updateGverbOptions(); - addReverb((int16_t*)outputBuffer.data(), numDeviceOutputSamples, _outputFormat); + addReverb(_gverb, (int16_t*)outputBuffer.data(), numDeviceOutputSamples, _outputFormat); } } diff --git a/interface/src/Audio.h b/interface/src/Audio.h index 913524d8e5..127c2e3332 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -248,6 +248,7 @@ private: AudioEffectOptions _scriptReverbOptions; AudioEffectOptions _zoneReverbOptions; AudioEffectOptions* _reverbOptions; + ty_gverb* _gverbLocal; ty_gverb* _gverb; GLuint _micTextureId; GLuint _muteTextureId; @@ -269,7 +270,7 @@ private: // Adds Reverb void initGverb(); void updateGverbOptions(); - void addReverb(int16_t* samples, int numSamples, QAudioFormat& format, bool noEcho = false); + void addReverb(ty_gverb* gverb, int16_t* samples, int numSamples, QAudioFormat& format, bool noEcho = false); void handleLocalEchoAndReverb(QByteArray& inputByteArray); From af606f01a9418fb76975aaae890e61e8022a47c7 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 17 Nov 2014 17:35:44 -0800 Subject: [PATCH 92/94] combined SimulationStates Moving and Changing also funnel entity updates by UDP packet through a single list --- .../entities/RenderableModelEntityItem.cpp | 3 +- libraries/entities/src/BoxEntityItem.cpp | 2 +- libraries/entities/src/EntityItem.cpp | 11 +- libraries/entities/src/EntityItem.h | 17 +- libraries/entities/src/EntityTree.cpp | 178 ++++++------------ libraries/entities/src/EntityTree.h | 17 +- libraries/entities/src/EntityTreeElement.cpp | 11 +- libraries/entities/src/ModelEntityItem.cpp | 6 +- libraries/entities/src/ModelEntityItem.h | 2 +- 9 files changed, 95 insertions(+), 152 deletions(-) diff --git a/interface/src/entities/RenderableModelEntityItem.cpp b/interface/src/entities/RenderableModelEntityItem.cpp index 8d932b121d..7b2856bb18 100644 --- a/interface/src/entities/RenderableModelEntityItem.cpp +++ b/interface/src/entities/RenderableModelEntityItem.cpp @@ -246,8 +246,7 @@ Model* RenderableModelEntityItem::getModel(EntityTreeRenderer* renderer) { } bool RenderableModelEntityItem::needsSimulation() const { - SimulationState simulationState = getSimulationState(); - return _needsInitialSimulation || simulationState == Moving || simulationState == Changing; + return _needsInitialSimulation || getSimulationState() == EntityItem::Moving; } EntityItemProperties RenderableModelEntityItem::getProperties() const { diff --git a/libraries/entities/src/BoxEntityItem.cpp b/libraries/entities/src/BoxEntityItem.cpp index 83d6d7eff9..16204f0c16 100644 --- a/libraries/entities/src/BoxEntityItem.cpp +++ b/libraries/entities/src/BoxEntityItem.cpp @@ -94,4 +94,4 @@ void BoxEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitst bool successPropertyFits = true; APPEND_ENTITY_PROPERTY(PROP_COLOR, appendColor, getColor()); -} \ No newline at end of file +} diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index d5790d88a7..d0fafa06b1 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -92,6 +92,7 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) { _created = 0; _changedOnServer = 0; initFromEntityItemID(entityItemID); + _simulationState = EntityItem::Static; } EntityItem::EntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) { @@ -104,6 +105,7 @@ EntityItem::EntityItem(const EntityItemID& entityItemID, const EntityItemPropert _changedOnServer = 0; initFromEntityItemID(entityItemID); setProperties(properties, true); // force copy + _simulationState = EntityItem::Static; } EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& params) const { @@ -404,7 +406,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef qDebug() << " fromSameServerEdit=" << fromSameServerEdit; } - bool ignoreServerPacket = false; // assume we're use this server packet + bool ignoreServerPacket = false; // assume we'll use this server packet // If this packet is from the same server edit as the last packet we accepted from the server // we probably want to use it. @@ -715,13 +717,10 @@ void EntityItem::update(const quint64& updateTime) { } } -EntityItem::SimulationState EntityItem::getSimulationState() const { - if (hasVelocity() || (hasGravity() && !isRestingOnSurface())) { +EntityItem::SimulationState EntityItem::computeSimulationState() const { + if (hasVelocity() || (hasGravity() && !isRestingOnSurface()) || hasAngularVelocity()) { return EntityItem::Moving; } - if (hasAngularVelocity()) { - return EntityItem::Changing; - } if (isMortal()) { return EntityItem::Mortal; } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index cb153dee60..61e929d9b3 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -28,6 +28,7 @@ #include "EntityItemProperties.h" #include "EntityTypes.h" +class EntityTree; class EntityTreeElement; class EntityTreeElementExtraEncodeData; @@ -59,10 +60,10 @@ public: // methods for getting/setting all properties of an entity virtual EntityItemProperties getProperties() const; - /// returns true is something changed + /// returns true if something changed virtual bool setProperties(const EntityItemProperties& properties, bool forceCopy = false); - /// override this in your derived class if you'd like to be informed when something about the state of the entity + /// Override this in your derived class if you'd like to be informed when something about the state of the entity /// has changed. This will be called with properties change or when new data is loaded from a stream virtual void somethingChangedNotification() { } @@ -115,11 +116,13 @@ public: typedef enum SimulationState_t { Static, Mortal, - Changing, Moving } SimulationState; - virtual SimulationState getSimulationState() const; + // computes the SimulationState that the entity SHOULD be in. + // Use getSimulationState() to find the state under which it is currently categorized. + virtual SimulationState computeSimulationState() const; + virtual void debugDump() const; // similar to assignment/copy, but it handles keeping lifetime accurate @@ -262,8 +265,13 @@ public: void applyHardCollision(const CollisionInfo& collisionInfo); virtual const Shape& getCollisionShapeInMeters() const { return _collisionShape; } virtual bool contains(const glm::vec3& point) const { return getAABox().contains(point); } + + SimulationState getSimulationState() const { return _simulationState; } protected: + friend EntityTree; + void setSimulationState(SimulationState state) { _simulationState = state; } + virtual void initFromEntityItemID(const EntityItemID& entityItemID); // maybe useful to allow subclasses to init virtual void recalculateCollisionShape(); @@ -305,6 +313,7 @@ protected: void setRadius(float value); AACubeShape _collisionShape; + SimulationState _simulationState; // only set by EntityTree }; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 73957ad077..53d040c4a8 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -40,8 +40,8 @@ void EntityTree::eraseAllOctreeElements(bool createNewRoot) { _entityToElementMap.clear(); Octree::eraseAllOctreeElements(createNewRoot); _movingEntities.clear(); - _changingEntities.clear(); _mortalEntities.clear(); + _changedEntities.clear(); } bool EntityTree::handlesEditPacketType(PacketType packetType) const { @@ -80,7 +80,7 @@ void EntityTree::addEntityItem(EntityItem* entityItem) { EntityItemID entityID = entityItem->getEntityItemID(); EntityTreeElement* containingElement = getContainingElement(entityID); if (containingElement) { - qDebug() << "UNEXPECTED!!!! don't call addEntityItem() on existing entity items. entityID=" << entityID; + qDebug() << "UNEXPECTED!!!! don't call addEntityItem() on existing EntityItems. entityID=" << entityID; return; } @@ -89,7 +89,7 @@ void EntityTree::addEntityItem(EntityItem* entityItem) { recurseTreeWithOperator(&theOperator); // check to see if we need to simulate this entity.. - changeEntityState(entityItem, EntityItem::Static, entityItem->getSimulationState()); + changeEntityState(entityItem); _isDirty = true; } @@ -123,15 +123,13 @@ bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProp } } else { // check to see if we need to simulate this entity... - EntityItem::SimulationState oldState = existingEntity->getSimulationState(); QString entityScriptBefore = existingEntity->getScript(); UpdateEntityOperator theOperator(this, containingElement, existingEntity, properties); recurseTreeWithOperator(&theOperator); _isDirty = true; - EntityItem::SimulationState newState = existingEntity->getSimulationState(); - changeEntityState(existingEntity, oldState, newState); + changeEntityState(existingEntity); QString entityScriptAfter = existingEntity->getScript(); if (entityScriptBefore != entityScriptAfter) { @@ -229,10 +227,6 @@ void EntityTree::removeEntityFromSimulationLists(const EntityItemID& entityID) { // make sure to remove it from any of our simulation lists EntityItem::SimulationState theState = theEntity->getSimulationState(); switch (theState) { - case EntityItem::Changing: - _changingEntities.removeAll(theEntity); - break; - case EntityItem::Moving: _movingEntities.removeAll(theEntity); break; @@ -244,6 +238,7 @@ void EntityTree::removeEntityFromSimulationLists(const EntityItemID& entityID) { default: break; } + _changedEntities.remove(theEntity); } } @@ -518,7 +513,7 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char // search for the entity by EntityItemID EntityItem* existingEntity = findEntityByEntityItemID(entityItemID); - // if the entityItem exists, then update it + // if the EntityItem exists, then update it if (existingEntity) { updateEntity(entityItemID, properties); existingEntity->markAsChangedOnServer(); @@ -580,15 +575,42 @@ void EntityTree::releaseSceneEncodeData(OctreeElementExtraEncodeData* extraEncod extraEncodeData->clear(); } -void EntityTree::changeEntityState(EntityItem* const entity, - EntityItem::SimulationState oldState, EntityItem::SimulationState newState) { +void EntityTree::changeEntityState(EntityItem* entity) { + EntityItem::SimulationState oldState = entity->getSimulationState(); + EntityItem::SimulationState newState = entity->computeSimulationState(); + if (newState != oldState) { + switch (oldState) { + case EntityItem::Moving: + _movingEntities.removeAll(entity); + break; + + case EntityItem::Mortal: + _mortalEntities.removeAll(entity); + break; + + default: + break; + } + + switch (newState) { + case EntityItem::Moving: + _movingEntities.push_back(entity); + break; + + case EntityItem::Mortal: + _mortalEntities.push_back(entity); + break; + + default: + break; + } + entity->setSimulationState(newState); + } +} - // TODO: can we short circuit this if the state isn't changing? +void EntityTree::clearEntityState(EntityItem* entity) { + EntityItem::SimulationState oldState = entity->getSimulationState(); switch (oldState) { - case EntityItem::Changing: - _changingEntities.removeAll(entity); - break; - case EntityItem::Moving: _movingEntities.removeAll(entity); break; @@ -600,24 +622,11 @@ void EntityTree::changeEntityState(EntityItem* const entity, default: break; } + entity->setSimulationState(EntityItem::Static); +} - - switch (newState) { - case EntityItem::Changing: - _changingEntities.push_back(entity); - break; - - case EntityItem::Moving: - _movingEntities.push_back(entity); - break; - - case EntityItem::Mortal: - _mortalEntities.push_back(entity); - break; - - default: - break; - } +void EntityTree::entityChanged(EntityItem* entity) { + _changedEntities.insert(entity); } void EntityTree::update() { @@ -633,7 +642,7 @@ void EntityTree::update() { lockForWrite(); quint64 now = usecTimestampNow(); QSet entitiesToDelete; - updateChangingEntities(now, entitiesToDelete); + updateChangedEntities(now, entitiesToDelete); updateMovingEntities(now, entitiesToDelete); updateMortalEntities(now, entitiesToDelete); @@ -643,55 +652,25 @@ void EntityTree::update() { unlock(); } -void EntityTree::updateChangingEntities(quint64 now, QSet& entitiesToDelete) { - QSet entitiesBecomingStatic; - QSet entitiesBecomingMortal; - QSet entitiesBecomingMoving; - +void EntityTree::updateChangedEntities(quint64 now, QSet& entitiesToDelete) { // TODO: switch these to iterators so we can remove items that get deleted - for (int i = 0; i < _changingEntities.size(); i++) { - EntityItem* thisEntity = _changingEntities[i]; - thisEntity->update(now); - // always check to see if the lifetime has expired, for immortal entities this is always false + foreach (EntityItem* thisEntity, _changedEntities) { + // check to see if the lifetime has expired, for immortal entities this is always false if (thisEntity->lifetimeHasExpired()) { - qDebug() << "Lifetime has expired for entity:" << thisEntity->getEntityItemID(); + qDebug() << "Lifetime has expired for thisEntity:" << thisEntity->getEntityItemID(); entitiesToDelete << thisEntity->getEntityItemID(); - entitiesBecomingStatic << thisEntity; + clearEntityState(thisEntity); } else { - // check to see if this entity is no longer moving - EntityItem::SimulationState newState = thisEntity->getSimulationState(); - - if (newState == EntityItem::Static) { - entitiesBecomingStatic << thisEntity; - } else if (newState == EntityItem::Mortal) { - entitiesBecomingMortal << thisEntity; - } else if (newState == EntityItem::Moving) { - entitiesBecomingMoving << thisEntity; - } + changeEntityState(thisEntity); } } - - // change state for any entities that were changing but are now either static, mortal, or moving - foreach(EntityItem* entity, entitiesBecomingStatic) { - changeEntityState(entity, EntityItem::Changing, EntityItem::Static); - } - foreach(EntityItem* entity, entitiesBecomingMortal) { - changeEntityState(entity, EntityItem::Changing, EntityItem::Mortal); - } - foreach(EntityItem* entity, entitiesBecomingMoving) { - changeEntityState(entity, EntityItem::Changing, EntityItem::Moving); - } + _changedEntities.clear(); } void EntityTree::updateMovingEntities(quint64 now, QSet& entitiesToDelete) { PerformanceTimer perfTimer("updateMovingEntities"); if (_movingEntities.size() > 0) { MovingEntitiesOperator moveOperator(this); - - QSet entitiesBecomingStatic; - QSet entitiesBecomingMortal; - QSet entitiesBecomingChanging; - { PerformanceTimer perfTimer("_movingEntities"); @@ -703,7 +682,7 @@ void EntityTree::updateMovingEntities(quint64 now, QSet& entitiesT if (thisEntity->lifetimeHasExpired()) { qDebug() << "Lifetime has expired for entity:" << thisEntity->getEntityItemID(); entitiesToDelete << thisEntity->getEntityItemID(); - entitiesBecomingStatic << thisEntity; + clearEntityState(thisEntity); } else { AACube oldCube = thisEntity->getMaximumAACube(); thisEntity->update(now); @@ -714,19 +693,10 @@ void EntityTree::updateMovingEntities(quint64 now, QSet& entitiesT if (!domainBounds.touches(newCube)) { qDebug() << "Entity " << thisEntity->getEntityItemID() << " moved out of domain bounds."; entitiesToDelete << thisEntity->getEntityItemID(); - entitiesBecomingStatic << thisEntity; + clearEntityState(thisEntity); } else { moveOperator.addEntityToMoveList(thisEntity, oldCube, newCube); - - // check to see if this entity is no longer moving - EntityItem::SimulationState newState = thisEntity->getSimulationState(); - if (newState == EntityItem::Changing) { - entitiesBecomingChanging << thisEntity; - } else if (newState == EntityItem::Mortal) { - entitiesBecomingMortal << thisEntity; - } else if (newState == EntityItem::Static) { - entitiesBecomingStatic << thisEntity; - } + changeEntityState(thisEntity); } } } @@ -735,25 +705,10 @@ void EntityTree::updateMovingEntities(quint64 now, QSet& entitiesT PerformanceTimer perfTimer("recurseTreeWithOperator"); recurseTreeWithOperator(&moveOperator); } - - // change state for any entities that were moving but are now either static, mortal, or changing - foreach(EntityItem* entity, entitiesBecomingStatic) { - changeEntityState(entity, EntityItem::Moving, EntityItem::Static); - } - foreach(EntityItem* entity, entitiesBecomingMortal) { - changeEntityState(entity, EntityItem::Moving, EntityItem::Mortal); - } - foreach(EntityItem* entity, entitiesBecomingChanging) { - changeEntityState(entity, EntityItem::Moving, EntityItem::Changing); - } } } void EntityTree::updateMortalEntities(quint64 now, QSet& entitiesToDelete) { - QSet entitiesBecomingStatic; - QSet entitiesBecomingChanging; - QSet entitiesBecomingMoving; - // TODO: switch these to iterators so we can remove items that get deleted for (int i = 0; i < _mortalEntities.size(); i++) { EntityItem* thisEntity = _mortalEntities[i]; @@ -762,31 +717,12 @@ void EntityTree::updateMortalEntities(quint64 now, QSet& entitiesT if (thisEntity->lifetimeHasExpired()) { qDebug() << "Lifetime has expired for entity:" << thisEntity->getEntityItemID(); entitiesToDelete << thisEntity->getEntityItemID(); - entitiesBecomingStatic << thisEntity; + clearEntityState(thisEntity); } else { // check to see if this entity is no longer moving - EntityItem::SimulationState newState = thisEntity->getSimulationState(); - - if (newState == EntityItem::Static) { - entitiesBecomingStatic << thisEntity; - } else if (newState == EntityItem::Changing) { - entitiesBecomingChanging << thisEntity; - } else if (newState == EntityItem::Moving) { - entitiesBecomingMoving << thisEntity; - } + changeEntityState(thisEntity); } } - - // change state for any entities that were mortal but are now either static, changing, or moving - foreach(EntityItem* entity, entitiesBecomingStatic) { - changeEntityState(entity, EntityItem::Mortal, EntityItem::Static); - } - foreach(EntityItem* entity, entitiesBecomingChanging) { - changeEntityState(entity, EntityItem::Mortal, EntityItem::Changing); - } - foreach(EntityItem* entity, entitiesBecomingMoving) { - changeEntityState(entity, EntityItem::Mortal, EntityItem::Moving); - } } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 6fe2d256c2..bf9da5a15d 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -12,6 +12,8 @@ #ifndef hifi_EntityTree_h #define hifi_EntityTree_h +#include + #include #include "EntityTreeElement.h" @@ -135,8 +137,10 @@ public: void sendEntities(EntityEditPacketSender* packetSender, EntityTree* localTree, float x, float y, float z); - void changeEntityState(EntityItem* const entity, - EntityItem::SimulationState oldState, EntityItem::SimulationState newState); + void changeEntityState(EntityItem* entity); + void clearEntityState(EntityItem* entity); + + void entityChanged(EntityItem* entity); void trackDeletedEntity(const EntityItemID& entityID); @@ -153,7 +157,7 @@ signals: private: - void updateChangingEntities(quint64 now, QSet& entitiesToDelete); + void updateChangedEntities(quint64 now, QSet& entitiesToDelete); void updateMovingEntities(quint64 now, QSet& entitiesToDelete); void updateMortalEntities(quint64 now, QSet& entitiesToDelete); @@ -173,9 +177,10 @@ private: QHash _entityToElementMap; - QList _movingEntities; // entities that are moving as part of update - QList _changingEntities; // entities that are changing (like animating), but not moving - QList _mortalEntities; // entities that are mortal (have lifetime), but not moving or changing + QList _movingEntities; // entities that need to be updated + QList _mortalEntities; // entities that need to be checked for expiry + + QSet _changedEntities; // entities that have changed in the last frame }; #endif // hifi_EntityTree_h diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index 1dea2bcd85..a461df5fde 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -737,14 +737,10 @@ int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int QString entityScriptBefore = entityItem->getScript(); bool bestFitBefore = bestFitEntityBounds(entityItem); EntityTreeElement* currentContainingElement = _myTree->getContainingElement(entityItemID); - EntityItem::SimulationState oldState = entityItem->getSimulationState(); bytesForThisEntity = entityItem->readEntityDataFromBuffer(dataAt, bytesLeftToRead, args); - - EntityItem::SimulationState newState = entityItem->getSimulationState(); - if (oldState != newState) { - _myTree->changeEntityState(entityItem, oldState, newState); - } + // TODO: Andrew to only set changed if something has actually changed + _myTree->entityChanged(entityItem); bool bestFitAfter = bestFitEntityBounds(entityItem); if (bestFitBefore != bestFitAfter) { @@ -771,9 +767,8 @@ int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int addEntityItem(entityItem); // add this new entity to this elements entities entityItemID = entityItem->getEntityItemID(); _myTree->setContainingElement(entityItemID, this); + _myTree->changeEntityState(entityItem); _myTree->emitAddingEntity(entityItemID); // we just added an entity - EntityItem::SimulationState newState = entityItem->getSimulationState(); - _myTree->changeEntityState(entityItem, EntityItem::Static, newState); } } // Move the buffer forward to read more entities diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index f50fe7866b..31a0c57f5b 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -371,15 +371,15 @@ bool ModelEntityItem::isAnimatingSomething() const { !getAnimationURL().isEmpty(); } -EntityItem::SimulationState ModelEntityItem::getSimulationState() const { - EntityItem::SimulationState baseClassState = EntityItem::getSimulationState(); +EntityItem::SimulationState ModelEntityItem::computeSimulationState() const { + EntityItem::SimulationState baseClassState = EntityItem::computeSimulationState(); // if the base class is static, then consider our animation state, and upgrade to changing if // we are animating. If the base class has a higher simulation state than static, then // use the base class state. if (baseClassState == EntityItem::Static) { if (isAnimatingSomething()) { - return EntityItem::Changing; + return EntityItem::Moving; } } return baseClassState; diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 97ffed4076..0b2508ec80 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -46,7 +46,7 @@ public: EntityPropertyFlags& propertyFlags, bool overwriteLocalData); virtual void update(const quint64& now); - virtual SimulationState getSimulationState() const; + virtual SimulationState computeSimulationState() const; virtual void debugDump() const; From 47615ba9c221ea575eba6a3ee2bbff0703766963 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 17 Nov 2014 17:38:26 -0800 Subject: [PATCH 93/94] changeEntityState() --> updateEntityState() --- libraries/entities/src/EntityTree.cpp | 12 ++++++------ libraries/entities/src/EntityTree.h | 2 +- libraries/entities/src/EntityTreeElement.cpp | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 53d040c4a8..a0b2d6f9c3 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -89,7 +89,7 @@ void EntityTree::addEntityItem(EntityItem* entityItem) { recurseTreeWithOperator(&theOperator); // check to see if we need to simulate this entity.. - changeEntityState(entityItem); + updateEntityState(entityItem); _isDirty = true; } @@ -129,7 +129,7 @@ bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProp recurseTreeWithOperator(&theOperator); _isDirty = true; - changeEntityState(existingEntity); + updateEntityState(existingEntity); QString entityScriptAfter = existingEntity->getScript(); if (entityScriptBefore != entityScriptAfter) { @@ -575,7 +575,7 @@ void EntityTree::releaseSceneEncodeData(OctreeElementExtraEncodeData* extraEncod extraEncodeData->clear(); } -void EntityTree::changeEntityState(EntityItem* entity) { +void EntityTree::updateEntityState(EntityItem* entity) { EntityItem::SimulationState oldState = entity->getSimulationState(); EntityItem::SimulationState newState = entity->computeSimulationState(); if (newState != oldState) { @@ -661,7 +661,7 @@ void EntityTree::updateChangedEntities(quint64 now, QSet& entities entitiesToDelete << thisEntity->getEntityItemID(); clearEntityState(thisEntity); } else { - changeEntityState(thisEntity); + updateEntityState(thisEntity); } } _changedEntities.clear(); @@ -696,7 +696,7 @@ void EntityTree::updateMovingEntities(quint64 now, QSet& entitiesT clearEntityState(thisEntity); } else { moveOperator.addEntityToMoveList(thisEntity, oldCube, newCube); - changeEntityState(thisEntity); + updateEntityState(thisEntity); } } } @@ -720,7 +720,7 @@ void EntityTree::updateMortalEntities(quint64 now, QSet& entitiesT clearEntityState(thisEntity); } else { // check to see if this entity is no longer moving - changeEntityState(thisEntity); + updateEntityState(thisEntity); } } } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index bf9da5a15d..7370ebadc6 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -137,7 +137,7 @@ public: void sendEntities(EntityEditPacketSender* packetSender, EntityTree* localTree, float x, float y, float z); - void changeEntityState(EntityItem* entity); + void updateEntityState(EntityItem* entity); void clearEntityState(EntityItem* entity); void entityChanged(EntityItem* entity); diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index a461df5fde..7d4d95bf94 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -767,7 +767,7 @@ int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int addEntityItem(entityItem); // add this new entity to this elements entities entityItemID = entityItem->getEntityItemID(); _myTree->setContainingElement(entityItemID, this); - _myTree->changeEntityState(entityItem); + _myTree->updateEntityState(entityItem); _myTree->emitAddingEntity(entityItemID); // we just added an entity } } From 27614092700e6039562afb4fd4639a413b3873bb Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 18 Nov 2014 08:55:01 -0800 Subject: [PATCH 94/94] fix build error on linux --- libraries/entities/src/EntityItem.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 61e929d9b3..d57f547cc5 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -269,7 +269,7 @@ public: SimulationState getSimulationState() const { return _simulationState; } protected: - friend EntityTree; + friend class EntityTree; void setSimulationState(SimulationState state) { _simulationState = state; } virtual void initFromEntityItemID(const EntityItemID& entityItemID); // maybe useful to allow subclasses to init