Add hue, saturation and brightness dynamic brushes.

Add continuous drawing mode.
Add new brushes.
Remove some brushes.
Fix animation play distance for when painting in Desktop mode.
Fix Hue animation not starting from the chosen color (would always start
from red).
Fix multiple color polyline.
This commit is contained in:
Artur Gomes 2017-08-04 17:54:43 +01:00
parent 678dd5fbae
commit 83cdd1739d
27 changed files with 751 additions and 504 deletions

View file

@ -127,16 +127,21 @@ _numVertices(0)
gpu::Stream::FormatPointer RenderablePolyLineEntityItem::_format;
void RenderablePolyLineEntityItem::createStreamFormat() {
static const int NORMAL_OFFSET = 12;
static const int TEXTURE_OFFSET = 24;
struct Vertex {
glm::vec3 pos;
glm::vec2 textCoord;
glm::vec3 color;
glm::vec3 normal;
};
_format.reset(new gpu::Stream::Format());
_format->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
_format->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), NORMAL_OFFSET);
_format->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), TEXTURE_OFFSET);
_format->setAttribute(gpu::Stream::COLOR, 0, gpu::Element(gpu::VEC3, gpu::UINT8, gpu::RGB), 0);
_format->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), offsetof(Vertex, pos));
_format->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), offsetof(Vertex, textCoord));
_format->setAttribute(gpu::Stream::COLOR, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB), offsetof(Vertex, color));
_format->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), offsetof(Vertex, normal));
}
void RenderablePolyLineEntityItem::updateGeometry() {
_numVertices = 0;
_verticesBuffer.reset(new gpu::Buffer());
@ -179,37 +184,26 @@ void RenderablePolyLineEntityItem::updateGeometry() {
accumulatedDistance += distanceToLastPoint;
}
vec3 color = _strokeColors.size() == _normals.size() ? _strokeColors.at(i) : toGlm(getXColor());
uv = vec2(uCoord, vCoord);
_verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_vertices.at(vertexIndex));
_verticesBuffer->append(sizeof(glm::vec2), (const gpu::Byte*)&uv);
_verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&color);
_verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_normals.at(i));
_verticesBuffer->append(sizeof(glm::vec2), (gpu::Byte*)&uv);
_strokeColors.size() > i
? _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_strokeColors.at(i))
: _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&toGlm(getXColor()));
vertexIndex++;
uv.y = 1.0f;
_verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_vertices.at(vertexIndex));
_verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_normals.at(i));
_verticesBuffer->append(sizeof(glm::vec2), (const gpu::Byte*)&uv);
_strokeColors.size() > i
? _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_strokeColors.at(i))
: _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&toGlm(getXColor()));
_verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&color);
_verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_normals.at(i));
vertexIndex++;
_numVertices += 2;
uCoord += uCoordInc;
/*
if (!_isUVModeStretch) {
if (i % 2 == 0) {
uCoord = 1.0f;
} else {
uCoord = 0.0f;
}
}
*/
}
_pointsChanged = false;

View file

@ -40,7 +40,7 @@ void main(void) {
packDeferredFragmentTranslucent(
interpolatedNormal * frontCondition,
texel.a * varColor.a,
polyline.color * texel.rgb,
color * texel.rgb,
vec3(0.01, 0.01, 0.01),
10.0);
}

View file

@ -40,7 +40,7 @@ _strokeColorsChanged(true),
_strokeWidthsChanged(true),
_points(QVector<glm::vec3>(0.0f)),
_normals(QVector<glm::vec3>(0.0f)),
_strokeColors(QVector<glm::vec3>(0.0f)),
_strokeColors(QVector<glm::vec3>(1.0f)),
_strokeWidths(QVector<float>(0.0f)),
_textures(""),
_isUVModeStretch(true)

View file

@ -0,0 +1,76 @@
//converts hsv color into rgb color space, expects hsv with the following ranges
//H(0, 359), S(0, 1), V(0, 1) to R(0, 255), G(0, 255), B(0, 255)
hsv2rgb = function (hsvColor) {
var c = hsvColor.value * hsvColor.saturation;
var x = c * (1 - Math.abs((hsvColor.hue/60) % 2 - 1));
var m = hsvColor.value - c;
var rgbColor = new Object();
if (hsvColor.hue >= 0 && hsvColor.hue < 60) {
rgbColor.red = Math.ceil((c + m) * 255);
rgbColor.green = Math.ceil((x + m) * 255);
rgbColor.blue = Math.ceil((0 + m) * 255);
} else if (hsvColor.hue >= 60 && hsvColor.hue < 120) {
rgbColor.red = Math.ceil((x + m) * 255);
rgbColor.green = Math.ceil((c + m) * 255);
rgbColor.blue = Math.ceil((0 + m) * 255);
} else if (hsvColor.hue >= 120 && hsvColor.hue < 180) {
rgbColor.red = Math.ceil((0 + m) * 255);
rgbColor.green = Math.ceil((c + m) * 255);
rgbColor.blue = Math.ceil((x + m) * 255);
} else if (hsvColor.hue >= 180 && hsvColor.hue < 240) {
rgbColor.red = Math.ceil((0 + m) * 255);
rgbColor.green = Math.ceil((x + m) * 255);
rgbColor.blue = Math.ceil((c + m) * 255);
} else if (hsvColor.hue >= 240 && hsvColor.hue < 300) {
rgbColor.red = Math.ceil((x + m) * 255);
rgbColor.green = Math.ceil((0 + m) * 255);
rgbColor.blue = Math.ceil((c + m) * 255);
} else if (hsvColor.hue >= 300 && hsvColor.hue < 360) {
rgbColor.red = Math.ceil((c + m) * 255);
rgbColor.green = Math.ceil((0 + m) * 255);
rgbColor.blue = Math.ceil((x + m) * 255);
}
return rgbColor;
}
//converts rgb color into hsv color space, expects rgb with the following ranges
//R(0, 255), G(0, 255), B(0, 255) to H(0, 359), S(0, 1), V(0, 1)
rgb2hsv = function (rgbColor) {
var r = rgbColor.red / 255.0;
var g = rgbColor.green / 255.0;
var b = rgbColor.blue / 255.0;
var cMax = Math.max(r, Math.max(g, b));
var cMin = Math.min(r, Math.min(g, b));
var deltaC = cMax - cMin;
var hsvColor = new Object();
//hue calculatio
if (deltaC == 0) {
hsvColor.hue = 0;
} else if (cMax == r) {
hsvColor.hue = 60 * (((g-b)/deltaC) % 6);
} else if (cMax == g) {
hsvColor.hue = 60 * (((b-r)/deltaC) + 2);
} else if (cMax == b) {
hsvColor.hue = 60 * (((r-g)/deltaC) + 4);
}
if (hsvColor.hue < 0) {
hsvColor.hue += 360;
}
//saturation calculation
if (cMax == 0) {
hsvColor.saturation = 0;
} else {
hsvColor.saturation = (deltaC/cMax);
}
hsvColor.value = (cMax);
return hsvColor;
}

View file

@ -1,5 +1,5 @@
//This file is just used for the superclass
function DynamicBrushClass() {}
function AnimatedBrushClass() {}
/**
* Called on every frame draw after the user stops painting
@ -9,29 +9,32 @@ function DynamicBrushClass() {}
* @param entityID: the id of the polyline being drawn
* @param fingerOverlayID: the id of the overlay that shows over the finger when using fingerpaint
*/
DynamicBrushClass.prototype.onUpdate = function(deltaSeconds, entityIDs) {
AnimatedBrushClass.prototype.onUpdate = function(deltaSeconds, entityID) {
//To be implemented on the child
throw "Abstract method onUpdate not implemented";
}
/**
* This function updates the user data so in the next frame the animation gets the previous values.
*
* This function updates the user data so in the next frame the animation gets the previous values.\
*
* @param entityID: the id of the polyline being animated
* @param dynamicBrushObject: the animation object (should be a subclass of dynamicBrush)
* @param animatedBrushObject: the animation object (should be a subclass of animatedBrush)
*/
DynamicBrushClass.prototype.updateUserData = function(entityID, dynamicBrushObject) {
//print("Saving class " + dynamicBrushObject.NAME);
AnimatedBrushClass.prototype.updateUserData = function(entityID, animatedBrushObject) {
//print("Saving class " + animatedBrushObject.NAME);
var prevUserData = Entities.getEntityProperties(entityID).userData;
if (prevUserData) {
print("saving on parent: " + JSON.stringify(animatedBrushObject));
prevUserData = prevUserData == "" ? new Object() : JSON.parse(prevUserData); //preserve other possible user data
if (prevUserData.animations != null && prevUserData.animations[dynamicBrushObject.NAME] != null) {
delete prevUserData.animations[dynamicBrushObject.NAME];
prevUserData.animations[dynamicBrushObject.NAME] = dynamicBrushObject;
if (prevUserData.animations != null && prevUserData.animations[animatedBrushObject.NAME] != null) {
delete prevUserData.animations[animatedBrushObject.NAME];
prevUserData.animations[animatedBrushObject.NAME] = animatedBrushObject;
}
prevUserData.timeFromLastAnimation = Date.now();
Entities.editEntity(entityID, {userData: JSON.stringify(prevUserData)});
print(JSON.stringify(Entities.getEntityProperties(entityID)));
}
}
DynamicBrush = DynamicBrushClass;
AnimatedBrush = AnimatedBrushClass;

View file

@ -1,18 +1,19 @@
(function() {
Script.include("dynamicBrushesList.js");
Script.include("animatedBrushesList.js");
var UPDATE_TIME = 33; //run at aproximatelly 30fps
var MIN_PLAY_DISTANCE = 6; //Minimum distance from player to entity in order to play animation
var self = this;
this.preload = function(entityID) {
//print("After adding script 2 : " + JSON.stringify(Entities.getEntityProperties(entityID)));
self.intervalID = Script.setInterval(function() {
if (Vec3.withinEpsilon(MyAvatar.position, Entities.getEntityProperties(entityID).position, 3)) {
if (Vec3.withinEpsilon(MyAvatar.position, Entities.getEntityProperties(entityID).position, MIN_PLAY_DISTANCE)) {
var userData = Entities.getEntityProperties(entityID).userData;
//print("UserData: " + userData);
if (userData) {
var userDataObject = JSON.parse(userData);
var animationObject = userDataObject.animations;
//print("Playing animation " + JSON.stringify(animationObject));
print("Playing animation " + JSON.stringify(animationObject));
var newAnimationObject = null;
if (!userDataObject.timeFromLastAnimation) {
userDataObject.timeFromLastAnimation = Date.now();
@ -20,7 +21,7 @@
Object.keys(animationObject).forEach(function(animationName) {
newAnimationObject = animationObject[animationName];
//print("Proto 0001: " + JSON.stringify(newAnimationObject));
newAnimationObject.__proto__ = DynamicBrushesInfo[animationName].proto;
newAnimationObject.__proto__ = AnimatedBrushesInfo[animationName].proto;
//print("time from last draw " + (Date.now() - userDataObject.animations.timeFromLastDraw));
newAnimationObject.onUpdate(Date.now() - userDataObject.timeFromLastAnimation, entityID);
});

View file

@ -0,0 +1,36 @@
Script.include("animatedHueBrush.js");
Script.include("animatedRotationBrush.js");
Script.include("animatedTranslationBrush.js");
AnimatedBrushesInfo = {
animatedHueBrush: {
isEnabled: false,
proto: AnimatedHueBrush.prototype,
settings: null,
},
animatedRotationBrush: {
isEnabled: false,
proto: AnimatedRotationBrush.prototype,
settings: null,
},
animatedTranslationBrush: {
isEnabled: false,
proto: AnimatedTranslationBrush.prototype,
settings: null,
},
}
animatedBrushFactory = function(animatedBrushName, settings, entityID) {
switch (animatedBrushName) {
case "animatedHueBrush":
return new AnimatedHueBrush(settings, entityID);
case "animatedRotationBrush":
return new AnimatedRotationBrush(settings, entityID);
case "animatedTranslationBrush":
return new AnimatedTranslationBrush(settings, entityID);
default:
throw new Error("Invalid Brush Name. Could not instantiate " + animatedBrushName);
}
}

View file

@ -0,0 +1,30 @@
//Superclass
Script.include("animatedBrush.js");
Script.include("../../ColorUtils2.js");
function AnimatedHueBrushClass(settings, entityID) {
//Animated brush vars
AnimatedBrush.call(this);
//print("Starting animated hue brush");
this.hsvColor = rgb2hsv(Entities.getEntityProperties(entityID).color);// {hue: 0, saturation: 1.0, value: 1.0};
this.animatedColor = {red: 0, green: 0, blue: 0};
}
AnimatedHueBrushClass.prototype.ANIMATED_BRUSH_TIME = 10; //inteval in milliseconds to update the brush width;
AnimatedHueBrushClass.prototype.ANIMATED_BRUSH_INCREMENT = 0.5; //linear increment of brush size;
AnimatedHueBrushClass.prototype.NAME = "animatedHueBrush";
AnimatedHueBrushClass.prototype.onUpdate = function(deltaSeconds, entityID) {
//print("Animated Hue Brush");
this.hsvColor.hue = this.hsvColor.hue + ((deltaSeconds * this.ANIMATED_BRUSH_INCREMENT)/this.ANIMATED_BRUSH_TIME);
this.hsvColor.hue = this.hsvColor.hue >= 360 ? 0 : this.hsvColor.hue; //restart hue cycle
this.animatedColor = hsv2rgb(this.hsvColor);
Entities.editEntity(entityID, { color : this.animatedColor});
this.parent.updateUserData(entityID, this);
}
//AnimatedHueBrushClass.prototype = Object.create(AnimatedBrush.prototype);
AnimatedHueBrushClass.prototype.constructor = AnimatedHueBrushClass;
AnimatedHueBrushClass.prototype.parent = AnimatedBrush.prototype;
AnimatedHueBrush = AnimatedHueBrushClass;

View file

@ -0,0 +1,28 @@
//Superclass
Script.include("animatedBrush.js");
function AnimatedRotationBrushClass(settings, entityID) {
//animated brush vars
AnimatedBrush.call(this);
//print("Starting animated rotation brush");
this.angle = 0;
this.activeAxis = settings.axis;
}
AnimatedRotationBrushClass.prototype.constructor = AnimatedRotationBrushClass;
AnimatedRotationBrushClass.prototype.parent = AnimatedBrush.prototype;
AnimatedRotationBrushClass.prototype.ANIMATED_BRUSH_TIME = 100; //inteval in milliseconds to update the entity rotation;
AnimatedRotationBrushClass.prototype.ANIMATED_BRUSH_INCREMENT = 5; //linear increment of brush size;
AnimatedRotationBrushClass.prototype.NAME = "animatedRotationBrush"; //linear increment of brush size;
AnimatedRotationBrushClass.prototype.onUpdate = function(deltaSeconds, entityID) {
//print("Animated rotation this: " + JSON.stringify(rotation));
this.angle = this.angle + ((deltaSeconds * this.ANIMATED_BRUSH_INCREMENT)/this.ANIMATED_BRUSH_TIME);
this.angle = this.angle >= 360 ? 0 : this.angle; //restart hue cycle
var rotation = Vec3.multiply(this.angle, this.activeAxis);
Entities.editEntity(entityID, {rotation : Quat.fromPitchYawRollDegrees(rotation.x, rotation.y, rotation.z)});
this.parent.updateUserData(entityID, this);
}
AnimatedRotationBrush = AnimatedRotationBrushClass;

View file

@ -1,31 +1,31 @@
//Superclass
Script.include("dynamicBrush.js");
Script.include("animatedBrush.js");
function DynamicTranslationBrushClass(settings) {
//dynamic brush vars
DynamicBrush.call(this);
//print("Starting dynamic Translation brush");
function AnimatedTranslationBrushClass(settings, entityID) {
//Animated brush vars
AnimatedBrush.call(this);
//print("Starting Animated Translation brush");
this.startingPosition = null;
this.translation = 0;
this.activeAxis = settings.axis;
}
DynamicTranslationBrushClass.prototype.constructor = DynamicTranslationBrushClass;
DynamicTranslationBrushClass.prototype.parent = DynamicBrush.prototype;
AnimatedTranslationBrushClass.prototype.constructor = AnimatedTranslationBrushClass;
AnimatedTranslationBrushClass.prototype.parent = AnimatedBrush.prototype;
DynamicTranslationBrushClass.prototype.DYNAMIC_BRUSH_TIME = 10; //inteval in milliseconds to update the brush width;
DynamicTranslationBrushClass.prototype.DYNAMIC_BRUSH_INCREMENT = 0.005; //linear increment of brush size;
DynamicTranslationBrushClass.prototype.MAX_TRANSLATION = 2;
DynamicTranslationBrushClass.prototype.NAME = "DynamicTranslationBrush"; //linear increment of brush size;
AnimatedTranslationBrushClass.prototype.ANIMATED_BRUSH_TIME = 10; //inteval in milliseconds to update the brush width;
AnimatedTranslationBrushClass.prototype.ANIMATED_BRUSH_INCREMENT = 0.005; //linear increment of brush size;
AnimatedTranslationBrushClass.prototype.MAX_TRANSLATION = 2;
AnimatedTranslationBrushClass.prototype.NAME = "animatedTranslationBrush"; //linear increment of brush size;
DynamicTranslationBrushClass.prototype.onUpdate = function(deltaSeconds, entityID) {
AnimatedTranslationBrushClass.prototype.onUpdate = function(deltaSeconds, entityID) {
//print("translation this: " + JSON.stringify(this) + " : " + JSON.stringify(this.activeAxis));
var currentPosition = Entities.getEntityProperties(entityID).position;
//print("currentPosition " + JSON.stringify(currentPosition));
if (this.startingPosition == null) {
this.startingPosition = currentPosition;
}
this.translation = this.translation + ((deltaSeconds * this.DYNAMIC_BRUSH_INCREMENT)/this.DYNAMIC_BRUSH_TIME);
this.translation = this.translation + ((deltaSeconds * this.ANIMATED_BRUSH_INCREMENT)/this.ANIMATED_BRUSH_TIME);
var translationVec = Vec3.multiply(this.translation, this.activeAxis);
var nextPosition = {
@ -42,4 +42,4 @@ DynamicTranslationBrushClass.prototype.onUpdate = function(deltaSeconds, entityI
this.parent.updateUserData(entityID, this);
}
DynamicTranslationBrush = DynamicTranslationBrushClass;
AnimatedTranslationBrush = AnimatedTranslationBrushClass;

View file

@ -1,36 +0,0 @@
Script.include("dynamicHueBrush.js");
Script.include("dynamicRotationBrush.js");
Script.include("dynamicTranslationBrush.js");
DynamicBrushesInfo = {
DynamicHueBrush: {
isEnabled: false,
proto: DynamicHueBrush.prototype,
settings: null,
},
DynamicRotationBrush: {
isEnabled: false,
proto: DynamicRotationBrush.prototype,
settings: null,
},
DynamicTranslationBrush: {
isEnabled: false,
proto: DynamicTranslationBrush.prototype,
settings: null,
},
}
dynamicBrushFactory = function(dynamicBrushName, settings) {
switch (dynamicBrushName) {
case "DynamicHueBrush":
return new DynamicHueBrush(settings);
case "DynamicRotationBrush":
return new DynamicRotationBrush(settings);
case "DynamicTranslationBrush":
return new DynamicTranslationBrush(settings);
default:
throw new Error("Could not instantiate " + dynamicBrushName);
}
}

View file

@ -1,63 +0,0 @@
//Superclass
Script.include("dynamicBrush.js");
function DynamicHueBrushClass(settings) {
//dynamic brush vars
DynamicBrush.call(this);
//print("Starting dynamic hue brush");
this.hsvColor = {hue: 0, saturation: 1.0, value: 1.0};
this.dynamicColor = {red: 0, green: 0, blue: 0};
}
DynamicHueBrushClass.prototype.DYNAMIC_BRUSH_TIME = 10; //inteval in milliseconds to update the brush width;
DynamicHueBrushClass.prototype.DYNAMIC_BRUSH_INCREMENT = 0.5; //linear increment of brush size;
DynamicHueBrushClass.prototype.NAME = "DynamicHueBrush"; //linear increment of brush size;
DynamicHueBrushClass.prototype.onUpdate = function(deltaSeconds, entityID) {
//print("Dynamic Hue Brush");
this.hsvColor.hue = this.hsvColor.hue + ((deltaSeconds * this.DYNAMIC_BRUSH_INCREMENT)/this.DYNAMIC_BRUSH_TIME);
this.hsvColor.hue = this.hsvColor.hue >= 360 ? 0 : this.hsvColor.hue; //restart hue cycle
this.dynamicColor = this.convertHsvToRgb(this.hsvColor);
Entities.editEntity(entityID, { color : this.dynamicColor});
this.parent.updateUserData(entityID, this);
}
DynamicHueBrushClass.prototype.convertHsvToRgb = function(hsvColor) {
var c = hsvColor.value * hsvColor.saturation;
var x = c * (1 - Math.abs((hsvColor.hue/60) % 2 - 1));
var m = hsvColor.value - c;
var rgbColor = new Object();
if (hsvColor.hue >= 0 && hsvColor.hue < 60) {
rgbColor.red = (c + m) * 255;
rgbColor.green = (x + m) * 255;
rgbColor.blue = (0 + m) * 255;
} else if (hsvColor.hue >= 60 && hsvColor.hue < 120) {
rgbColor.red = (x + m) * 255;
rgbColor.green = (c + m) * 255;
rgbColor.blue = (0 + m) * 255;
} else if (hsvColor.hue >= 120 && hsvColor.hue < 180) {
rgbColor.red = (0 + m) * 255;
rgbColor.green = (c + m) * 255;
rgbColor.blue = (x + m) * 255;
} else if (hsvColor.hue >= 180 && hsvColor.hue < 240) {
rgbColor.red = (0 + m) * 255;
rgbColor.green = (x + m) * 255;
rgbColor.blue = (c + m) * 255;
} else if (hsvColor.hue >= 240 && hsvColor.hue < 300) {
rgbColor.red = (x + m) * 255;
rgbColor.green = (0 + m) * 255;
rgbColor.blue = (c + m) * 255;
} else if (hsvColor.hue >= 300 && hsvColor.hue < 360) {
rgbColor.red = (c + m) * 255;
rgbColor.green = (0 + m) * 255;
rgbColor.blue = (x + m) * 255;
}
return rgbColor;
}
//DynamicHueBrushClass.prototype = Object.create(DynamicBrush.prototype);
DynamicHueBrushClass.prototype.constructor = DynamicHueBrushClass;
DynamicHueBrushClass.prototype.parent = DynamicBrush.prototype;
DynamicHueBrush = DynamicHueBrushClass;

View file

@ -1,28 +0,0 @@
//Superclass
Script.include("dynamicBrush.js");
function DynamicRotationBrushClass(settings) {
//dynamic brush vars
DynamicBrush.call(this);
//print("Starting dynamic rotation brush");
this.angle = 0;
this.activeAxis = settings.axis;
}
DynamicRotationBrushClass.prototype.constructor = DynamicRotationBrushClass;
DynamicRotationBrushClass.prototype.parent = DynamicBrush.prototype;
DynamicRotationBrushClass.prototype.DYNAMIC_BRUSH_TIME = 100; //inteval in milliseconds to update the entity rotation;
DynamicRotationBrushClass.prototype.DYNAMIC_BRUSH_INCREMENT = 5; //linear increment of brush size;
DynamicRotationBrushClass.prototype.NAME = "DynamicRotationBrush"; //linear increment of brush size;
DynamicRotationBrushClass.prototype.onUpdate = function(deltaSeconds, entityID) {
//print("Dynamic rotation this: " + JSON.stringify(rotation));
this.angle = this.angle + ((deltaSeconds * this.DYNAMIC_BRUSH_INCREMENT)/this.DYNAMIC_BRUSH_TIME);
this.angle = this.angle >= 360 ? 0 : this.angle; //restart hue cycle
var rotation = Vec3.multiply(this.angle, this.activeAxis);
Entities.editEntity(entityID, {rotation : Quat.fromPitchYawRollDegrees(rotation.x, rotation.y, rotation.z)});
this.parent.updateUserData(entityID, this);
}
DynamicRotationBrush = DynamicRotationBrushClass;

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View file

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><defs><style>.cls-1{fill:#fff;}</style></defs><title>hand</title><path class="cls-1" d="M197.33,26.23q13.93-19.8,40.33-19.8t40.7,20.17q14.3,20.17,14.3,51v38.87l124.3,48a52.83,52.83,0,0,1,15,7.15q7.33,5,7.33,10.45v125.4q0,2.57-29.7,33T375.17,370.9H182.67q-6.24,0-13-5.13A48.79,48.79,0,0,1,159.2,355.5l-3.3-5.13L71.57,217.27q-5.87-11.36,2.2-19.43l41.07-40.33a16.62,16.62,0,0,1,11.73-5A18.61,18.61,0,0,1,139,156.77l44.37,30.8V76.83Q183.4,46,197.33,26.23ZM256,124.5V50.07q0-7.7-9.17-11.18a25.63,25.63,0,0,0-18.33-.18q-9.17,3.3-9.17,11.37V224a8.5,8.5,0,0,1-.18,2.2c-.13.37-.31,1-.55,1.83a7.1,7.1,0,0,1-.73,1.83c-.25.37-.55.86-.92,1.47a4.23,4.23,0,0,1-1.47,1.47c-.61.37-1.16.68-1.65.92q-9.17,4.4-17.23-1.83L129.5,178.4,99.07,209.93l86.53,124.3H370l32.63-36.67V190.13l-124.3-48a52.74,52.74,0,0,1-15-7.15Q256,130,256,124.5ZM201,407.57H384.33a18.15,18.15,0,0,1,18.33,18.33v36.67a18.15,18.15,0,0,1-18.33,18.33H201a18.15,18.15,0,0,1-18.33-18.33V425.9A18.15,18.15,0,0,1,201,407.57Z"/></svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -18,10 +18,6 @@
isTabletFocused = false,
shouldRestoreTablet = false,
tabletDebugFocusLine = null,
//animated brush vars
lastFrameTime = Date.now(),
frameDeltaSeconds = null, //time that passed between frames in ms;
//end of dynamic brush vars
MAX_LINE_WIDTH = 0.036,
leftHand = null,
rightHand = null,
@ -38,13 +34,14 @@
HIFI_POINTER_DISABLE_MESSAGE_CHANNEL = "Hifi-Pointer-Disable",
SCRIPT_PATH = Script.resolvePath(''),
CONTENT_PATH = SCRIPT_PATH.substr(0, SCRIPT_PATH.lastIndexOf('/')),
ANIMATION_SCRIPT_PATH = Script.resolvePath("content/brushes/dynamicBrushes/dynamicBrushScript.js"),
ANIMATION_SCRIPT_PATH = Script.resolvePath("content/brushes/animatedBrushes/animatedBrushScript.js"),
APP_URL = CONTENT_PATH + "/html/main.html";
// Set up the qml ui
//var qml = Script.resolvePath('PaintWindow.qml');
Script.include("../libraries/controllers.js");
Script.include("content/brushes/dynamicBrushes/dynamicBrushesList.js");
Script.include("content/ColorUtils2.js");
Script.include("content/brushes/animatedBrushes/animatedBrushesList.js");
//var window = null;
//var inkSource = null;
@ -58,7 +55,12 @@
function paintBrush(name) {
// Paints in 3D.
var brushName = name,
STROKE_COLOR = savedSettings.currentColor,
STROKE_COLOR = {
red: savedSettings.currentColor.red,
green: savedSettings.currentColor.green,
blue: savedSettings.currentColor.blue
},
dynamicColor = null,
ERASE_SEARCH_RADIUS = 0.1, // m
STROKE_DIMENSIONS = { x: 10, y: 10, z: 10 },
isDrawingLine = false,
@ -67,9 +69,14 @@
basePosition,
strokePoints,
strokeNormals,
strokeColors,
strokeWidths,
timeOfLastPoint,
isContinuousLine = savedSettings.currentIsContinuous,
lastPosition = null,
shouldKeepDrawing = false,
texture = CONTENT_PATH + "/" + savedSettings.currentTexture.brushName,
dynamicEffects = savedSettings.currentDynamicBrushes;
//'https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Caris_Tessellation.svg/1024px-Caris_Tessellation.svg.png', // Daantje
strokeWidthMultiplier = savedSettings.currentStrokeWidth * 2 + 0.1,
IS_UV_MODE_STRETCH = savedSettings.currentTexture.brushType == "stretch",
@ -101,6 +108,58 @@
return STROKE_COLOR;
}
function nextValueInRange(value, min, max, increment) {
var delta = max - min;
value += increment;
if (value > max) {
return min;
} else {
return value;
}
}
function attacthColorToProperties(properties) {
var isAnyDynamicEffectEnabled = false;
if ("dynamicHue" in dynamicEffects && dynamicEffects.dynamicHue) {
isAnyDynamicEffectEnabled = true;
var hueIncrement = 359.0 / 70.0;
dynamicColor.hue = nextValueInRange(dynamicColor.hue, 0, 359, hueIncrement);
}
if ("dynamicSaturation" in dynamicEffects && dynamicEffects.dynamicSaturation) {
isAnyDynamicEffectEnabled = true;
dynamicColor.saturation = dynamicColor.saturation == 0.2 ? 0.8 : 0.2;
/*var saturationIncrement = 1.0 / 70.0;
dynamicColor.saturation = nextValueInRange(dynamicColor.saturation, 0, 1, saturationIncrement);*/
}
if ("dynamicValue" in dynamicEffects && dynamicEffects.dynamicValue) {
isAnyDynamicEffectEnabled = true;
dynamicColor.value = dynamicColor.value == 0.2 ? 0.8 : 0.2;
/*var saturationIncrement = 1.0 / 70.0;
dynamicColor.saturation = nextValueInRange(dynamicColor.saturation, 0, 1, saturationIncrement);*/
}
if (!isAnyDynamicEffectEnabled) {
properties.color = STROKE_COLOR;
return;
}
var newRgbColor = hsv2rgb(dynamicColor);
strokeColors.push({
x: newRgbColor.red/255.0,
y: newRgbColor.green/255.0,
z: newRgbColor.blue/255.0}
);
properties.strokeColors = strokeColors;
}
function setDynamicEffects(newDynamicEffects) {
dynamicEffects = newDynamicEffects;
}
function isDrawing() {
return isDrawingLine;
}
@ -111,6 +170,10 @@
strokeWidthMultiplier = multiplier;
}
function switchContinuousLine(isContinuous) {
isContinuousLine = isContinuous;
}
function setTriggerPressureWidthEnabled(isEnabled) {
isTriggerPressureWidthEnabled = isEnabled;
}
@ -173,18 +236,22 @@
// Nevertheless, continue on and start a new line.
}
basePosition = position;
if (shouldKeepDrawing) {
strokePoints = [Vec3.distance(basePosition, strokePoints[strokePoints.length - 1])];
} else {
strokePoints = [Vec3.ZERO];
}
strokePoints = [Vec3.ZERO];
basePosition = position;
strokeNormals = [strokeNormal()];
strokeColors = [];
strokeWidths = [width];
timeOfLastPoint = Date.now();
entityID = Entities.addEntity({
var newEntityProperties = {
type: "PolyLine",
name: "fingerPainting",
shapeType: "box",
color: STROKE_COLOR,
position: position,
linePoints: strokePoints,
normals: strokeNormals,
@ -192,9 +259,13 @@
textures: texture, // Daantje
isUVModeStretch: IS_UV_MODE_STRETCH,
dimensions: STROKE_DIMENSIONS,
});
};
dynamicColor = rgb2hsv(STROKE_COLOR);
attacthColorToProperties(newEntityProperties);
entityID = Entities.addEntity(newEntityProperties);
isDrawingLine = true;
addAnimationToBrush(entityID);
lastPosition = position;
}
function drawLine(position, width) {
@ -222,23 +293,34 @@
&& (Date.now() - timeOfLastPoint) >= MIN_STROKE_INTERVAL
&& strokePoints.length < MAX_POINTS_PER_LINE) {
strokePoints.push(localPosition);
//strokeColors.push({x: STROKE_COLOR.red/255.0, y: STROKE_COLOR.green/255.0, z: STROKE_COLOR.blue/255.0});
strokeNormals.push(strokeNormal());
strokeWidths.push(width);
timeOfLastPoint = Date.now();
Entities.editEntity(entityID, {
var editItemProperties = {
color: STROKE_COLOR,
linePoints: strokePoints,
normals: strokeNormals,
strokeWidths: strokeWidths
});
};
attacthColorToProperties(editItemProperties);
Entities.editEntity(entityID, editItemProperties);
} else if (isContinuousLine && strokePoints.length >= MAX_POINTS_PER_LINE) {
print("restarting to draw line");
finishLine(position, width);
shouldKeepDrawing = true;
startLine(lastPosition, width);
}
if (strokePoints.length >= MAX_POINTS_PER_LINE)
print("restarting to draw linea asdasdadwe");
lastPosition = position;
}
function finishLine(position, width) {
// Finish drawing polyline; delete if it has only 1 point.
//stopDynamicBrush = true;
//print("Before adding script: " + JSON.stringify(Entities.getEntityProperties(entityID)));
var userData = Entities.getEntityProperties(entityID).userData;
if (userData && JSON.parse(userData).animations) {
@ -262,6 +344,7 @@
}
isDrawingLine = false;
shouldKeepDrawing = false;
addElementToUndoStack({type: "created", data: entityID});
//print("After adding script 3: " + JSON.stringify(Entities.getEntityProperties(entityID)));
}
@ -338,7 +421,8 @@
getStrokeWidth: getStrokeWidth,
getEntityID: getEntityID,
changeUVMode: changeUVMode,
setTriggerPressureWidthEnabled: setTriggerPressureWidthEnabled
setTriggerPressureWidthEnabled: setTriggerPressureWidthEnabled,
setDynamicEffects: setDynamicEffects
};
}
@ -500,26 +584,16 @@
if (overlays.intersects && HMD.tabletID == overlays.overlayID) {
if (!isTabletFocused) {
isTabletFocused = true;
//isFingerPainting = false;
Overlays.editOverlay(inkSourceOverlay, {visible: false});
updateHandAnimations();
pauseProcessing();
//print("Hovering tablet!");
}
} else {
if (isTabletFocused) {
//print("Unhovering tablet!");
isTabletFocused = false;
//isFingerPainting = true;
Overlays.editOverlay(inkSourceOverlay, {visible: true});
resumeProcessing();
updateHandFunctions();
//updateHandAnimations();
/*print("Current hand " + handName);
print("isFingerPainting " + isFingerPainting);
print("inkSourceOverlay " + JSON.stringify(inkSourceOverlay));
print("inkSourceOverlay " + JSON.stringify(inkSourceOverlay));*/
}
};
}
@ -555,20 +629,6 @@
// }
// inkSource = Entities.addEntity(inkSourceProps);
// }
/*frameDeltaSeconds = Date.now() - lastFrameTime;
lastFrameTime = Date.now();
var nearbyEntities = Entities.findEntities(MyAvatar.position, 5.0);
for (var i = 0; i < nearbyEntities.length; i++) {
//Entities.editEntity(nearbyEntities[i], {userData: ""}); //clear user data (good to use in case we need to clear it)
var userData = Entities.getEntityProperties(nearbyEntities[i]).userData;
if (userData != "") {
playAnimations(nearbyEntities[i], JSON.parse(userData).animations);
}
}*/
/*if (Entities.getEntityProperties(nearbyEntities[i]).name == "fingerPainting")
Entities.deleteEntity(nearbyEntities[i]);*/
if (HMD.tabletID && (((leftBrush == null || rightBrush == null) || (!leftBrush.isDrawing() && !rightBrush.isDrawing())))) {
checkTabletHasFocus();
}
@ -709,18 +769,10 @@
}
function pauseProcessing() {
//Script.update.disconnect(leftHand.onUpdate);
//Script.update.disconnect(rightHand.onUpdate);
//Controller.disableMapping(CONTROLLER_MAPPING_NAME);
Messages.sendLocalMessage("Hifi-Hand-Disabler", "none");
Messages.unsubscribe(HIFI_POINT_INDEX_MESSAGE_CHANNEL);
Messages.unsubscribe(HIFI_GRAB_DISABLE_MESSAGE_CHANNEL);
Messages.unsubscribe(HIFI_POINTER_DISABLE_MESSAGE_CHANNEL);
//Restores and clears hand animations
restoreAllHandAnimations();
}
@ -877,10 +929,12 @@
savedSettings.currentStrokeWidth = Settings.getValue("currentStrokeWidth", 0.25);
savedSettings.currentTexture = Settings.getValue("currentTexture", {brushID: 0});
savedSettings.currentDrawingHand = Settings.getValue("currentDrawingHand", MyAvatar.getDominantHand() == "left");
savedSettings.currentDynamicBrushes = Settings.getValue("currentDynamicBrushes", []);
savedSettings.currentAnimatedBrushes = Settings.getValue("currentAnimatedBrushes", []);
savedSettings.customColors = Settings.getValue("customColors", []);
savedSettings.currentTab = Settings.getValue("currentTab", 0);
savedSettings.currentTriggerWidthEnabled = Settings.getValue("currentTriggerWidthEnabled", true);
savedSettings.currentDynamicBrushes = Settings.getValue("currentDynamicBrushes", new Object());
savedSettings.currentIsContinuous = Settings.getValue("currentIsContinuous", false);
savedSettings.undoDisable = undoStack.length == 0;
isLeftHandDominant = savedSettings.currentDrawingHand;
}
@ -891,7 +945,7 @@
var wasFingerPainting = isFingerPainting;
isFingerPainting = !isFingerPainting;
print("isFingerPainting: " + isFingerPainting);
//print("isFingerPainting: " + isFingerPainting);
if (!isFingerPainting) {
tablet.gotoHomeScreen();
}
@ -903,7 +957,7 @@
}
if (isFingerPainting) {
print("opening tablet fingerpaint app");
//print("opening tablet fingerpaint app");
tablet.gotoWebScreen(APP_URL + "?" + encodeURIComponent(JSON.stringify(savedSettings)));
enableProcessing();
savedSettings = null;
@ -924,18 +978,6 @@
}
function onTabletScreenChanged(type, url) {
//var TABLET_SCREEN_CLOSED = "Closed";
//var TABLET_SCREEN_HOME = "Home";
//isTabletDisplayed = type !== TABLET_SCREEN_CLOSED;
//if (type === TABLET_SCREEN_HOME) {
// if (isFingerPainting) {
// isFingerPainting = false;
// disableProcessing();
// }
// button.editProperties({ isActive: isFingerPainting });
// print("Closing the APP");
//}
//updateHandFunctions();
var TABLET_SCREEN_CLOSED = "Closed";
isTabletDisplayed = type !== TABLET_SCREEN_CLOSED;
isFingerPainting = type === "Web" && url.indexOf("fingerPaint/html/main.html") > -1;
@ -1005,11 +1047,11 @@
//print("abrushType: " + event.brushType);
Settings.setValue("currentTexture", event);
if (event.brushType === "repeat") {
print("brushType: " + event.brushType);
//print("brushType: " + event.brushType);
leftBrush.changeUVMode(false);
rightBrush.changeUVMode(false);
} else if (event.brushType === "stretch") {
print("brushType: " + event.brushType);
//print("brushType: " + event.brushType);
leftBrush.changeUVMode(true);
rightBrush.changeUVMode(true);
}
@ -1042,7 +1084,6 @@
case "undo":
//print("Going to undo");
//The undo is called only on the right brush because the undo stack is global, meaning that
//calling undo on both the left and right brush would cause the stack to pop twice.
//Using the leftBrush instead of the rightBrush would have the exact same effect.
@ -1055,18 +1096,31 @@
updateHandAnimations();
break;
case "switchDynamicBrush":
var dynamicBrushes = Settings.getValue("currentDynamicBrushes", []);
var brushSettingsIndex = dynamicBrushes.indexOf(event.dynamicBrushID);
case "switchAnimatedBrush":
var animatedBrushes = Settings.getValue("currentAnimatedBrushes", []);
var brushSettingsIndex = animatedBrushes.indexOf(event.animatedBrushID);
if (brushSettingsIndex > -1) { //already exists so we are disabling it
dynamicBrushes.splice(brushSettingsIndex, 1);
animatedBrushes.splice(brushSettingsIndex, 1);
} else { //doesn't exist yet so we are just adding it
dynamicBrushes.push(event.dynamicBrushID);
animatedBrushes.push(event.animatedBrushID);
}
Settings.setValue("currentAnimatedBrushes", animatedBrushes);
AnimatedBrushesInfo[event.animatedBrushName].isEnabled = event.enabled;
AnimatedBrushesInfo[event.animatedBrushName].settings = event.settings;
//print("SEtting animated brush" + JSON.stringify(AnimatedBrushesInfo[event.animatedBrushName]));
break;
case "switchDynamicBrush":
var dynamicBrushes = Settings.getValue("currentDynamicBrushes", new Object());
dynamicBrushes[event.dynamicBrushId] = event.enabled;
Settings.setValue("currentDynamicBrushes", dynamicBrushes);
DynamicBrushesInfo[event.dynamicBrushName].isEnabled = event.enabled;
DynamicBrushesInfo[event.dynamicBrushName].settings = event.settings;
//print("SEtting dynamic brush" + JSON.stringify(DynamicBrushesInfo[event.dynamicBrushName]));
rightBrush.setDynamicEffects(dynamicBrushes);
leftBrush.setDynamicEffects(dynamicBrushes);
break;
case "switchIsContinuous":
Settings.setValue("currentIsContinuous", event.enabled);
rightBrush.switchIsContinuous(event.enabled);
leftBrush.switchIsContinuous(event.enabled);
break;
default:
@ -1075,16 +1129,21 @@
}
function addAnimationToBrush(entityID) {
Object.keys(DynamicBrushesInfo).forEach(function(animationName) {
if (DynamicBrushesInfo[animationName].isEnabled) {
Object.keys(AnimatedBrushesInfo).forEach(function(animationName) {
print(animationName);
if (AnimatedBrushesInfo[animationName].isEnabled) {
//print("Adding animation " + animationName);
var prevUserData = Entities.getEntityProperties(entityID).userData;
prevUserData = prevUserData == "" ? new Object() : JSON.parse(prevUserData); //preserve other possible user data
if (prevUserData.animations == null) {
prevUserData.animations = {};
}
prevUserData.animations[animationName] = dynamicBrushFactory(animationName, DynamicBrushesInfo[animationName].settings);
prevUserData.animations[animationName] = animatedBrushFactory(animationName,
AnimatedBrushesInfo[animationName].settings, entityID);
Entities.editEntity(entityID, {userData: JSON.stringify(prevUserData)});
//Entities.editEntity(entityID, {script: Script.resolvePath("content/brushes/dynamicBrushes/dynamicBrushScript.js")});
//print("Added animation: " + JSON.stringify(Entities.getEntityProperties(entityID)));
}
});
}
@ -1102,23 +1161,21 @@
function onHmdChanged(isHMDActive) {
var HMDInfo = Settings.getValue("wasFingerPaintingWhenHMDClosed", {isHMDActive: true, wasFingerPainting: false});
print("IS HMD " + isHMDActive + " fingerPainting: " + isFingerPainting + " was fingerPainting " + HMDInfo.wasFingerPainting + " TabletID " + HMD.tabletID);
// if (isHMDActive && !isFingerPainting && HMDInfo.wasFingerPainting) { only reopen in hmd mode
if (!isFingerPainting && HMDInfo.wasFingerPainting) {
print("Restarting fingerPaint app!");
//print("Restarting fingerPaint app!");
shouldRestoreTablet = true;
HMD.openTablet();
}
if (isHMDActive != HMDInfo.isHMDActive) { //check if state is different as some times it will be the same
//onHmdChanged seems to be called twice (once before and once after fingerpaint is over)
Settings.setValue("wasFingerPaintingWhenHMDClosed", {isHMDActive: isHMDActive, wasFingerPainting: isFingerPainting});
print("Saving finger painting value " + isFingerPainting);
//print("Saving finger painting value " + isFingerPainting);
}
}
function setUp() {
print("Setting button...");
//print("Setting button...");
tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
if (!tablet) {
return;
@ -1131,7 +1188,7 @@
text: BUTTON_NAME,
isActive: isFingerPainting
});
print("button-1 : " + JSON.stringify(button.getProperties()));
//print("button-1 : " + JSON.stringify(button.getProperties()));
button.clicked.connect(onButtonClicked);
// Track whether tablet is displayed or not.
tablet.screenChanged.connect(onTabletScreenChanged);
@ -1162,20 +1219,15 @@
function mouseDrawLine(event){
if (rightBrush && rightBrush.isDrawing()) {
print(JSON.stringify(event));
rightBrush.drawLine(getFingerPosition(event.x, event.y), MAX_LINE_WIDTH);
} else {
print("cannot draw with mouse");
}
}
}
function mouseStartLine(event){
print(JSON.stringify(event));
//print(JSON.stringify(event));
if (event.isLeftButton && rightBrush) {
isMouseDrawing = true;
rightBrush.startLine(getFingerPosition(event.x, event.y), MAX_LINE_WIDTH);
} else {
print("cannot draw with mouse");
}
//Note: won't work until findRayIntersection works with polylines
//
@ -1200,9 +1252,7 @@
isMouseDrawing = false;
if (rightBrush && rightBrush.isDrawing()) {
rightBrush.finishLine(getFingerPosition(event.x, event.y), MAX_LINE_WIDTH);
} else {
print("cannot draw with mouse");
}
}
}
setUp();

View file

@ -38,7 +38,7 @@
background-color: #2e2e2e;
border:none;
position: relative;
width: 66px;
width: 80px;
margin: 1px 0px;
}
.checkbox {
@ -46,7 +46,7 @@
}
.BrushIcon {
width: 100%;
height: 66px;
height: 80px;
background-size: 75% 75%;
background-position: center;
background-repeat: no-repeat;
@ -55,7 +55,7 @@
background-image: url("../../../../resources/icons/loadingDark.gif");
-webkit-mask-repeat: no-repeat;
}
#dynamicBrush {
#animatedBrush {
margin: 20px 0;
}
.selectedBrush {
@ -82,6 +82,7 @@
display: block;
position: relative;
margin-bottom: 5px;
height: 80px;
}
.brushLabel {
display: block;
@ -89,6 +90,7 @@
margin-bottom: 5px;
color: white;
width: 100%;
font-size: 12px;
z-index: 2;
word-wrap: break-word;
text-overflow: ellipsis;
@ -97,6 +99,7 @@
#strokeWidthWidget {
position: fixed;
background-color: #404040;
display: flex;
z-index: 3;
top: -1px;
margin: 0px;
@ -104,47 +107,84 @@
border: none;
}
#pressureSensitiveCheckbox {
margin-left: 20px;
margin-top: 23px;
}
.animationBrush input[type=checkbox]:disabled + label,
.dynamicBrush input[type=checkbox]:disabled + label {
color: #202020;
}
</style>
<div id="strokeWidthWidget" class="property range">
<label style="display: block">Stroke Width</label>
<div class="sliderWrapper">
<input type="range" id="lineWidthRange" value=0.25 min=0 max=1 step=0.01 onchange="changeLineWidthRange(this)"/>
<input type="number" id="lineWidthText" value=0.25 min=0 max=1 step=0.01 onchange="changeLineWidthNumber(this)"/>
<div>
<label style="display: block">Stroke Width</label>
<div class="sliderWrapper">
<input type="range" id="lineWidthRange" value=0.25 min=0 max=1 step=0.01 onchange="changeLineWidthRange(this)"/>
<input type="number" id="lineWidthText" value=0.25 min=0 max=1 step=0.01 onchange="changeLineWidthNumber(this)"/>
</div>
</div>
<div id="pressureSensitiveCheckbox" class="behavior-group property checkbox">
<input onchange="switchPressureSensitiveWidth(this)" type="checkbox" id="triggerSensitiveWidth"></input>
<label for="triggerSensitiveWidth">Trigger Sensitive Width</label>
</div>
</div>
<div style="margin-top: 75px">
<div class="behavior-group property checkbox">
<input onchange="setDynamicBrush(this)" animationType="DynamicHueBrush" type="checkbox" id="dynamicBrush"></input>
<label for="dynamicBrush">Use Dynamic Hue </label>
<input onchange="setContinuosLineMode(this)" type="checkbox" id="continuousLine"></input>
<label for="continuousLine">Use Continuous Line</label>
</div>
<div class="behavior-group property checkbox animationBrush">
<input onchange="setAnimatedBrush(this)" animationType="animatedHueBrush" type="checkbox" id="animatedBrush"></input>
<label for="animatedBrush">Use Hue Animation</label>
</div>
<div class="behavior-group property checkbox dynamicBrush">
<input onchange="setDynamicBrush(this)" type="checkbox" id="dynamicHue"></input>
<label for="dynamicHue">Use Dynamic Hue</label>
</div>
<div class="behavior-group property checkbox dynamicBrush">
<input onchange="setDynamicBrush(this)" type="checkbox" id="dynamicSaturation"></input>
<label for="dynamicSaturation">Use Dynamic Saturation</label>
</div>
<div class="behavior-group property checkbox dynamicBrush">
<input onchange="setDynamicBrush(this)" type="checkbox" id="dynamicValue"></input>
<label for="dynamicValue">Use Dynamic Brightness</label>
</div>
<!--<div>
<div style="float: left; margin-right: 20px">
<div class="behavior-group property checkbox">
<input onchange="setDynamicBrush(this)" animationType="DynamicRotationBrush" type="checkbox" id="yawRotationBrush"></input>
<input onchange="setAnimatedBrush(this)" animationType="animatedRotationBrush" type="checkbox" id="yawRotationBrush"></input>
<label for="yawRotationBrush">Use Yaw Rotation</label>
</div>
<div class="behavior-group property checkbox">
<input onchange="setDynamicBrush(this)" animationType="DynamicRotationBrush" type="checkbox" id="pitchRotationBrush"></input>
<input onchange="setAnimatedBrush(this)" animationType="animatedRotationBrush" type="checkbox" id="pitchRotationBrush"></input>
<label for="pitchRotationBrush">Use Pitch Rotation</label>
</div>
<div class="behavior-group property checkbox">
<input onchange="setDynamicBrush(this)" animationType="DynamicRotationBrush" type="checkbox" id="rollRotationBrush"></input>
<input onchange="setAnimatedBrush(this)" animationType="animatedRotationBrush" type="checkbox" id="rollRotationBrush"></input>
<label for="rollRotationBrush">Use Roll Rotation</label>
</div>
</div>
<div>
<div class="behavior-group property checkbox">
<input onchange="setDynamicBrush(this)" animationType="DynamicTranslationBrush" type="checkbox" id="xTranslationBrush"></input>
<input onchange="setAnimatedBrush(this)" animationType="animatedTranslationBrush" type="checkbox" id="xTranslationBrush"></input>
<label for="xTranslationBrush">Use Translation x</label>
</div>
<div class="behavior-group property checkbox">
<input onchange="setDynamicBrush(this)" animationType="DynamicTranslationBrush" type="checkbox" id="yTranslationBrush"></input>
<input onchange="setAnimatedBrush(this)" animationType="animatedTranslationBrush" type="checkbox" id="yTranslationBrush"></input>
<label for="yTranslationBrush">Use Translation y</label>
</div>
<div class="behavior-group property checkbox">
<input onchange="setDynamicBrush(this)" animationType="DynamicTranslationBrush" type="checkbox" id="zTranslationBrush"></input>
<input onchange="setAnimatedBrush(this)" animationType="animatedTranslationBrush" type="checkbox" id="zTranslationBrush"></input>
<label for="zTranslationBrush">Use Translation z</label>
</div>
</div>
@ -152,91 +192,244 @@
<div id="brushesCointainer">
<button class="brushButton" brushType="stretch" id="content/brushes/256x256/basic.png" onclick="changePaintBrush(0)">
<button class="brushButton" brushType="stretch" id="content/brushes/square.png" onclick="changePaintBrush(0)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/basic.png" class="BrushIcon"></div>
<div imageSrc="../content/brushes/square.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">basic A</div>
<div class="brushLabel">Square</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/256x256/basic.png" onclick="changePaintBrush(1)">
<button class="brushButton" brushType="stretch" id="content/brushes/paintbrush6.png" onclick="changePaintBrush(1)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/basic.png" class="BrushIcon"></div>
<div imageSrc="../content/brushes/paintbrush6.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">basic B</div>
<div class="brushLabel">Rounded</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/256x256/bristle.png" onclick="changePaintBrush(2)">
<button class="brushButton" brushType="stretch" id="content/brushes/soft.png" onclick="changePaintBrush(2)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/bristle.png" class="BrushIcon"></div>
<div imageSrc="../content/brushes/soft.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">bristle A</div>
<div class="brushLabel">Soft</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/256x256/bristle.png" onclick="changePaintBrush(3)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/bristle.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">bristle B</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/256x256/dupuiz.png" onclick="changePaintBrush(4)">
<button class="brushButton" brushType="stretch" id="content/brushes/256x256/dupuiz.png" onclick="changePaintBrush(3)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/dupuiz.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">dupuiz A</div>
<div class="brushLabel">Tri</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/256x256/dupuiz.png" onclick="changePaintBrush(5)">
<button class="brushButton" brushType="stretch" id="content/brushes/256x256/basic.png" onclick="changePaintBrush(4)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/dupuiz.png" class="BrushIcon"></div>
<div imageSrc="../content/brushes/256x256/basic.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">dupuiz B</div>
<div class="brushLabel">Basic</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/oil.png" onclick="changePaintBrush(5)">
<div class="imageContainer">
<div imageSrc="../content/brushes/oil.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Oil</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/256x256/gouache.png" onclick="changePaintBrush(6)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/gouache.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">gouache A</div>
<div class="brushLabel">Gouache A</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/256x256/gouache.png" onclick="changePaintBrush(7)">
<button class="brushButton" brushType="stretch" id="content/brushes/256x256stretched/gouache.png" onclick="changePaintBrush(7)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256stretched/gouache.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Gouache B</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/koons.png" onclick="changePaintBrush(8)">
<div class="imageContainer">
<div imageSrc="../content/brushes/koons.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Koons</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/256x256/sponge.png" onclick="changePaintBrush(9)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/sponge.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Sponge A</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/256x256stretched/sponge.png" onclick="changePaintBrush(10)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256stretched/sponge.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Sponge B</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/256x256/graphite.png" onclick="changePaintBrush(11)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/graphite.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Graphite</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/256x256/bristle.png" onclick="changePaintBrush(12)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/bristle.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Bristle</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/256x256/spat-fine.png" onclick="changePaintBrush(13)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/spat-fine.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Spat</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/gradient2.png" onclick="changePaintBrush(14)">
<div class="imageContainer">
<div imageSrc="../content/brushes/gradient2.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Gradient A</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/gradient2.png" onclick="changePaintBrush(15)">
<div class="imageContainer">
<div imageSrc="../content/brushes/gradient2.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Gradient B</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/gimickkywhite/dot.png" onclick="changePaintBrush(16)">
<div class="imageContainer">
<div imageSrc="../content/brushes/gimickkywhite/dot.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Dot</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/gimickkywhite/polka.png" onclick="changePaintBrush(17)">
<div class="imageContainer">
<div imageSrc="../content/brushes/gimickkywhite/polka.png" class="BrushIcon"/></div>
</div>
<div class="brushLabel">Polka</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/gimickkywhite/heart.png" onclick="changePaintBrush(18)">
<div class="imageContainer">
<div imageSrc="../content/brushes/gimickkywhite/heart.png" class="BrushIcon"/></div>
</div>
<div class="brushLabel">Heart</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/gimickkywhite/hearts.png" onclick="changePaintBrush(19)">
<div class="imageContainer">
<div imageSrc="../content/brushes/gimickkywhite/hearts.png" class="BrushIcon"/></div>
</div>
<div class="brushLabel">Hearts</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/gimickkywhite/flowers2.png" onclick="changePaintBrush(20)">
<div class="imageContainer">
<div imageSrc="../content/brushes/gimickkywhite/flowers2.png" class="BrushIcon"/></div>
</div>
<div class="brushLabel">Flowers</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/gimickkywhite/leaves.png" onclick="changePaintBrush(21)">
<div class="imageContainer">
<div imageSrc="../content/brushes/gimickkywhite/leaves.png" class="BrushIcon"/></div>
</div>
<div class="brushLabel">Leaves</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/gimickkywhite/snowflakes2.png" onclick="changePaintBrush(22)">
<div class="imageContainer">
<div imageSrc="../content/brushes/gimickkywhite/snowflakes2.png" class="BrushIcon"/></div>
</div>
<div class="brushLabel">Snowflakes</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/paintbrush1.png" onclick="changePaintBrush(23)">
<div class="imageContainer">
<div imageSrc="../content/brushes/paintbrush1.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Stars</div>
</button>
<button class="brushButton" colored="true" brushType="stretch" id="content/brushes/colored/breakfast.png" onclick="changePaintBrush(24)">
<div class="imageContainer">
<div imageSrc="../content/brushes/colored/breakfast.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Breakfast</div>
</button>
<button class="brushButton" colored="true" brushType="stretch" id="content/brushes/colored/newton.png" onclick="changePaintBrush(25)">
<div class="imageContainer">
<div imageSrc="../content/brushes/colored/newton.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Newton</div>
</button>
<button class="brushButton" colored="true" brushType="stretch" id="content/brushes/colored/softy.png" onclick="changePaintBrush(26)">
<div class="imageContainer">
<div imageSrc="../content/brushes/colored/softy.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">Softbow</div>
</button>
<!--<button class="brushButton" brushType="repeat" id="content/brushes/256x256/basic.png" onclick="changePaintBrush(1)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/basic.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">basic B</div>
</button>-->
<!--<button class="brushButton" brushType="repeat" id="content/brushes/256x256/bristle.png" onclick="changePaintBrush(3)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/bristle.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">bristle B</div>
</button>-->
<!--<button class="brushButton" brushType="repeat" id="content/brushes/256x256/dupuiz.png" onclick="changePaintBrush(5)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/dupuiz.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">dupuiz B</div>
</button>-->
<!--<button class="brushButton" brushType="repeat" id="content/brushes/256x256/gouache.png" onclick="changePaintBrush(7)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/gouache.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">gouache B</div>
</button>
</button>-->
<button class="brushButton" brushType="stretch" id="content/brushes/256x256/graphite.png" onclick="changePaintBrush(8)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/graphite.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">graphite A</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/256x256/graphite.png" onclick="changePaintBrush(9)">
<!--<button class="brushButton" brushType="repeat" id="content/brushes/256x256/graphite.png" onclick="changePaintBrush(9)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/graphite.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">graphite B</div>
</button>
</button>-->
<button class="brushButton" brushType="stretch" id="content/brushes/256x256/spat-fine.png" onclick="changePaintBrush(10)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/spat-fine.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">spat-fine A</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/256x256/spat-fine.png" onclick="changePaintBrush(11)">
<!--<button class="brushButton" brushType="repeat" id="content/brushes/256x256/spat-fine.png" onclick="changePaintBrush(11)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/spat-fine.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">spat-fine B</div>
</button>
</button>-->
<button class="brushButton" brushType="stretch" id="content/brushes/256x256/spat-medium.png" onclick="changePaintBrush(12)">
<!--<button class="brushButton" brushType="stretch" id="content/brushes/256x256/spat-medium.png" onclick="changePaintBrush(12)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/spat-medium.png" class="BrushIcon"></div>
</div>
@ -248,23 +441,16 @@
<div imageSrc="../content/brushes/256x256/spat-medium.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">spat-medium B</div>
</button>
</button>-->
<button class="brushButton" brushType="stretch" id="content/brushes/256x256/sponge.png" onclick="changePaintBrush(14)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/sponge.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">sponge A</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/256x256/sponge.png" onclick="changePaintBrush(15)">
<!--<button class="brushButton" brushType="repeat" id="content/brushes/256x256/sponge.png" onclick="changePaintBrush(15)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256/sponge.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">sponge B</div>
</button>
</button>-->
<button class="brushButton" brushType="stretch" id="content/brushes/256x256stretched/basic.png" onclick="changePaintBrush(16)">
<!--<button class="brushButton" brushType="stretch" id="content/brushes/256x256stretched/basic.png" onclick="changePaintBrush(16)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256stretched/basic.png" class="BrushIcon"></div>
</div>
@ -290,37 +476,24 @@
<div imageSrc="../content/brushes/256x256stretched/bristle.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">bristle B</div>
</button>
</button>-->
<button class="brushButton" brushType="stretch" id="content/brushes/256x256stretched/gouache.png" onclick="changePaintBrush(20)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256stretched/gouache.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">gouache A</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/256x256stretched/gouache.png" onclick="changePaintBrush(21)">
<!--<button class="brushButton" brushType="repeat" id="content/brushes/256x256stretched/gouache.png" onclick="changePaintBrush(21)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256stretched/gouache.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">gouache B</div>
</button>
</button>-->
<button class="brushButton" brushType="stretch" id="content/brushes/256x256stretched/sponge.png" onclick="changePaintBrush(22)">
<!--<button class="brushButton" brushType="stretch" id="content/brushes/256x256stretched/sponge.png" onclick="changePaintBrush(22)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256stretched/sponge.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">sponge A</div>
</button>
</button>-->
<button class="brushButton" brushType="repeat" id="content/brushes/256x256stretched/sponge.png" onclick="changePaintBrush(23)">
<div class="imageContainer">
<div imageSrc="../content/brushes/256x256stretched/sponge.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">sponge B</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/basic.png" onclick="changePaintBrush(24)">
<!--<button class="brushButton" brushType="stretch" id="content/brushes/basic.png" onclick="changePaintBrush(24)">
<div class="imageContainer">
<div imageSrc="../content/brushes/basic.png" class="BrushIcon"></div>
</div>
@ -374,23 +547,9 @@
<div imageSrc="../content/brushes/gradient.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">gradient B</div>
</button>
</button>-->
<button class="brushButton" brushType="stretch" id="content/brushes/gradient2.png" onclick="changePaintBrush(32)">
<div class="imageContainer">
<div imageSrc="../content/brushes/gradient2.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">gradient2 A</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/gradient2.png" onclick="changePaintBrush(33)">
<div class="imageContainer">
<div imageSrc="../content/brushes/gradient2.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">gradient2 B</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/gradient3.png" onclick="changePaintBrush(34)">
<!--<button class="brushButton" brushType="stretch" id="content/brushes/gradient3.png" onclick="changePaintBrush(34)">
<div class="imageContainer">
<div imageSrc="../content/brushes/gradient3.png" class="BrushIcon"></div>
</div>
@ -402,51 +561,30 @@
<div imageSrc="../content/brushes/gradient3.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">gradient3 B</div>
</button>
</button>-->
<button class="brushButton" brushType="stretch" id="content/brushes/koons.png" onclick="changePaintBrush(36)">
<div class="imageContainer">
<div imageSrc="../content/brushes/koons.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">koons A</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/koons.png" onclick="changePaintBrush(37)">
<!--<button class="brushButton" brushType="repeat" id="content/brushes/koons.png" onclick="changePaintBrush(37)">
<div class="imageContainer">
<div imageSrc="../content/brushes/koons.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">koons B</div>
</button>
</button>-->
<button class="brushButton" brushType="stretch" id="content/brushes/oil.png" onclick="changePaintBrush(38)">
<div class="imageContainer">
<div imageSrc="../content/brushes/oil.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">oil A</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/oil.png" onclick="changePaintBrush(39)">
<!--<button class="brushButton" brushType="repeat" id="content/brushes/oil.png" onclick="changePaintBrush(39)">
<div class="imageContainer">
<div imageSrc="../content/brushes/oil.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">oil B</div>
</button>
</button>-->
<button class="brushButton" brushType="stretch" id="content/brushes/paintbrush1.png" onclick="changePaintBrush(40)">
<!--<button class="brushButton" brushType="stretch" id="content/brushes/paintbrush1.png" onclick="changePaintBrush(40)">
<div class="imageContainer">
<div imageSrc="../content/brushes/paintbrush1.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">paintbrush1 A</div>
</button>
</button>-->
<button class="brushButton" brushType="repeat" id="content/brushes/paintbrush1.png" onclick="changePaintBrush(41)">
<div class="imageContainer">
<div imageSrc="../content/brushes/paintbrush1.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">paintbrush1 B</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/paintbrush2.png" onclick="changePaintBrush(42)">
<!--<button class="brushButton" brushType="stretch" id="content/brushes/paintbrush2.png" onclick="changePaintBrush(42)">
<div class="imageContainer">
<div imageSrc="../content/brushes/paintbrush2.png" class="BrushIcon"></div>
</div>
@ -495,28 +633,22 @@
<div class="brushLabel">paintbrush5 A</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/paintbrush5.png" onclick="changePaintBrush(49)">
<!--<button class="brushButton" brushType="repeat" id="content/brushes/paintbrush5.png" onclick="changePaintBrush(49)">
<div class="imageContainer">
<div imageSrc="../content/brushes/paintbrush5.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">paintbrush5 B</div>
</button>
</button>-->
<button class="brushButton" brushType="stretch" id="content/brushes/paintbrush6.png" onclick="changePaintBrush(50)">
<div class="imageContainer">
<div imageSrc="../content/brushes/paintbrush6.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">paintbrush6 A</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/paintbrush6.png" onclick="changePaintBrush(51)">
<!--<button class="brushButton" brushType="repeat" id="content/brushes/paintbrush6.png" onclick="changePaintBrush(51)">
<div class="imageContainer">
<div imageSrc="../content/brushes/paintbrush6.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">paintbrush6 B</div>
</button>
<button class="brushButton" brushType="stretch" id="content/brushes/pastel.png" onclick="changePaintBrush(52)">
<!--<button class="brushButton" brushType="stretch" id="content/brushes/pastel.png" onclick="changePaintBrush(52)">
<div class="imageContainer">
<div imageSrc="../content/brushes/pastel.png" class="BrushIcon"></div>
</div>
@ -528,16 +660,9 @@
<div imageSrc="../content/brushes/pastel.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">pastel B</div>
</button>
</button>-->
<button class="brushButton" brushType="stretch" id="content/brushes/soft.png" onclick="changePaintBrush(54)">
<div class="imageContainer">
<div imageSrc="../content/brushes/soft.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">soft A</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/soft.png" onclick="changePaintBrush(55)">
<!--<button class="brushButton" brushType="repeat" id="content/brushes/soft.png" onclick="changePaintBrush(55)">
<div class="imageContainer">
<div imageSrc="../content/brushes/soft.png" class="BrushIcon"></div>
</div>
@ -556,30 +681,16 @@
<div imageSrc="../content/brushes/sponge.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">sponge B</div>
</button>
</button>-->
<button class="brushButton" brushType="stretch" id="content/brushes/square.png" onclick="changePaintBrush(58)">
<div class="imageContainer">
<div imageSrc="../content/brushes/square.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">square A</div>
</button>
<button class="brushButton" brushType="repeat" id="content/brushes/square.png" onclick="changePaintBrush(59)">
<!--<button class="brushButton" brushType="repeat" id="content/brushes/square.png" onclick="changePaintBrush(59)">
<div class="imageContainer">
<div imageSrc="../content/brushes/square.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">square B</div>
</button>
</button>-->
<button class="brushButton" colored="true" brushType="stretch" id="content/brushes/colored/breakfast.png" onclick="changePaintBrush(60)">
<div class="imageContainer">
<div imageSrc="../content/brushes/colored/breakfast.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">breakfast A</div>
</button>
<button class="brushButton" colored="true" brushType="repeat" id="content/brushes/colored/breakfast.png" onclick="changePaintBrush(61)">
<!--<button class="brushButton" colored="true" brushType="repeat" id="content/brushes/colored/breakfast.png" onclick="changePaintBrush(61)">
<div class="imageContainer">
<div imageSrc="../content/brushes/colored/breakfast.png" class="BrushIcon"></div>
</div>
@ -612,16 +723,11 @@
<div imageSrc="../content/brushes/colored/hawaii.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">hawaii B</div>
</button>
</button>-->
<button class="brushButton" colored="true" brushType="stretch" id="content/brushes/colored/newton.png" onclick="changePaintBrush(66)">
<div class="imageContainer">
<div imageSrc="../content/brushes/colored/newton.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">newton A</div>
</button>
<button class="brushButton" colored="true" brushType="repeat" id="content/brushes/colored/newton.png" onclick="changePaintBrush(67)">
<!--<button class="brushButton" colored="true" brushType="repeat" id="content/brushes/colored/newton.png" onclick="changePaintBrush(67)">
<div class="imageContainer">
<div imageSrc="../content/brushes/colored/newton.png" class="BrushIcon"></div>
</div>
@ -640,21 +746,14 @@
<div imageSrc="../content/brushes/colored/pastels.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">pastels B</div>
</button>
</button>-->
<button class="brushButton" colored="true" brushType="stretch" id="content/brushes/colored/softy.png" onclick="changePaintBrush(70)">
<div class="imageContainer">
<div imageSrc="../content/brushes/colored/softy.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">softy A</div>
</button>
<button class="brushButton" colored="true" brushType="repeat" id="content/brushes/colored/softy.png" onclick="changePaintBrush(71)">
<!--<button class="brushButton" colored="true" brushType="repeat" id="content/brushes/colored/softy.png" onclick="changePaintBrush(71)">
<div class="imageContainer">
<div imageSrc="../content/brushes/colored/softy.png" class="BrushIcon"></div>
</div>
<div class="brushLabel">softy B</div>
</button>
</button>-->
</div>
</div>
@ -662,6 +761,7 @@
<script type="text/javascript">
var currentBrush = 0;
setStrokeColor({red: 255, green: 0, blue: 0});
var EventBridge = parent.EventBridge;
function changeLineWidthRange(e) {
@ -685,6 +785,15 @@
parent.postMessage(JSON.stringify(changeLineWidthEvent), "*");
}
function switchPressureSensitiveWidth(checkbox) {
// 'jscolor' instance can be used as a string
var switchPressureSensitiveWidthEvent = {
"type" : "switchTriggerPressureWidth",
"enabled" : checkbox.checked,
};
parent.postMessage(JSON.stringify(switchPressureSensitiveWidthEvent), "*");
}
function changePaintBrush(brushIndex) {
var brushes = document.getElementById("brushesCointainer").children;
brushes[currentBrush].classList.remove("selectedBrush");
@ -710,8 +819,8 @@
parent.postMessage(JSON.stringify(changedBrushEvent), "*");
}
function calculateDynamicAxis(checkbox) {
if (checkbox.getAttribute("animationType") == "DynamicRotationBrush") {
function calculateAnimatedAxis(checkbox) {
if (checkbox.getAttribute("animationType") == "animatedRotationBrush") {
return {
axis: {
x: document.getElementById("pitchRotationBrush").checked ? 1 : 0,
@ -720,7 +829,7 @@
}
}
}
if (checkbox.getAttribute("animationType") == "DynamicTranslationBrush") {
if (checkbox.getAttribute("animationType") == "animatedTranslationBrush") {
return {
axis: {
x: document.getElementById("xTranslationBrush").checked ? 1 : 0,
@ -732,29 +841,73 @@
}
function calculateEnabledStatus(checkbox, settings) {
if (checkbox.getAttribute("animationType") == "DynamicHueBrush") {
if (checkbox.getAttribute("animationType") == "animatedHueBrush") {
return checkbox.checked;
}
return settings.axis.x == 1 || settings.axis.y == 1 || settings.axis.z == 1;
}
function setDynamicBrush(checkbox) {
var settings = calculateDynamicAxis(checkbox);
var switchDynamicBrushEvent = {
"type" : "switchDynamicBrush",
"dynamicBrushName": checkbox.getAttribute("animationType"),
function switchDynamicBrushEnabledStatus(checkbox) {
var isAnyAnimatedChecked = false;
$(".animationBrush").each(function( index ) {
isAnyAnimatedChecked |= $(this).find("input[type=checkbox]")[0].checked;
});
$(".dynamicBrush").each(function( index ) {
$(this).find("input[type=checkbox]")[0].disabled = isAnyAnimatedChecked;
});
}
function switchAnimationBrushEnabledStatus(checkbox) {
var isAnyDynamicChecked = false;
$(".dynamicBrush").each(function( index ) {
isAnyDynamicChecked |= $(this).find("input[type=checkbox]")[0].checked;
});
$(".animationBrush").each(function( index ) {
$(this).find("input[type=checkbox]")[0].disabled = isAnyDynamicChecked;
});
}
function setAnimatedBrush(checkbox) {
switchDynamicBrushEnabledStatus();
var settings = calculateAnimatedAxis(checkbox);
var switchAnimatedBrushEvent = {
"type" : "switchAnimatedBrush",
"animatedBrushName": checkbox.getAttribute("animationType"),
"enabled" : calculateEnabledStatus(checkbox, settings),
"settings" : settings,
"dynamicBrushID" : checkbox.id
"animatedBrushID" : checkbox.id
};
parent.postMessage(JSON.stringify(switchAnimatedBrushEvent), "*");
}
function setDynamicBrush(checkbox) {
switchAnimationBrushEnabledStatus();
var switchDynamicBrushEvent = {
"type" : "switchDynamicBrush",
"enabled" : checkbox.checked,
"dynamicBrushId" : checkbox.id
};
parent.postMessage(JSON.stringify(switchDynamicBrushEvent), "*");
}
function setContinuosLineMode(checkbox) {
var switchContinuousDrawModeEvent = {
"type" : "switchIsContinuous",
"enabled" : checkbox.checked,
};
parent.postMessage(JSON.stringify(switchContinuousDrawModeEvent), "*");
}
function resizeImage(image, width, height) {
var height = height == width ? "66px" : "33px";
var height = height == width ? "80px" : "40px";
image.css("height", height);
image.first().css("background-image", "url(" + image.attr('imageSrc') + ")");
image.first().css("background-size", "contain");
image.first().css("background-position", "center");
if (height == "40px") {
image.first().css("top", "18px");
image.first().css("position", "absolute");
}
}
function setStrokeColor(strokeColor) {
@ -780,11 +933,19 @@
changePaintBrush(brushData.currentTexture.brushID);
}
if ("dynamicBrushes" in brushData) {
var dynamicBrushes = brushData.currentDynamicBrushes;
for (var i = 0; i < dynamicBrushes.length; i++) {
document.getElementById(dynamicBrushes[i]).checked = true;
if ("currentAnimatedBrushes" in brushData) {
var animatedBrushes = brushData.currentAnimatedBrushes;
for (var i = 0; i < animatedBrushes.length; i++) {
document.getElementById(animatedBrushes[i]).checked = true;
}
switchDynamicBrushEnabledStatus();
}
if ("currentDynamicBrushes" in brushData) {
for(var key in brushData.currentDynamicBrushes) {
document.getElementById(key).checked = brushData.currentDynamicBrushes[key];
}
switchAnimationBrushEnabledStatus();
}
if ("currentColor" in brushData) {
@ -796,6 +957,14 @@
changeLineWidthRange({value: brushData.currentStrokeWidth});
changeLineWidthNumber({value: brushData.currentStrokeWidth});
}
if ("currentTriggerWidthEnabled" in brushData) {
document.getElementById("triggerSensitiveWidth").checked = brushData.currentTriggerWidthEnabled;
}
if ("currentIsContinuous" in brushData) {
document.getElementById("continuousLine").checked = brushData.currentIsContinuous;
}
}

View file

@ -17,7 +17,10 @@
margin: 2px;
text-transform: uppercase;
font-size: 100px;
font-family: HiFi-Glyphs;
background-image: url("../content/tabicons/hand-icon.svg");
background-size: 60% 60%;
background-repeat: no-repeat;
background-position: center;
}
.changeHandButton:first-child {
@ -34,8 +37,8 @@
}
</style>
<div id="handButtonsContainer" >
<button class="changeHandButton glyph" id="left" onclick="chooseHand(0)">&#57;</button>
<button class="changeHandButton selectedHand" id="right" onclick="chooseHand(1)">&#57;</button>
<button class="changeHandButton" id="left" onclick="chooseHand(0)"></button>
<button class="changeHandButton selectedHand" id="right" onclick="chooseHand(1)"></button>
</div>
<script type="text/javascript">

View file

@ -38,11 +38,6 @@
background-size: contain;
}
</style>
<div class="behavior-group property checkbox">
<input onchange="switchPressureSensitiveWidth(this)" type="checkbox" id="triggerSensitiveWidth"></input>
<label for="triggerSensitiveWidth">Use Trigger Sensitive Width</label>
</div>
<div id="colorpicker"></div>
<div id="colorPickerTable"></div>
<div id="lastPickedColors"></div>
@ -129,15 +124,6 @@
update(colorArray);
}
function switchPressureSensitiveWidth(checkbox) {
// 'jscolor' instance can be used as a string
var switchPressureSensitiveWidthEvent = {
"type" : "switchTriggerPressureWidth",
"enabled" : checkbox.checked,
};
parent.postMessage(JSON.stringify(switchPressureSensitiveWidthEvent), "*");
}
function selectButton(button) {
if (lastSelectedButton != null) {
lastSelectedButton.removeChild(document.getElementById("selectedOverlay"));
@ -216,10 +202,6 @@
currentSelectedColorOrigin = newColor.origin;
setColorInTable([newColor.red, newColor.green, newColor.blue]);
}
if ("currentTriggerWidthEnabled" in palleteData) {
document.getElementById("triggerSensitiveWidth").checked = palleteData.currentTriggerWidthEnabled;
}
}
function setColorInTable(colorArray) {

View file

@ -22,7 +22,8 @@
.tabButton {
background-color: #000;
color: white;
font-size: 20px;
font-size: 14px;
line-height: 24px;
padding: 12px;
margin: 0px;
vertical-align: middle;
@ -53,7 +54,7 @@
<div id="tabs">
<div class="tabButton" onclick="selectTab(0)"><img class="tabIcon" src="../content/tabicons/palette-icon.svg"/>Palette</div>
<div class="tabButton" onclick="selectTab(1)"><img class="tabIcon" src="../content/tabicons/brush-icon.svg"/>Brushes</div>
<div class="tabButton" onclick="selectTab(2)"><img class="tabIcon" src="../content/tabicons/pointingfinger128px.png"/>Hand</div>
<div class="tabButton" onclick="selectTab(2)"><img class="tabIcon" src="../content/tabicons/hand-icon.svg"/>Hand</div>
<input type="button" onclick="undo()" id="undoButton" style="font-family: Font-Awesome;" disabled class="grayButton glyph" value="&#xf064;"/>
</div>
<div id="content">