mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 20:58:38 +02:00
Merge pull request #5482 from ericrius1/polyLineInProgress
Added PolyLine Entity and painting scripts to demonstrate its functionality (WARNING: protocol change) Test this please
This commit is contained in:
commit
74287c3cf5
36 changed files with 1305 additions and 29 deletions
225
examples/example/painting/hydraPaint.js
Normal file
225
examples/example/painting/hydraPaint.js
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
//
|
||||||
|
// hydraPaint.js
|
||||||
|
// examples
|
||||||
|
//
|
||||||
|
// Created by Eric Levin on 5/14/15.
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// This script allows you to paint with the hydra!
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
var LEFT = 0;
|
||||||
|
var RIGHT = 1;
|
||||||
|
var LASER_WIDTH = 3;
|
||||||
|
var LASER_COLOR = {
|
||||||
|
red: 50,
|
||||||
|
green: 150,
|
||||||
|
blue: 200
|
||||||
|
};
|
||||||
|
var TRIGGER_THRESHOLD = .1;
|
||||||
|
|
||||||
|
var MAX_POINTS_PER_LINE = 40;
|
||||||
|
|
||||||
|
var LIFETIME = 6000;
|
||||||
|
var DRAWING_DEPTH = 1;
|
||||||
|
var LINE_DIMENSIONS = 20;
|
||||||
|
|
||||||
|
|
||||||
|
var MIN_POINT_DISTANCE = 0.01;
|
||||||
|
|
||||||
|
var MIN_BRUSH_RADIUS = 0.08;
|
||||||
|
var MAX_BRUSH_RADIUS = 0.1;
|
||||||
|
|
||||||
|
var RIGHT_BUTTON_1 = 7
|
||||||
|
var RIGHT_BUTTON_2 = 8
|
||||||
|
var RIGHT_BUTTON_3 = 9;
|
||||||
|
var RIGHT_BUTTON_4 = 10
|
||||||
|
var LEFT_BUTTON_1 = 1;
|
||||||
|
var LEFT_BUTTON_2 = 2;
|
||||||
|
var LEFT_BUTTON_3 = 3;
|
||||||
|
var LEFT_BUTTON_4 = 4;
|
||||||
|
|
||||||
|
var colorPalette = [{
|
||||||
|
red: 250,
|
||||||
|
green: 0,
|
||||||
|
blue: 0
|
||||||
|
}, {
|
||||||
|
red: 214,
|
||||||
|
green: 91,
|
||||||
|
blue: 67
|
||||||
|
}, {
|
||||||
|
red: 192,
|
||||||
|
green: 41,
|
||||||
|
blue: 66
|
||||||
|
}, {
|
||||||
|
red: 84,
|
||||||
|
green: 36,
|
||||||
|
blue: 55
|
||||||
|
}, {
|
||||||
|
red: 83,
|
||||||
|
green: 119,
|
||||||
|
blue: 122
|
||||||
|
}];
|
||||||
|
|
||||||
|
var MIN_STROKE_WIDTH = 0.002;
|
||||||
|
var MAX_STROKE_WIDTH = 0.05;
|
||||||
|
|
||||||
|
function controller(side, cycleColorButton) {
|
||||||
|
this.triggerHeld = false;
|
||||||
|
this.triggerThreshold = 0.9;
|
||||||
|
this.side = side;
|
||||||
|
this.palm = 2 * side;
|
||||||
|
this.tip = 2 * side + 1;
|
||||||
|
this.trigger = side;
|
||||||
|
this.cycleColorButton = cycleColorButton;
|
||||||
|
|
||||||
|
this.points = [];
|
||||||
|
this.normals = [];
|
||||||
|
this.strokeWidths = [];
|
||||||
|
|
||||||
|
this.currentColorIndex = 0;
|
||||||
|
this.currentColor = colorPalette[this.currentColorIndex];
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
|
||||||
|
this.brush = Entities.addEntity({
|
||||||
|
type: 'Sphere',
|
||||||
|
position: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
},
|
||||||
|
color: this.currentColor,
|
||||||
|
dimensions: {
|
||||||
|
x: MIN_BRUSH_RADIUS,
|
||||||
|
y: MIN_BRUSH_RADIUS,
|
||||||
|
z: MIN_BRUSH_RADIUS
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.cycleColor = function() {
|
||||||
|
this.currentColor = colorPalette[++this.currentColorIndex];
|
||||||
|
if (this.currentColorIndex === colorPalette.length - 1) {
|
||||||
|
this.currentColorIndex = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.newLine = function(position) {
|
||||||
|
this.linePosition = position;
|
||||||
|
this.line = Entities.addEntity({
|
||||||
|
position: position,
|
||||||
|
type: "PolyLine",
|
||||||
|
color: this.currentColor,
|
||||||
|
dimensions: {
|
||||||
|
x: LINE_DIMENSIONS,
|
||||||
|
y: LINE_DIMENSIONS,
|
||||||
|
z: LINE_DIMENSIONS
|
||||||
|
},
|
||||||
|
lifetime: LIFETIME
|
||||||
|
});
|
||||||
|
this.points = [];
|
||||||
|
this.normals = []
|
||||||
|
this.strokeWidths = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.update = function(deltaTime) {
|
||||||
|
this.updateControllerState();
|
||||||
|
var newBrushPosOffset = Vec3.multiply(Vec3.normalize(Vec3.subtract(this.tipPosition, this.palmPosition)), DRAWING_DEPTH);
|
||||||
|
var newBrushPos = Vec3.sum(this.palmPosition, newBrushPosOffset);
|
||||||
|
var brushRadius = map(this.triggerValue, TRIGGER_THRESHOLD, 1, MIN_BRUSH_RADIUS, MAX_BRUSH_RADIUS)
|
||||||
|
Entities.editEntity(this.brush, {
|
||||||
|
position: newBrushPos,
|
||||||
|
color: this.currentColor,
|
||||||
|
dimensions: {
|
||||||
|
x: brushRadius,
|
||||||
|
y: brushRadius,
|
||||||
|
z: brushRadius
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
if (this.triggerValue > TRIGGER_THRESHOLD && !this.drawing) {
|
||||||
|
this.newLine(newBrushPos);
|
||||||
|
this.drawing = true;
|
||||||
|
} else if (this.drawing && this.triggerValue < TRIGGER_THRESHOLD) {
|
||||||
|
this.drawing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.drawing && this.points.length < MAX_POINTS_PER_LINE) {
|
||||||
|
var localPoint = Vec3.subtract(newBrushPos, this.linePosition);
|
||||||
|
if (Vec3.distance(localPoint, this.points[this.points.length - 1]) < MIN_POINT_DISTANCE) {
|
||||||
|
//Need a minimum distance to avoid binormal NANs
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.points.push(localPoint);
|
||||||
|
var normal = computeNormal(newBrushPos, Camera.getPosition());
|
||||||
|
|
||||||
|
this.normals.push(normal);
|
||||||
|
var strokeWidth = map(this.triggerValue, TRIGGER_THRESHOLD, 1, MIN_STROKE_WIDTH, MAX_STROKE_WIDTH);
|
||||||
|
this.strokeWidths.push(strokeWidth);
|
||||||
|
Entities.editEntity(this.line, {
|
||||||
|
linePoints: this.points,
|
||||||
|
normals: this.normals,
|
||||||
|
strokeWidths: this.strokeWidths,
|
||||||
|
color: this.currentColor
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.updateControllerState = function() {
|
||||||
|
this.cycleColorButtonPressed = Controller.isButtonPressed(this.cycleColorButton);
|
||||||
|
this.palmPosition = Controller.getSpatialControlPosition(this.palm);
|
||||||
|
this.tipPosition = Controller.getSpatialControlPosition(this.tip);
|
||||||
|
this.palmNormal = Controller.getSpatialControlNormal(this.palm);
|
||||||
|
this.triggerValue = Controller.getTriggerValue(this.trigger);
|
||||||
|
|
||||||
|
|
||||||
|
if (this.prevCycleColorButtonPressed === true && this.cycleColorButtonPressed === false) {
|
||||||
|
this.cycleColor();
|
||||||
|
Entities.editEntity(this.brush, {
|
||||||
|
// color: this.currentColor
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.prevCycleColorButtonPressed = this.cycleColorButtonPressed;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cleanup = function() {
|
||||||
|
Entities.deleteEntity(self.brush);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeNormal(p1, p2) {
|
||||||
|
return Vec3.normalize(Vec3.subtract(p2, p1));
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(deltaTime) {
|
||||||
|
leftController.update(deltaTime);
|
||||||
|
rightController.update(deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
function scriptEnding() {
|
||||||
|
leftController.cleanup();
|
||||||
|
rightController.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
function vectorIsZero(v) {
|
||||||
|
return v.x === 0 && v.y === 0 && v.z === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var rightController = new controller(RIGHT, RIGHT_BUTTON_4);
|
||||||
|
var leftController = new controller(LEFT, LEFT_BUTTON_4);
|
||||||
|
Script.update.connect(update);
|
||||||
|
Script.scriptEnding.connect(scriptEnding);
|
||||||
|
|
||||||
|
function map(value, min1, max1, min2, max2) {
|
||||||
|
return min2 + (max2 - min2) * ((value - min1) / (max1 - min1));
|
||||||
|
}
|
194
examples/example/painting/mousePaint.js
Normal file
194
examples/example/painting/mousePaint.js
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
//
|
||||||
|
// mousePaint.js
|
||||||
|
// examples
|
||||||
|
//
|
||||||
|
// Created by Eric Levin on 6/4/15.
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// This script allows you to paint with the hydra or mouse!
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
|
||||||
|
var LINE_DIMENSIONS = 10;
|
||||||
|
var LIFETIME = 6000;
|
||||||
|
var EVENT_CHANGE_THRESHOLD = 200;
|
||||||
|
var LINE_WIDTH = .07;
|
||||||
|
var MAX_POINTS_PER_LINE = 40;
|
||||||
|
var points = [];
|
||||||
|
var normals = [];
|
||||||
|
var deletedLines = [];
|
||||||
|
var strokeWidths = [];
|
||||||
|
var count = 0;
|
||||||
|
var prevEvent = {x: 0, y: 0};
|
||||||
|
var eventChange;
|
||||||
|
|
||||||
|
var MIN_POINT_DISTANCE = .01;
|
||||||
|
|
||||||
|
var colorPalette = [{
|
||||||
|
red: 250,
|
||||||
|
green: 0,
|
||||||
|
blue: 0
|
||||||
|
}, {
|
||||||
|
red: 214,
|
||||||
|
green: 91,
|
||||||
|
blue: 67
|
||||||
|
}, {
|
||||||
|
red: 192,
|
||||||
|
green: 41,
|
||||||
|
blue: 66
|
||||||
|
}, {
|
||||||
|
red: 84,
|
||||||
|
green: 36,
|
||||||
|
blue: 55
|
||||||
|
}, {
|
||||||
|
red: 83,
|
||||||
|
green: 119,
|
||||||
|
blue: 122
|
||||||
|
}];
|
||||||
|
|
||||||
|
var currentColorIndex = 0;
|
||||||
|
var currentColor = colorPalette[currentColorIndex];
|
||||||
|
|
||||||
|
function cycleColor() {
|
||||||
|
currentColor = colorPalette[++currentColorIndex];
|
||||||
|
if (currentColorIndex === colorPalette.length - 1) {
|
||||||
|
currentColorIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MousePaint();
|
||||||
|
|
||||||
|
function MousePaint() {
|
||||||
|
var DRAWING_DISTANCE = 5;
|
||||||
|
var lines = [];
|
||||||
|
var isDrawing = false;
|
||||||
|
|
||||||
|
var line, linePosition;
|
||||||
|
|
||||||
|
var BRUSH_SIZE = .05;
|
||||||
|
|
||||||
|
var brush = Entities.addEntity({
|
||||||
|
type: 'Sphere',
|
||||||
|
position: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
},
|
||||||
|
color: currentColor,
|
||||||
|
dimensions: {
|
||||||
|
x: BRUSH_SIZE,
|
||||||
|
y: BRUSH_SIZE,
|
||||||
|
z: BRUSH_SIZE
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function newLine(position) {
|
||||||
|
linePosition = position;
|
||||||
|
line = Entities.addEntity({
|
||||||
|
position: position,
|
||||||
|
type: "PolyLine",
|
||||||
|
color: currentColor,
|
||||||
|
dimensions: {
|
||||||
|
x: LINE_DIMENSIONS,
|
||||||
|
y: LINE_DIMENSIONS,
|
||||||
|
z: LINE_DIMENSIONS
|
||||||
|
},
|
||||||
|
linePoints: [],
|
||||||
|
lifetime: LIFETIME
|
||||||
|
});
|
||||||
|
points = [];
|
||||||
|
normals = []
|
||||||
|
strokeWidths = [];
|
||||||
|
lines.push(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function mouseMoveEvent(event) {
|
||||||
|
|
||||||
|
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||||
|
count++;
|
||||||
|
var worldPoint = computeWorldPoint(pickRay);
|
||||||
|
Entities.editEntity(brush, {
|
||||||
|
position: worldPoint
|
||||||
|
});
|
||||||
|
|
||||||
|
eventChange = Math.sqrt(Math.pow(event.x - prevEvent.x, 2) + Math.pow(event.y - prevEvent.y, 2));
|
||||||
|
localPoint = computeLocalPoint(worldPoint);
|
||||||
|
if (!isDrawing || points.length > MAX_POINTS_PER_LINE || eventChange > EVENT_CHANGE_THRESHOLD ||
|
||||||
|
Vec3.distance(points[points.length - 1], localPoint) < MIN_POINT_DISTANCE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
points.push(localPoint)
|
||||||
|
normals.push(computeNormal(worldPoint, pickRay.origin));
|
||||||
|
strokeWidths.push(LINE_WIDTH);
|
||||||
|
Entities.editEntity(line, {
|
||||||
|
strokeWidths: strokeWidths,
|
||||||
|
linePoints: points,
|
||||||
|
normals: normals,
|
||||||
|
});
|
||||||
|
prevEvent = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeNormal(p1, p2) {
|
||||||
|
return Vec3.normalize(Vec3.subtract(p2, p1));
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeWorldPoint(pickRay) {
|
||||||
|
var addVector = Vec3.multiply(Vec3.normalize(pickRay.direction), DRAWING_DISTANCE);
|
||||||
|
return Vec3.sum(pickRay.origin, addVector);
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeLocalPoint(worldPoint) {
|
||||||
|
var localPoint = Vec3.subtract(worldPoint, linePosition);
|
||||||
|
return localPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mousePressEvent(event) {
|
||||||
|
if (!event.isLeftButton) {
|
||||||
|
isDrawing = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||||
|
prevEvent = {x: event.x, y:event.y};
|
||||||
|
var worldPoint = computeWorldPoint(pickRay);
|
||||||
|
newLine(worldPoint);
|
||||||
|
var localPoint = computeLocalPoint(worldPoint);
|
||||||
|
points.push(localPoint);
|
||||||
|
normals.push(computeNormal(worldPoint, pickRay.origin));
|
||||||
|
strokeWidths.push(0.07);
|
||||||
|
isDrawing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseReleaseEvent() {
|
||||||
|
isDrawing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function keyPressEvent(event) {
|
||||||
|
if (event.text === "SPACE") {
|
||||||
|
cycleColor();
|
||||||
|
Entities.editEntity(brush, {
|
||||||
|
color: currentColor
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanup() {
|
||||||
|
lines.forEach(function(line) {
|
||||||
|
// Entities.deleteEntity(line);
|
||||||
|
});
|
||||||
|
Entities.deleteEntity(brush);
|
||||||
|
}
|
||||||
|
|
||||||
|
Controller.mousePressEvent.connect(mousePressEvent);
|
||||||
|
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
|
||||||
|
Controller.mouseMoveEvent.connect(mouseMoveEvent);
|
||||||
|
Script.scriptEnding.connect(cleanup);
|
||||||
|
|
||||||
|
Controller.keyPressEvent.connect(keyPressEvent);
|
||||||
|
}
|
BIN
interface/resources/images/paintStroke.png
Normal file
BIN
interface/resources/images/paintStroke.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
|
@ -793,7 +793,7 @@ void Application::initializeGL() {
|
||||||
init();
|
init();
|
||||||
qCDebug(interfaceapp, "init() complete.");
|
qCDebug(interfaceapp, "init() complete.");
|
||||||
|
|
||||||
// create thread for parsing of octee data independent of the main network and rendering threads
|
// create thread for parsing of octree data independent of the main network and rendering threads
|
||||||
_octreeProcessor.initialize(_enableProcessOctreeThread);
|
_octreeProcessor.initialize(_enableProcessOctreeThread);
|
||||||
connect(&_octreeProcessor, &OctreePacketProcessor::packetVersionMismatch, this, &Application::notifyPacketVersionMismatch);
|
connect(&_octreeProcessor, &OctreePacketProcessor::packetVersionMismatch, this, &Application::notifyPacketVersionMismatch);
|
||||||
_entityEditSender.initialize(_enableProcessOctreeThread);
|
_entityEditSender.initialize(_enableProcessOctreeThread);
|
||||||
|
|
78
libraries/entities-renderer/src/DeferredBufferWrite.slh
Executable file
78
libraries/entities-renderer/src/DeferredBufferWrite.slh
Executable file
|
@ -0,0 +1,78 @@
|
||||||
|
<!
|
||||||
|
// DeferredBufferWrite.slh
|
||||||
|
// libraries/render-utils/src
|
||||||
|
//
|
||||||
|
// Created by Sam Gateau on 1/12/15.
|
||||||
|
// 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
|
||||||
|
!>
|
||||||
|
<@if not DEFERRED_BUFFER_WRITE_SLH@>
|
||||||
|
<@def DEFERRED_BUFFER_WRITE_SLH@>
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 _fragColor0;
|
||||||
|
layout(location = 1) out vec4 _fragColor1;
|
||||||
|
layout(location = 2) out vec4 _fragColor2;
|
||||||
|
|
||||||
|
// the glow intensity
|
||||||
|
uniform float glowIntensity;
|
||||||
|
|
||||||
|
// the alpha threshold
|
||||||
|
uniform float alphaThreshold;
|
||||||
|
|
||||||
|
uniform sampler2D normalFittingMap;
|
||||||
|
|
||||||
|
vec3 bestFitNormal(vec3 normal) {
|
||||||
|
vec3 absNorm = abs(normal);
|
||||||
|
float maxNAbs = max(absNorm.z, max(absNorm.x, absNorm.y));
|
||||||
|
|
||||||
|
vec2 texcoord = (absNorm.z < maxNAbs ?
|
||||||
|
(absNorm.y < maxNAbs ? absNorm.yz : absNorm.xz) :
|
||||||
|
absNorm.xy);
|
||||||
|
texcoord = (texcoord.x < texcoord.y ? texcoord.yx : texcoord.xy);
|
||||||
|
texcoord.y /= texcoord.x;
|
||||||
|
vec3 cN = normal / maxNAbs;
|
||||||
|
float fittingScale = texture(normalFittingMap, texcoord).a;
|
||||||
|
cN *= fittingScale;
|
||||||
|
return (cN * 0.5 + 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
float evalOpaqueFinalAlpha(float alpha, float mapAlpha) {
|
||||||
|
return mix(alpha * glowIntensity, 1.0 - alpha * glowIntensity, step(mapAlpha, alphaThreshold));
|
||||||
|
}
|
||||||
|
|
||||||
|
const vec3 DEFAULT_SPECULAR = vec3(0.1);
|
||||||
|
const float DEFAULT_SHININESS = 10;
|
||||||
|
|
||||||
|
void packDeferredFragment(vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess) {
|
||||||
|
if (alpha != glowIntensity) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
_fragColor0 = vec4(diffuse.rgb, alpha);
|
||||||
|
_fragColor1 = vec4(bestFitNormal(normal), 1.0);
|
||||||
|
_fragColor2 = vec4(specular, shininess / 128.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess, vec3 emissive) {
|
||||||
|
if (alpha != glowIntensity) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
|
||||||
|
_fragColor0 = vec4(diffuse.rgb, alpha);
|
||||||
|
//_fragColor1 = vec4(normal, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
|
||||||
|
_fragColor1 = vec4(bestFitNormal(normal), 0.5);
|
||||||
|
_fragColor2 = vec4(emissive, shininess / 128.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void packDeferredFragmentTranslucent(vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess) {
|
||||||
|
if (alpha <= alphaThreshold) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
|
||||||
|
_fragColor0 = vec4(diffuse.rgb, alpha);
|
||||||
|
// _fragColor1 = vec4(normal, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
|
||||||
|
// _fragColor2 = vec4(specular, shininess / 128.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
<@endif@>
|
|
@ -38,6 +38,7 @@
|
||||||
#include "RenderableZoneEntityItem.h"
|
#include "RenderableZoneEntityItem.h"
|
||||||
#include "RenderableLineEntityItem.h"
|
#include "RenderableLineEntityItem.h"
|
||||||
#include "RenderablePolyVoxEntityItem.h"
|
#include "RenderablePolyVoxEntityItem.h"
|
||||||
|
#include "RenderablePolyLineEntityItem.h"
|
||||||
#include "EntitiesRendererLogging.h"
|
#include "EntitiesRendererLogging.h"
|
||||||
#include "AddressManager.h"
|
#include "AddressManager.h"
|
||||||
#include "EntityRig.h"
|
#include "EntityRig.h"
|
||||||
|
@ -66,6 +67,7 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf
|
||||||
REGISTER_ENTITY_TYPE_WITH_FACTORY(Zone, RenderableZoneEntityItem::factory)
|
REGISTER_ENTITY_TYPE_WITH_FACTORY(Zone, RenderableZoneEntityItem::factory)
|
||||||
REGISTER_ENTITY_TYPE_WITH_FACTORY(Line, RenderableLineEntityItem::factory)
|
REGISTER_ENTITY_TYPE_WITH_FACTORY(Line, RenderableLineEntityItem::factory)
|
||||||
REGISTER_ENTITY_TYPE_WITH_FACTORY(PolyVox, RenderablePolyVoxEntityItem::factory)
|
REGISTER_ENTITY_TYPE_WITH_FACTORY(PolyVox, RenderablePolyVoxEntityItem::factory)
|
||||||
|
REGISTER_ENTITY_TYPE_WITH_FACTORY(PolyLine, RenderablePolyLineEntityItem::factory)
|
||||||
|
|
||||||
_currentHoverOverEntityID = UNKNOWN_ENTITY_ID;
|
_currentHoverOverEntityID = UNKNOWN_ENTITY_ID;
|
||||||
_currentClickingOnEntityID = UNKNOWN_ENTITY_ID;
|
_currentClickingOnEntityID = UNKNOWN_ENTITY_ID;
|
||||||
|
|
|
@ -18,6 +18,9 @@ namespace render {
|
||||||
if (payload->entity->getType() == EntityTypes::Light) {
|
if (payload->entity->getType() == EntityTypes::Light) {
|
||||||
return ItemKey::Builder::light();
|
return ItemKey::Builder::light();
|
||||||
}
|
}
|
||||||
|
if (payload && payload->entity->getType() == EntityTypes::PolyLine) {
|
||||||
|
return ItemKey::Builder::transparentShape();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ItemKey::Builder::opaqueShape();
|
return ItemKey::Builder::opaqueShape();
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,9 @@ void RenderableLineEntityItem::updateGeometry() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void RenderableLineEntityItem::render(RenderArgs* args) {
|
void RenderableLineEntityItem::render(RenderArgs* args) {
|
||||||
PerformanceTimer perfTimer("RenderableLineEntityItem::render");
|
PerformanceTimer perfTimer("RenderableLineEntityItem::render");
|
||||||
Q_ASSERT(getType() == EntityTypes::Line);
|
Q_ASSERT(getType() == EntityTypes::Line);
|
||||||
|
|
158
libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp
Normal file
158
libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
//
|
||||||
|
// RenderablePolyLineEntityItem.cpp
|
||||||
|
// libraries/entities-renderer/src/
|
||||||
|
//
|
||||||
|
// Created by Eric Levin on 8/10/15
|
||||||
|
// Copyright 2015 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 <glm/gtx/quaternion.hpp>
|
||||||
|
|
||||||
|
#include <GeometryCache.h>
|
||||||
|
#include <TextureCache.h>
|
||||||
|
#include <PathUtils.h>
|
||||||
|
#include <DeferredLightingEffect.h>
|
||||||
|
#include <PerfStat.h>
|
||||||
|
|
||||||
|
#include "RenderablePolyLineEntityItem.h"
|
||||||
|
|
||||||
|
#include "paintStroke_vert.h"
|
||||||
|
#include "paintStroke_frag.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
EntityItemPointer RenderablePolyLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
|
return EntityItemPointer(new RenderablePolyLineEntityItem(entityID, properties));
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderablePolyLineEntityItem::RenderablePolyLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||||
|
PolyLineEntityItem(entityItemID, properties) {
|
||||||
|
_numVertices = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
gpu::PipelinePointer RenderablePolyLineEntityItem::_pipeline;
|
||||||
|
gpu::Stream::FormatPointer RenderablePolyLineEntityItem::_format;
|
||||||
|
gpu::TexturePointer RenderablePolyLineEntityItem::_texture;
|
||||||
|
GLint RenderablePolyLineEntityItem::PAINTSTROKE_GPU_SLOT;
|
||||||
|
|
||||||
|
void RenderablePolyLineEntityItem::createPipeline() {
|
||||||
|
static const int NORMAL_OFFSET = 12;
|
||||||
|
static const int COLOR_OFFSET = 24;
|
||||||
|
static const int TEXTURE_OFFSET = 28;
|
||||||
|
|
||||||
|
auto textureCache = DependencyManager::get<TextureCache>();
|
||||||
|
QString path = PathUtils::resourcesPath() + "images/paintStroke.png";
|
||||||
|
_texture = textureCache->getImageTexture(path);
|
||||||
|
_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::COLOR, 0, gpu::Element::COLOR_RGBA_32, COLOR_OFFSET);
|
||||||
|
_format->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), TEXTURE_OFFSET);
|
||||||
|
|
||||||
|
auto VS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(paintStroke_vert)));
|
||||||
|
auto PS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(paintStroke_frag)));
|
||||||
|
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PS));
|
||||||
|
|
||||||
|
gpu::Shader::BindingSet slotBindings;
|
||||||
|
PAINTSTROKE_GPU_SLOT = 0;
|
||||||
|
slotBindings.insert(gpu::Shader::Binding(std::string("paintStrokeTextureBinding"), PAINTSTROKE_GPU_SLOT));
|
||||||
|
gpu::Shader::makeProgram(*program, slotBindings);
|
||||||
|
|
||||||
|
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||||
|
state->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||||
|
state->setBlendFunction(true,
|
||||||
|
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||||
|
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||||
|
_pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderablePolyLineEntityItem::updateGeometry() {
|
||||||
|
_numVertices = 0;
|
||||||
|
_verticesBuffer.reset(new gpu::Buffer());
|
||||||
|
int vertexIndex = 0;
|
||||||
|
vec2 uv;
|
||||||
|
float tailStart = 0.0f;
|
||||||
|
float tailEnd = 0.25f;
|
||||||
|
float tailLength = tailEnd - tailStart;
|
||||||
|
|
||||||
|
float headStart = 0.76f;
|
||||||
|
float headEnd = 1.0f;
|
||||||
|
float headLength = headEnd - headStart;
|
||||||
|
float uCoord, vCoord;
|
||||||
|
|
||||||
|
int numTailStrips = 5;
|
||||||
|
int numHeadStrips = 10;
|
||||||
|
int startHeadIndex = _normals.size() - numHeadStrips;
|
||||||
|
for (int i = 0; i < _normals.size(); i++) {
|
||||||
|
uCoord = 0.26f;
|
||||||
|
vCoord = 0.0f;
|
||||||
|
//tail
|
||||||
|
if(i < numTailStrips) {
|
||||||
|
uCoord = float(i)/numTailStrips * tailLength + tailStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
//head
|
||||||
|
if( i > startHeadIndex) {
|
||||||
|
uCoord = float( (i+ 1) - startHeadIndex)/numHeadStrips * headLength + headStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
uv = vec2(uCoord, vCoord);
|
||||||
|
|
||||||
|
_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(int), (gpu::Byte*)&_color);
|
||||||
|
_verticesBuffer->append(sizeof(glm::vec2), (gpu::Byte*)&uv);
|
||||||
|
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(int), (gpu::Byte*)_color);
|
||||||
|
_verticesBuffer->append(sizeof(glm::vec2), (const gpu::Byte*)&uv);
|
||||||
|
vertexIndex++;
|
||||||
|
|
||||||
|
_numVertices +=2;
|
||||||
|
}
|
||||||
|
_pointsChanged = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RenderablePolyLineEntityItem::render(RenderArgs* args) {
|
||||||
|
QWriteLocker lock(&_quadReadWriteLock);
|
||||||
|
if (_points.size() < 2 || _vertices.size() != _normals.size() * 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_pipeline) {
|
||||||
|
createPipeline();
|
||||||
|
}
|
||||||
|
|
||||||
|
PerformanceTimer perfTimer("RenderablePolyLineEntityItem::render");
|
||||||
|
Q_ASSERT(getType() == EntityTypes::PolyLine);
|
||||||
|
|
||||||
|
Q_ASSERT(args->_batch);
|
||||||
|
if (_pointsChanged) {
|
||||||
|
updateGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
|
gpu::Batch& batch = *args->_batch;
|
||||||
|
Transform transform = Transform();
|
||||||
|
transform.setTranslation(getPosition());
|
||||||
|
transform.setRotation(getRotation());
|
||||||
|
batch.setModelTransform(transform);
|
||||||
|
|
||||||
|
batch.setPipeline(_pipeline);
|
||||||
|
batch.setResourceTexture(PAINTSTROKE_GPU_SLOT, _texture);
|
||||||
|
|
||||||
|
batch.setInputFormat(_format);
|
||||||
|
batch.setInputBuffer(0, _verticesBuffer, 0, _format->getChannels().at(0)._stride);
|
||||||
|
|
||||||
|
batch.draw(gpu::TRIANGLE_STRIP, _numVertices, 0);
|
||||||
|
|
||||||
|
RenderableDebugableEntityItem::render(this, args);
|
||||||
|
};
|
|
@ -0,0 +1,47 @@
|
||||||
|
//
|
||||||
|
// RenderablePolyLineEntityItem.h
|
||||||
|
// libraries/entities-renderer/src/
|
||||||
|
//
|
||||||
|
// Created by Eric Levin on 6/22/15.
|
||||||
|
// Copyright 2015 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_RenderablePolyLineEntityItem_h
|
||||||
|
#define hifi_RenderablePolyLineEntityItem_h
|
||||||
|
|
||||||
|
#include <gpu/Batch.h>
|
||||||
|
#include <PolyLineEntityItem.h>
|
||||||
|
#include "RenderableDebugableEntityItem.h"
|
||||||
|
#include "RenderableEntityItem.h"
|
||||||
|
#include <GeometryCache.h>
|
||||||
|
#include <QReadWriteLock>
|
||||||
|
#include <gpu/GPUConfig.h>
|
||||||
|
|
||||||
|
|
||||||
|
class RenderablePolyLineEntityItem : public PolyLineEntityItem {
|
||||||
|
public:
|
||||||
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
static void createPipeline();
|
||||||
|
RenderablePolyLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
|
virtual void render(RenderArgs* args);
|
||||||
|
|
||||||
|
SIMPLE_RENDERABLE();
|
||||||
|
|
||||||
|
static gpu::PipelinePointer _pipeline;
|
||||||
|
static gpu::Stream::FormatPointer _format;
|
||||||
|
static gpu::TexturePointer _texture;
|
||||||
|
static GLint PAINTSTROKE_GPU_SLOT;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void updateGeometry();
|
||||||
|
gpu::BufferPointer _verticesBuffer;
|
||||||
|
unsigned int _numVertices;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // hifi_RenderablePolyLineEntityItem_h
|
|
@ -40,7 +40,7 @@
|
||||||
#include "EntityTreeRenderer.h"
|
#include "EntityTreeRenderer.h"
|
||||||
#include "polyvox_vert.h"
|
#include "polyvox_vert.h"
|
||||||
#include "polyvox_frag.h"
|
#include "polyvox_frag.h"
|
||||||
#include "RenderablePolyVoxEntityItem.h"
|
#include "RenderablePolyVoxEntityItem.h"
|
||||||
|
|
||||||
gpu::PipelinePointer RenderablePolyVoxEntityItem::_pipeline = nullptr;
|
gpu::PipelinePointer RenderablePolyVoxEntityItem::_pipeline = nullptr;
|
||||||
|
|
||||||
|
|
45
libraries/entities-renderer/src/paintStroke.slf
Normal file
45
libraries/entities-renderer/src/paintStroke.slf
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<@include gpu/Config.slh@>
|
||||||
|
<$VERSION_HEADER$>
|
||||||
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
|
//
|
||||||
|
// paintStroke.frag
|
||||||
|
// fragment shader
|
||||||
|
//
|
||||||
|
// Created by Eric Levin on 8/10/2015
|
||||||
|
// Copyright 2015 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 DeferredBufferWrite.slh@>
|
||||||
|
|
||||||
|
|
||||||
|
// the diffuse texture
|
||||||
|
uniform sampler2D originalTexture;
|
||||||
|
|
||||||
|
// the interpolated normal
|
||||||
|
in vec3 interpolatedNormal;
|
||||||
|
in vec2 varTexcoord;
|
||||||
|
in vec4 varColor;
|
||||||
|
|
||||||
|
float rand(vec2 point){
|
||||||
|
return fract(sin(dot(point.xy ,vec2(12.9898,78.233))) * 43758.5453);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
|
||||||
|
|
||||||
|
vec4 texel = texture(originalTexture, varTexcoord);
|
||||||
|
int frontCondition = 1 -int(gl_FrontFacing) * 2;
|
||||||
|
vec3 color = varColor.rgb;
|
||||||
|
//vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess
|
||||||
|
packDeferredFragmentTranslucent(
|
||||||
|
interpolatedNormal * frontCondition,
|
||||||
|
texel.a,
|
||||||
|
color *texel.rgb,
|
||||||
|
vec3(0.01, 0.01, 0.01),
|
||||||
|
10.0);
|
||||||
|
}
|
40
libraries/entities-renderer/src/paintStroke.slv
Normal file
40
libraries/entities-renderer/src/paintStroke.slv
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<@include gpu/Config.slh@>
|
||||||
|
<$VERSION_HEADER$>
|
||||||
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
|
//
|
||||||
|
// paintStroke.vert
|
||||||
|
// vertex shader
|
||||||
|
//
|
||||||
|
// Created by Eric Levin on 7/20/15.
|
||||||
|
// 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 gpu/Inputs.slh@>
|
||||||
|
<@include gpu/Transform.slh@>
|
||||||
|
|
||||||
|
<$declareStandardTransform()$>
|
||||||
|
|
||||||
|
// the interpolated normal
|
||||||
|
out vec3 interpolatedNormal;
|
||||||
|
|
||||||
|
//the diffuse texture
|
||||||
|
out vec2 varTexcoord;
|
||||||
|
|
||||||
|
out vec4 varColor;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
|
||||||
|
varTexcoord = inTexCoord0.st;
|
||||||
|
|
||||||
|
// pass along the diffuse color
|
||||||
|
varColor = inColor;
|
||||||
|
|
||||||
|
// standard transform
|
||||||
|
TransformCamera cam = getTransformCamera();
|
||||||
|
TransformObject obj = getTransformObject();
|
||||||
|
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
|
||||||
|
<$transformModelToEyeDir(cam, obj, inNormal.xyz, interpolatedNormal)$>
|
||||||
|
}
|
|
@ -28,6 +28,7 @@
|
||||||
#include "ZoneEntityItem.h"
|
#include "ZoneEntityItem.h"
|
||||||
#include "PolyVoxEntityItem.h"
|
#include "PolyVoxEntityItem.h"
|
||||||
#include "LineEntityItem.h"
|
#include "LineEntityItem.h"
|
||||||
|
#include "PolyLineEntityItem.h"
|
||||||
|
|
||||||
AtmospherePropertyGroup EntityItemProperties::_staticAtmosphere;
|
AtmospherePropertyGroup EntityItemProperties::_staticAtmosphere;
|
||||||
SkyboxPropertyGroup EntityItemProperties::_staticSkybox;
|
SkyboxPropertyGroup EntityItemProperties::_staticSkybox;
|
||||||
|
@ -102,6 +103,8 @@ CONSTRUCT_PROPERTY(lineWidth, LineEntityItem::DEFAULT_LINE_WIDTH),
|
||||||
CONSTRUCT_PROPERTY(linePoints, QVector<glm::vec3>()),
|
CONSTRUCT_PROPERTY(linePoints, QVector<glm::vec3>()),
|
||||||
CONSTRUCT_PROPERTY(faceCamera, TextEntityItem::DEFAULT_FACE_CAMERA),
|
CONSTRUCT_PROPERTY(faceCamera, TextEntityItem::DEFAULT_FACE_CAMERA),
|
||||||
CONSTRUCT_PROPERTY(actionData, QByteArray()),
|
CONSTRUCT_PROPERTY(actionData, QByteArray()),
|
||||||
|
CONSTRUCT_PROPERTY(normals, QVector<glm::vec3>()),
|
||||||
|
CONSTRUCT_PROPERTY(strokeWidths, QVector<float>()),
|
||||||
CONSTRUCT_PROPERTY(xTextureURL, ""),
|
CONSTRUCT_PROPERTY(xTextureURL, ""),
|
||||||
CONSTRUCT_PROPERTY(yTextureURL, ""),
|
CONSTRUCT_PROPERTY(yTextureURL, ""),
|
||||||
CONSTRUCT_PROPERTY(zTextureURL, ""),
|
CONSTRUCT_PROPERTY(zTextureURL, ""),
|
||||||
|
@ -367,6 +370,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||||
CHECK_PROPERTY_CHANGE(PROP_DESCRIPTION, description);
|
CHECK_PROPERTY_CHANGE(PROP_DESCRIPTION, description);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_FACE_CAMERA, faceCamera);
|
CHECK_PROPERTY_CHANGE(PROP_FACE_CAMERA, faceCamera);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_ACTION_DATA, actionData);
|
CHECK_PROPERTY_CHANGE(PROP_ACTION_DATA, actionData);
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_NORMALS, normals);
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_STROKE_WIDTHS, strokeWidths);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_X_TEXTURE_URL, xTextureURL);
|
CHECK_PROPERTY_CHANGE(PROP_X_TEXTURE_URL, xTextureURL);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_Y_TEXTURE_URL, yTextureURL);
|
CHECK_PROPERTY_CHANGE(PROP_Y_TEXTURE_URL, yTextureURL);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_Z_TEXTURE_URL, zTextureURL);
|
CHECK_PROPERTY_CHANGE(PROP_Z_TEXTURE_URL, zTextureURL);
|
||||||
|
@ -469,6 +474,8 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(description);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(description);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(faceCamera);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(faceCamera);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(actionData);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(actionData);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(normals);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(strokeWidths);
|
||||||
|
|
||||||
// Sitting properties support
|
// Sitting properties support
|
||||||
if (!skipDefaults) {
|
if (!skipDefaults) {
|
||||||
|
@ -587,6 +594,8 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(description, QString, setDescription);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(description, QString, setDescription);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(faceCamera, bool, setFaceCamera);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(faceCamera, bool, setFaceCamera);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(actionData, QByteArray, setActionData);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(actionData, QByteArray, setActionData);
|
||||||
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(normals, qVectorVec3, setNormals);
|
||||||
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(strokeWidths,qVectorFloat, setStrokeWidths);
|
||||||
|
|
||||||
if (!honorReadOnly) {
|
if (!honorReadOnly) {
|
||||||
// this is used by the json reader to set things that we don't want javascript to able to affect.
|
// this is used by the json reader to set things that we don't want javascript to able to affect.
|
||||||
|
@ -843,6 +852,14 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType::Value command, Ent
|
||||||
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, properties.getLineWidth());
|
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, properties.getLineWidth());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, properties.getLinePoints());
|
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, properties.getLinePoints());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (properties.getType() == EntityTypes::PolyLine) {
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, properties.getLineWidth());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, properties.getLinePoints());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_NORMALS, properties.getNormals());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, properties.getStrokeWidths());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, properties.getMarketplaceID());
|
APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, properties.getMarketplaceID());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_NAME, properties.getName());
|
APPEND_ENTITY_PROPERTY(PROP_NAME, properties.getName());
|
||||||
|
@ -1097,6 +1114,14 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_WIDTH, float, setLineWidth);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_WIDTH, float, setLineWidth);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (properties.getType() == EntityTypes::PolyLine) {
|
||||||
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_WIDTH, float, setLineWidth);
|
||||||
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
|
||||||
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NORMALS, QVector<glm::vec3>, setNormals);
|
||||||
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STROKE_WIDTHS, QVector<float>, setStrokeWidths);
|
||||||
|
}
|
||||||
|
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MARKETPLACE_ID, QString, setMarketplaceID);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MARKETPLACE_ID, QString, setMarketplaceID);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NAME, QString, setName);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NAME, QString, setName);
|
||||||
|
@ -1215,6 +1240,9 @@ void EntityItemProperties::markAllChanged() {
|
||||||
_descriptionChanged = true;
|
_descriptionChanged = true;
|
||||||
_faceCameraChanged = true;
|
_faceCameraChanged = true;
|
||||||
_actionDataChanged = true;
|
_actionDataChanged = true;
|
||||||
|
|
||||||
|
_normalsChanged = true;
|
||||||
|
_strokeWidthsChanged = true;
|
||||||
|
|
||||||
_xTextureURLChanged = true;
|
_xTextureURLChanged = true;
|
||||||
_yTextureURLChanged = true;
|
_yTextureURLChanged = true;
|
||||||
|
|
|
@ -56,6 +56,7 @@ class EntityItemProperties {
|
||||||
friend class WebEntityItem; // TODO: consider removing this friend relationship and use public methods
|
friend class WebEntityItem; // TODO: consider removing this friend relationship and use public methods
|
||||||
friend class LineEntityItem; // TODO: consider removing this friend relationship and use public methods
|
friend class LineEntityItem; // TODO: consider removing this friend relationship and use public methods
|
||||||
friend class PolyVoxEntityItem; // TODO: consider removing this friend relationship and use public methods
|
friend class PolyVoxEntityItem; // TODO: consider removing this friend relationship and use public methods
|
||||||
|
friend class PolyLineEntityItem; // TODO: consider removing this friend relationship and use public methods
|
||||||
public:
|
public:
|
||||||
EntityItemProperties();
|
EntityItemProperties();
|
||||||
virtual ~EntityItemProperties();
|
virtual ~EntityItemProperties();
|
||||||
|
@ -153,6 +154,8 @@ public:
|
||||||
DEFINE_PROPERTY_REF(PROP_HREF, Href, href, QString);
|
DEFINE_PROPERTY_REF(PROP_HREF, Href, href, QString);
|
||||||
DEFINE_PROPERTY_REF(PROP_DESCRIPTION, Description, description, QString);
|
DEFINE_PROPERTY_REF(PROP_DESCRIPTION, Description, description, QString);
|
||||||
DEFINE_PROPERTY(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool);
|
DEFINE_PROPERTY(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool);
|
||||||
|
DEFINE_PROPERTY(PROP_NORMALS, Normals, normals, QVector<glm::vec3>);
|
||||||
|
DEFINE_PROPERTY(PROP_STROKE_WIDTHS, StrokeWidths, strokeWidths, QVector<float>);
|
||||||
DEFINE_PROPERTY_REF(PROP_ACTION_DATA, ActionData, actionData, QByteArray);
|
DEFINE_PROPERTY_REF(PROP_ACTION_DATA, ActionData, actionData, QByteArray);
|
||||||
DEFINE_PROPERTY_REF(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString);
|
DEFINE_PROPERTY_REF(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString);
|
||||||
DEFINE_PROPERTY_REF(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString);
|
DEFINE_PROPERTY_REF(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString);
|
||||||
|
|
|
@ -98,7 +98,8 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const QString& v) { ret
|
||||||
inline QScriptValue convertScriptValue(QScriptEngine* e, const xColor& v) { return xColorToScriptValue(e, v); }
|
inline QScriptValue convertScriptValue(QScriptEngine* e, const xColor& v) { return xColorToScriptValue(e, v); }
|
||||||
inline QScriptValue convertScriptValue(QScriptEngine* e, const glm::quat& v) { return quatToScriptValue(e, v); }
|
inline QScriptValue convertScriptValue(QScriptEngine* e, const glm::quat& v) { return quatToScriptValue(e, v); }
|
||||||
inline QScriptValue convertScriptValue(QScriptEngine* e, const QScriptValue& v) { return v; }
|
inline QScriptValue convertScriptValue(QScriptEngine* e, const QScriptValue& v) { return v; }
|
||||||
inline QScriptValue convertScriptValue(QScriptEngine* e, const QVector<glm::vec3>& v) {return qVectorVec3ToScriptValue(e, v); }
|
inline QScriptValue convertScriptValue(QScriptEngine* e, const QVector<glm::vec3>& v) {return qVectorVec3ToScriptValue(e, v); }
|
||||||
|
inline QScriptValue convertScriptValue(QScriptEngine* e, const QVector<float>& v) { return qVectorFloatToScriptValue(e, v); }
|
||||||
|
|
||||||
inline QScriptValue convertScriptValue(QScriptEngine* e, const QByteArray& v) {
|
inline QScriptValue convertScriptValue(QScriptEngine* e, const QByteArray& v) {
|
||||||
QByteArray b64 = v.toBase64();
|
QByteArray b64 = v.toBase64();
|
||||||
|
@ -134,6 +135,7 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const QByteArray& v) {
|
||||||
typedef glm::vec3 glmVec3;
|
typedef glm::vec3 glmVec3;
|
||||||
typedef glm::quat glmQuat;
|
typedef glm::quat glmQuat;
|
||||||
typedef QVector<glm::vec3> qVectorVec3;
|
typedef QVector<glm::vec3> qVectorVec3;
|
||||||
|
typedef QVector<float> qVectorFloat;
|
||||||
inline float float_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toFloat(&isValid); }
|
inline float float_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toFloat(&isValid); }
|
||||||
inline quint64 quint64_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toULongLong(&isValid); }
|
inline quint64 quint64_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toULongLong(&isValid); }
|
||||||
inline uint16_t uint16_t_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toInt(&isValid); }
|
inline uint16_t uint16_t_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toInt(&isValid); }
|
||||||
|
@ -177,6 +179,11 @@ inline glmVec3 glmVec3_convertFromScriptValue(const QScriptValue& v, bool& isVal
|
||||||
return glm::vec3(0);
|
return glm::vec3(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline qVectorFloat qVectorFloat_convertFromScriptValue(const QScriptValue& v, bool& isValid) {
|
||||||
|
isValid = true;
|
||||||
|
return qVectorFloatFromScriptValue(v);
|
||||||
|
}
|
||||||
|
|
||||||
inline qVectorVec3 qVectorVec3_convertFromScriptValue(const QScriptValue& v, bool& isValid) {
|
inline qVectorVec3 qVectorVec3_convertFromScriptValue(const QScriptValue& v, bool& isValid) {
|
||||||
isValid = true;
|
isValid = true;
|
||||||
return qVectorVec3FromScriptValue(v);
|
return qVectorVec3FromScriptValue(v);
|
||||||
|
|
|
@ -124,11 +124,17 @@ enum EntityPropertyList {
|
||||||
|
|
||||||
PROP_FACE_CAMERA,
|
PROP_FACE_CAMERA,
|
||||||
PROP_SCRIPT_TIMESTAMP,
|
PROP_SCRIPT_TIMESTAMP,
|
||||||
|
|
||||||
PROP_ACTION_DATA,
|
PROP_ACTION_DATA,
|
||||||
|
|
||||||
PROP_X_TEXTURE_URL, // used by PolyVox
|
PROP_X_TEXTURE_URL, // used by PolyVox
|
||||||
PROP_Y_TEXTURE_URL, // used by PolyVox
|
PROP_Y_TEXTURE_URL, // used by PolyVox
|
||||||
PROP_Z_TEXTURE_URL, // used by PolyVox
|
PROP_Z_TEXTURE_URL, // used by PolyVox
|
||||||
|
|
||||||
|
// Used by PolyLine entity
|
||||||
|
PROP_NORMALS,
|
||||||
|
PROP_STROKE_WIDTHS,
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// ATTENTION: add new properties to end of list just ABOVE this line
|
// ATTENTION: add new properties to end of list just ABOVE this line
|
||||||
|
|
|
@ -455,18 +455,18 @@ bool EntityScriptingInterface::setPoints(QUuid entityID, std::function<bool(Line
|
||||||
if (!_entityTree) {
|
if (!_entityTree) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemPointer entity = static_cast<EntityItemPointer>(_entityTree->findEntityByEntityItemID(entityID));
|
EntityItemPointer entity = static_cast<EntityItemPointer>(_entityTree->findEntityByEntityItemID(entityID));
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
qCDebug(entities) << "EntityScriptingInterface::setPoints no entity with ID" << entityID;
|
qCDebug(entities) << "EntityScriptingInterface::setPoints no entity with ID" << entityID;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityTypes::EntityType entityType = entity->getType();
|
EntityTypes::EntityType entityType = entity->getType();
|
||||||
|
|
||||||
if (entityType != EntityTypes::Line) {
|
if (entityType != EntityTypes::Line) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto now = usecTimestampNow();
|
auto now = usecTimestampNow();
|
||||||
|
|
||||||
auto lineEntity = std::static_pointer_cast<LineEntityItem>(entity);
|
auto lineEntity = std::static_pointer_cast<LineEntityItem>(entity);
|
||||||
|
@ -475,19 +475,20 @@ bool EntityScriptingInterface::setPoints(QUuid entityID, std::function<bool(Line
|
||||||
entity->setLastEdited(now);
|
entity->setLastEdited(now);
|
||||||
entity->setLastBroadcast(now);
|
entity->setLastBroadcast(now);
|
||||||
_entityTree->unlock();
|
_entityTree->unlock();
|
||||||
|
|
||||||
_entityTree->lockForRead();
|
_entityTree->lockForRead();
|
||||||
EntityItemProperties properties = entity->getProperties();
|
EntityItemProperties properties = entity->getProperties();
|
||||||
_entityTree->unlock();
|
_entityTree->unlock();
|
||||||
|
|
||||||
properties.setLinePointsDirty();
|
properties.setLinePointsDirty();
|
||||||
properties.setLastEdited(now);
|
properties.setLastEdited(now);
|
||||||
|
|
||||||
|
|
||||||
queueEntityMessage(PacketType::EntityEdit, entityID, properties);
|
queueEntityMessage(PacketType::EntityEdit, entityID, properties);
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool EntityScriptingInterface::setVoxelSphere(QUuid entityID, const glm::vec3& center, float radius, int value) {
|
bool EntityScriptingInterface::setVoxelSphere(QUuid entityID, const glm::vec3& center, float radius, int value) {
|
||||||
return setVoxels(entityID, [center, radius, value](PolyVoxEntityItem& polyVoxEntity) {
|
return setVoxels(entityID, [center, radius, value](PolyVoxEntityItem& polyVoxEntity) {
|
||||||
polyVoxEntity.setSphere(center, radius, value);
|
polyVoxEntity.setSphere(center, radius, value);
|
||||||
|
@ -507,17 +508,39 @@ bool EntityScriptingInterface::setAllVoxels(QUuid entityID, int value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityScriptingInterface::setAllPoints(QUuid entityID, const QVector<glm::vec3>& points) {
|
bool EntityScriptingInterface::setAllPoints(QUuid entityID, const QVector<glm::vec3>& points) {
|
||||||
return setPoints(entityID, [points](LineEntityItem& lineEntity) -> bool
|
EntityItemPointer entity = static_cast<EntityItemPointer>(_entityTree->findEntityByEntityItemID(entityID));
|
||||||
{
|
if (!entity) {
|
||||||
return lineEntity.setLinePoints(points);
|
qCDebug(entities) << "EntityScriptingInterface::setPoints no entity with ID" << entityID;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
EntityTypes::EntityType entityType = entity->getType();
|
||||||
|
|
||||||
|
if (entityType == EntityTypes::Line) {
|
||||||
|
return setPoints(entityID, [points](LineEntityItem& lineEntity) -> bool
|
||||||
|
{
|
||||||
|
return (LineEntityItem*)lineEntity.setLinePoints(points);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityScriptingInterface::appendPoint(QUuid entityID, const glm::vec3& point) {
|
bool EntityScriptingInterface::appendPoint(QUuid entityID, const glm::vec3& point) {
|
||||||
return setPoints(entityID, [point](LineEntityItem& lineEntity) -> bool
|
EntityItemPointer entity = static_cast<EntityItemPointer>(_entityTree->findEntityByEntityItemID(entityID));
|
||||||
{
|
if (!entity) {
|
||||||
return lineEntity.appendPoint(point);
|
qCDebug(entities) << "EntityScriptingInterface::setPoints no entity with ID" << entityID;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
EntityTypes::EntityType entityType = entity->getType();
|
||||||
|
|
||||||
|
if (entityType == EntityTypes::Line) {
|
||||||
|
return setPoints(entityID, [point](LineEntityItem& lineEntity) -> bool
|
||||||
|
{
|
||||||
|
return (LineEntityItem*)lineEntity.appendPoint(point);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <RegisteredMetaTypes.h>
|
#include <RegisteredMetaTypes.h>
|
||||||
#include "PolyVoxEntityItem.h"
|
#include "PolyVoxEntityItem.h"
|
||||||
#include "LineEntityItem.h"
|
#include "LineEntityItem.h"
|
||||||
|
#include "PolyLineEntityItem.h"
|
||||||
|
|
||||||
#include "EntityEditPacketSender.h"
|
#include "EntityEditPacketSender.h"
|
||||||
|
|
||||||
|
@ -165,6 +166,7 @@ private:
|
||||||
bool setPoints(QUuid entityID, std::function<bool(LineEntityItem&)> actor);
|
bool setPoints(QUuid entityID, std::function<bool(LineEntityItem&)> actor);
|
||||||
void queueEntityMessage(PacketType::Value packetType, EntityItemID entityID, const EntityItemProperties& properties);
|
void queueEntityMessage(PacketType::Value packetType, EntityItemID entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
|
|
||||||
/// actually does the work of finding the ray intersection, can be called in locking mode or tryLock mode
|
/// actually does the work of finding the ray intersection, can be called in locking mode or tryLock mode
|
||||||
RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
|
RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
|
||||||
bool precisionPicking);
|
bool precisionPicking);
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "ZoneEntityItem.h"
|
#include "ZoneEntityItem.h"
|
||||||
#include "LineEntityItem.h"
|
#include "LineEntityItem.h"
|
||||||
#include "PolyVoxEntityItem.h"
|
#include "PolyVoxEntityItem.h"
|
||||||
|
#include "PolyLineEntityItem.h"
|
||||||
|
|
||||||
QMap<EntityTypes::EntityType, QString> EntityTypes::_typeToNameMap;
|
QMap<EntityTypes::EntityType, QString> EntityTypes::_typeToNameMap;
|
||||||
QMap<QString, EntityTypes::EntityType> EntityTypes::_nameToTypeMap;
|
QMap<QString, EntityTypes::EntityType> EntityTypes::_nameToTypeMap;
|
||||||
|
@ -47,6 +48,7 @@ REGISTER_ENTITY_TYPE(ParticleEffect)
|
||||||
REGISTER_ENTITY_TYPE(Zone)
|
REGISTER_ENTITY_TYPE(Zone)
|
||||||
REGISTER_ENTITY_TYPE(Line)
|
REGISTER_ENTITY_TYPE(Line)
|
||||||
REGISTER_ENTITY_TYPE(PolyVox)
|
REGISTER_ENTITY_TYPE(PolyVox)
|
||||||
|
REGISTER_ENTITY_TYPE(PolyLine);
|
||||||
|
|
||||||
const QString& EntityTypes::getEntityTypeName(EntityType entityType) {
|
const QString& EntityTypes::getEntityTypeName(EntityType entityType) {
|
||||||
QMap<EntityType, QString>::iterator matchedTypeName = _typeToNameMap.find(entityType);
|
QMap<EntityType, QString>::iterator matchedTypeName = _typeToNameMap.find(entityType);
|
||||||
|
|
|
@ -47,7 +47,8 @@ public:
|
||||||
Web,
|
Web,
|
||||||
Line,
|
Line,
|
||||||
PolyVox,
|
PolyVox,
|
||||||
LAST = PolyVox
|
PolyLine,
|
||||||
|
LAST = PolyLine
|
||||||
} EntityType;
|
} EntityType;
|
||||||
|
|
||||||
static const QString& getEntityTypeName(EntityType entityType);
|
static const QString& getEntityTypeName(EntityType entityType);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
//
|
//
|
||||||
// ParticleEffectEntityItem.cpp
|
// ParticleEffectEntityItem.cpp
|
||||||
// libraries/entities/src
|
// libraries/entities/src
|
||||||
|
|
238
libraries/entities/src/PolyLineEntityItem.cpp
Normal file
238
libraries/entities/src/PolyLineEntityItem.cpp
Normal file
|
@ -0,0 +1,238 @@
|
||||||
|
//
|
||||||
|
// PolyLineEntityItem.cpp
|
||||||
|
// libraries/entities/src
|
||||||
|
//
|
||||||
|
// Created by Eric Levin on 6/22/15.
|
||||||
|
// Copyright 2015 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 <QDebug>
|
||||||
|
|
||||||
|
#include <ByteCountCoding.h>
|
||||||
|
|
||||||
|
#include "PolyLineEntityItem.h"
|
||||||
|
#include "EntityTree.h"
|
||||||
|
#include "EntitiesLogging.h"
|
||||||
|
#include "EntityTreeElement.h"
|
||||||
|
#include "OctreeConstants.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const float PolyLineEntityItem::DEFAULT_LINE_WIDTH = 0.1f;
|
||||||
|
const int PolyLineEntityItem::MAX_POINTS_PER_LINE = 70;
|
||||||
|
|
||||||
|
|
||||||
|
EntityItemPointer PolyLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
|
EntityItemPointer result { new PolyLineEntityItem(entityID, properties) };
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolyLineEntityItem::PolyLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||||
|
EntityItem(entityItemID) ,
|
||||||
|
_lineWidth(DEFAULT_LINE_WIDTH),
|
||||||
|
_pointsChanged(true),
|
||||||
|
_points(QVector<glm::vec3>(0.0f)),
|
||||||
|
_vertices(QVector<glm::vec3>(0.0f)),
|
||||||
|
_normals(QVector<glm::vec3>(0.0f)),
|
||||||
|
_strokeWidths(QVector<float>(0.0f))
|
||||||
|
{
|
||||||
|
_type = EntityTypes::PolyLine;
|
||||||
|
_created = properties.getCreated();
|
||||||
|
setProperties(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityItemProperties PolyLineEntityItem::getProperties() const {
|
||||||
|
QWriteLocker lock(&_quadReadWriteLock);
|
||||||
|
EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class
|
||||||
|
|
||||||
|
|
||||||
|
properties._color = getXColor();
|
||||||
|
properties._colorChanged = false;
|
||||||
|
|
||||||
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineWidth, getLineWidth);
|
||||||
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(linePoints, getLinePoints);
|
||||||
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(normals, getNormals);
|
||||||
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(strokeWidths, getStrokeWidths);
|
||||||
|
|
||||||
|
properties._glowLevel = getGlowLevel();
|
||||||
|
properties._glowLevelChanged = false;
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PolyLineEntityItem::setProperties(const EntityItemProperties& properties) {
|
||||||
|
QWriteLocker lock(&_quadReadWriteLock);
|
||||||
|
bool somethingChanged = false;
|
||||||
|
somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
|
||||||
|
|
||||||
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
|
||||||
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lineWidth, setLineWidth);
|
||||||
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(linePoints, setLinePoints);
|
||||||
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(normals, setNormals);
|
||||||
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(strokeWidths, setStrokeWidths);
|
||||||
|
|
||||||
|
if (somethingChanged) {
|
||||||
|
bool wantDebug = false;
|
||||||
|
if (wantDebug) {
|
||||||
|
uint64_t now = usecTimestampNow();
|
||||||
|
int elapsed = now - getLastEdited();
|
||||||
|
qCDebug(entities) << "PolyLineEntityItem::setProperties() AFTER update... edited AGO=" << elapsed <<
|
||||||
|
"now=" << now << " getLastEdited()=" << getLastEdited();
|
||||||
|
}
|
||||||
|
setLastEdited(properties._lastEdited);
|
||||||
|
}
|
||||||
|
return somethingChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PolyLineEntityItem::appendPoint(const glm::vec3& point) {
|
||||||
|
if (_points.size() > MAX_POINTS_PER_LINE - 1) {
|
||||||
|
qDebug() << "MAX POINTS REACHED!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
glm::vec3 halfBox = getDimensions() * 0.5f;
|
||||||
|
if ( (point.x < - halfBox.x || point.x > halfBox.x) || (point.y < -halfBox.y || point.y > halfBox.y) || (point.z < - halfBox.z || point.z > halfBox.z) ) {
|
||||||
|
qDebug() << "Point is outside entity's bounding box";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_points << point;
|
||||||
|
_pointsChanged = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PolyLineEntityItem::setStrokeWidths(const QVector<float>& strokeWidths ) {
|
||||||
|
_strokeWidths = strokeWidths;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PolyLineEntityItem::setNormals(const QVector<glm::vec3>& normals) {
|
||||||
|
_normals = normals;
|
||||||
|
if (_points.size () < 2 || _normals.size() < 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int minVectorSize = _normals.size();
|
||||||
|
if (_points.size() < minVectorSize) {
|
||||||
|
minVectorSize = _points.size();
|
||||||
|
}
|
||||||
|
if (_strokeWidths.size() < minVectorSize) {
|
||||||
|
minVectorSize = _strokeWidths.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
_vertices.clear();
|
||||||
|
glm::vec3 v1, v2, tangent, binormal, point;
|
||||||
|
|
||||||
|
for (int i = 0; i < minVectorSize-1; i++) {
|
||||||
|
float width = _strokeWidths.at(i);
|
||||||
|
point = _points.at(i);
|
||||||
|
|
||||||
|
tangent = _points.at(i+1) - point;
|
||||||
|
glm::vec3 normal = normals.at(i);
|
||||||
|
binormal = glm::normalize(glm::cross(tangent, normal)) * width;
|
||||||
|
|
||||||
|
//This checks to make sure binormal is not a NAN
|
||||||
|
assert(binormal.x == binormal.x);
|
||||||
|
v1 = point + binormal;
|
||||||
|
v2 = point - binormal;
|
||||||
|
_vertices << v1 << v2;
|
||||||
|
}
|
||||||
|
//for last point we can just assume binormals are same since it represents last two vertices of quad
|
||||||
|
point = _points.at(_points.size() - 1);
|
||||||
|
v1 = point + binormal;
|
||||||
|
v2 = point - binormal;
|
||||||
|
_vertices << v1 << v2;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PolyLineEntityItem::setLinePoints(const QVector<glm::vec3>& points) {
|
||||||
|
if (points.size() > MAX_POINTS_PER_LINE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (points.size() != _points.size()) {
|
||||||
|
_pointsChanged = true;
|
||||||
|
}
|
||||||
|
//Check to see if points actually changed. If they haven't, return before doing anything else
|
||||||
|
else if (points.size() == _points.size()) {
|
||||||
|
//same number of points, so now compare every point
|
||||||
|
for (int i = 0; i < points.size(); i++ ) {
|
||||||
|
if (points.at(i) != _points.at(i)){
|
||||||
|
_pointsChanged = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!_pointsChanged) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < points.size(); i++) {
|
||||||
|
glm::vec3 point = points.at(i);
|
||||||
|
glm::vec3 pos = getPosition();
|
||||||
|
glm::vec3 halfBox = getDimensions() * 0.5f;
|
||||||
|
if ( (point.x < - halfBox.x || point.x > halfBox.x) || (point.y < -halfBox.y || point.y > halfBox.y) || (point.z < - halfBox.z || point.z > halfBox.z) ) {
|
||||||
|
qDebug() << "Point is outside entity's bounding box";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_points = points;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PolyLineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||||
|
ReadBitstreamToTreeParams& args,
|
||||||
|
EntityPropertyFlags& propertyFlags, bool overwriteLocalData) {
|
||||||
|
QWriteLocker lock(&_quadReadWriteLock);
|
||||||
|
int bytesRead = 0;
|
||||||
|
const unsigned char* dataAt = data;
|
||||||
|
|
||||||
|
READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_LINE_WIDTH, float, setLineWidth);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_NORMALS, QVector<glm::vec3>, setNormals);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, QVector<float>, setStrokeWidths);
|
||||||
|
|
||||||
|
return bytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
|
||||||
|
EntityPropertyFlags PolyLineEntityItem::getEntityProperties(EncodeBitstreamParams& params) const {
|
||||||
|
EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params);
|
||||||
|
requestedProperties += PROP_COLOR;
|
||||||
|
requestedProperties += PROP_LINE_WIDTH;
|
||||||
|
requestedProperties += PROP_LINE_POINTS;
|
||||||
|
requestedProperties += PROP_NORMALS;
|
||||||
|
requestedProperties += PROP_STROKE_WIDTHS;
|
||||||
|
return requestedProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolyLineEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
||||||
|
EntityTreeElementExtraEncodeData* modelTreeElementExtraEncodeData,
|
||||||
|
EntityPropertyFlags& requestedProperties,
|
||||||
|
EntityPropertyFlags& propertyFlags,
|
||||||
|
EntityPropertyFlags& propertiesDidntFit,
|
||||||
|
int& propertyCount,
|
||||||
|
OctreeElement::AppendState& appendState) const {
|
||||||
|
|
||||||
|
QWriteLocker lock(&_quadReadWriteLock);
|
||||||
|
bool successPropertyFits = true;
|
||||||
|
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, getLineWidth());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, getLinePoints());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_NORMALS, getNormals());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, getStrokeWidths());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolyLineEntityItem::debugDump() const {
|
||||||
|
quint64 now = usecTimestampNow();
|
||||||
|
qCDebug(entities) << " QUAD EntityItem id:" << getEntityItemID() << "---------------------------------------------";
|
||||||
|
qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2];
|
||||||
|
qCDebug(entities) << " position:" << debugTreeVector(getPosition());
|
||||||
|
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions());
|
||||||
|
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
||||||
|
}
|
||||||
|
|
94
libraries/entities/src/PolyLineEntityItem.h
Normal file
94
libraries/entities/src/PolyLineEntityItem.h
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
//
|
||||||
|
// PolyLineEntityItem.h
|
||||||
|
// libraries/entities/src
|
||||||
|
//
|
||||||
|
// Created by Eric Levin on 8/3/15.
|
||||||
|
// Copyright 2015 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_PolyLineEntityItem_h
|
||||||
|
#define hifi_PolyLineEntityItem_h
|
||||||
|
|
||||||
|
#include "EntityItem.h"
|
||||||
|
|
||||||
|
class PolyLineEntityItem : public EntityItem {
|
||||||
|
public:
|
||||||
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
|
||||||
|
PolyLineEntityItem(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);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
const rgbColor& getColor() const { return _color; }
|
||||||
|
xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; }
|
||||||
|
|
||||||
|
void setColor(const rgbColor& value) {
|
||||||
|
memcpy(_color, value, sizeof(_color));
|
||||||
|
}
|
||||||
|
void setColor(const xColor& value) {
|
||||||
|
|
||||||
|
_color[RED_INDEX] = value.red;
|
||||||
|
_color[GREEN_INDEX] = value.green;
|
||||||
|
_color[BLUE_INDEX] = value.blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLineWidth(float lineWidth){ _lineWidth = lineWidth; }
|
||||||
|
float getLineWidth() const{ return _lineWidth; }
|
||||||
|
|
||||||
|
bool setLinePoints(const QVector<glm::vec3>& points);
|
||||||
|
bool appendPoint(const glm::vec3& point);
|
||||||
|
const QVector<glm::vec3>& getLinePoints() const{ return _points; }
|
||||||
|
|
||||||
|
bool setNormals(const QVector<glm::vec3>& normals);
|
||||||
|
const QVector<glm::vec3>& getNormals() const{ return _normals; }
|
||||||
|
|
||||||
|
bool setStrokeWidths(const QVector<float>& strokeWidths);
|
||||||
|
const QVector<float>& getStrokeWidths() const{ return _strokeWidths; }
|
||||||
|
|
||||||
|
|
||||||
|
virtual ShapeType getShapeType() const { return SHAPE_TYPE_LINE; }
|
||||||
|
|
||||||
|
// never have a ray intersection pick a PolyLineEntityItem.
|
||||||
|
virtual bool supportsDetailedRayIntersection() const { return true; }
|
||||||
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
|
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
||||||
|
void** intersectedObject, bool precisionPicking) const { return false; }
|
||||||
|
|
||||||
|
virtual void debugDump() const;
|
||||||
|
static const float DEFAULT_LINE_WIDTH;
|
||||||
|
static const int MAX_POINTS_PER_LINE;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
rgbColor _color;
|
||||||
|
float _lineWidth;
|
||||||
|
bool _pointsChanged;
|
||||||
|
QVector<glm::vec3> _points;
|
||||||
|
QVector<glm::vec3> _vertices;
|
||||||
|
QVector<glm::vec3> _normals;
|
||||||
|
QVector<float> _strokeWidths;
|
||||||
|
mutable QReadWriteLock _quadReadWriteLock;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_PolyLineEntityItem_h
|
|
@ -75,7 +75,7 @@ namespace PacketType {
|
||||||
EntityErase,
|
EntityErase,
|
||||||
EntityEdit,
|
EntityEdit,
|
||||||
DomainServerConnectionToken
|
DomainServerConnectionToken
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const int NUM_BYTES_MD5_HASH = 16;
|
const int NUM_BYTES_MD5_HASH = 16;
|
||||||
|
@ -141,5 +141,6 @@ const PacketVersion VERSION_ENTITIES_SCRIPT_TIMESTAMP_FIX = 32;
|
||||||
const PacketVersion VERSION_ENTITIES_HAVE_SIMULATION_OWNER_AND_ACTIONS_OVER_WIRE = 33;
|
const PacketVersion VERSION_ENTITIES_HAVE_SIMULATION_OWNER_AND_ACTIONS_OVER_WIRE = 33;
|
||||||
const PacketVersion VERSION_ENTITIES_NEW_PROTOCOL_LAYER = 35;
|
const PacketVersion VERSION_ENTITIES_NEW_PROTOCOL_LAYER = 35;
|
||||||
const PacketVersion VERSION_POLYVOX_TEXTURES = 36;
|
const PacketVersion VERSION_POLYVOX_TEXTURES = 36;
|
||||||
|
const PacketVersion VERSION_ENTITIES_POLYLINE = 37;
|
||||||
|
|
||||||
#endif // hifi_PacketHeaders_h
|
#endif // hifi_PacketHeaders_h
|
|
@ -394,6 +394,19 @@ bool OctreePacketData::appendValue(const QVector<glm::vec3>& value) {
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OctreePacketData::appendValue(const QVector<float>& value) {
|
||||||
|
uint16_t qVecSize = value.size();
|
||||||
|
bool success = appendValue(qVecSize);
|
||||||
|
if (success) {
|
||||||
|
success = append((const unsigned char*)value.constData(), qVecSize * sizeof(float));
|
||||||
|
if (success) {
|
||||||
|
_bytesOfValues += qVecSize * sizeof(float);
|
||||||
|
_totalBytesOfValues += qVecSize * sizeof(float);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
bool OctreePacketData::appendValue(const glm::quat& value) {
|
bool OctreePacketData::appendValue(const glm::quat& value) {
|
||||||
const size_t VALUES_PER_QUAT = 4;
|
const size_t VALUES_PER_QUAT = 4;
|
||||||
const size_t PACKED_QUAT_SIZE = sizeof(uint16_t) * VALUES_PER_QUAT;
|
const size_t PACKED_QUAT_SIZE = sizeof(uint16_t) * VALUES_PER_QUAT;
|
||||||
|
@ -609,6 +622,16 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char *dataBytes, QVecto
|
||||||
memcpy(result.data(), dataBytes, length * sizeof(glm::vec3));
|
memcpy(result.data(), dataBytes, length * sizeof(glm::vec3));
|
||||||
return sizeof(uint16_t) + length * sizeof(glm::vec3);
|
return sizeof(uint16_t) + length * sizeof(glm::vec3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QVector<float>& result) {
|
||||||
|
uint16_t length;
|
||||||
|
memcpy(&length, dataBytes, sizeof(uint16_t));
|
||||||
|
dataBytes += sizeof(length);
|
||||||
|
result.resize(length);
|
||||||
|
memcpy(result.data(), dataBytes, length * sizeof(float));
|
||||||
|
return sizeof(uint16_t) + length * sizeof(float);
|
||||||
|
}
|
||||||
|
|
||||||
int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QByteArray& result) {
|
int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QByteArray& result) {
|
||||||
uint16_t length;
|
uint16_t length;
|
||||||
memcpy(&length, dataBytes, sizeof(length));
|
memcpy(&length, dataBytes, sizeof(length));
|
||||||
|
|
|
@ -165,6 +165,9 @@ public:
|
||||||
|
|
||||||
//appends a QVector of vec3's to the end of the stream, may fail if new data stream is too long to fit in packet
|
//appends a QVector of vec3's to the end of the stream, may fail if new data stream is too long to fit in packet
|
||||||
bool appendValue(const QVector<glm::vec3>& value);
|
bool appendValue(const QVector<glm::vec3>& value);
|
||||||
|
|
||||||
|
//appends a QVector of floats to the end of the stream, may fail if new data stream is too long to fit in packet
|
||||||
|
bool appendValue(const QVector<float>& value);
|
||||||
|
|
||||||
/// appends a packed quat to the end of the stream, may fail if new data stream is too long to fit in packet
|
/// appends a packed quat to the end of the stream, may fail if new data stream is too long to fit in packet
|
||||||
bool appendValue(const glm::quat& value);
|
bool appendValue(const glm::quat& value);
|
||||||
|
@ -245,6 +248,7 @@ public:
|
||||||
static int unpackDataFromBytes(const unsigned char* dataBytes, QUuid& result);
|
static int unpackDataFromBytes(const unsigned char* dataBytes, QUuid& result);
|
||||||
static int unpackDataFromBytes(const unsigned char* dataBytes, xColor& result);
|
static int unpackDataFromBytes(const unsigned char* dataBytes, xColor& result);
|
||||||
static int unpackDataFromBytes(const unsigned char* dataBytes, QVector<glm::vec3>& result);
|
static int unpackDataFromBytes(const unsigned char* dataBytes, QVector<glm::vec3>& result);
|
||||||
|
static int unpackDataFromBytes(const unsigned char* dataBytes, QVector<float>& result);
|
||||||
static int unpackDataFromBytes(const unsigned char* dataBytes, QByteArray& result);
|
static int unpackDataFromBytes(const unsigned char* dataBytes, QByteArray& result);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -139,6 +139,8 @@ void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) {
|
||||||
lp->setAmbientSpherePreset(gpu::SphericalHarmonics::Preset(_ambientLightMode % gpu::SphericalHarmonics::NUM_PRESET));
|
lp->setAmbientSpherePreset(gpu::SphericalHarmonics::Preset(_ambientLightMode % gpu::SphericalHarmonics::NUM_PRESET));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void DeferredLightingEffect::bindSimpleProgram(gpu::Batch& batch, bool textured, bool culled,
|
void DeferredLightingEffect::bindSimpleProgram(gpu::Batch& batch, bool textured, bool culled,
|
||||||
bool emmisive, bool depthBias) {
|
bool emmisive, bool depthBias) {
|
||||||
SimpleProgramKey config{textured, culled, emmisive, depthBias};
|
SimpleProgramKey config{textured, culled, emmisive, depthBias};
|
||||||
|
|
|
@ -77,6 +77,7 @@ public:
|
||||||
void setGlobalAtmosphere(const model::AtmospherePointer& atmosphere) { _atmosphere = atmosphere; }
|
void setGlobalAtmosphere(const model::AtmospherePointer& atmosphere) { _atmosphere = atmosphere; }
|
||||||
|
|
||||||
void setGlobalSkybox(const model::SkyboxPointer& skybox);
|
void setGlobalSkybox(const model::SkyboxPointer& skybox);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DeferredLightingEffect() {}
|
DeferredLightingEffect() {}
|
||||||
virtual ~DeferredLightingEffect() { }
|
virtual ~DeferredLightingEffect() { }
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "AbstractViewStateInterface.h"
|
#include "AbstractViewStateInterface.h"
|
||||||
#include "HitEffect.h"
|
#include "HitEffect.h"
|
||||||
|
|
||||||
#include "TextureCache.h"
|
#include "TextureCache.h"
|
||||||
#include "DependencyManager.h"
|
#include "DependencyManager.h"
|
||||||
#include "ViewFrustum.h"
|
#include "ViewFrustum.h"
|
||||||
|
@ -43,6 +44,7 @@ const gpu::PipelinePointer& HitEffect::getHitEffectPipeline() {
|
||||||
gpu::Shader::BindingSet slotBindings;
|
gpu::Shader::BindingSet slotBindings;
|
||||||
gpu::Shader::makeProgram(*program, slotBindings);
|
gpu::Shader::makeProgram(*program, slotBindings);
|
||||||
|
|
||||||
|
|
||||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||||
|
|
||||||
state->setDepthTest(false, false, gpu::LESS_EQUAL);
|
state->setDepthTest(false, false, gpu::LESS_EQUAL);
|
||||||
|
@ -50,7 +52,7 @@ const gpu::PipelinePointer& HitEffect::getHitEffectPipeline() {
|
||||||
// Blend on transparent
|
// Blend on transparent
|
||||||
state->setBlendFunction(true,
|
state->setBlendFunction(true,
|
||||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA);
|
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA);
|
||||||
|
|
||||||
// Good to go add the brand new pipeline
|
// Good to go add the brand new pipeline
|
||||||
_hitEffectPipeline.reset(gpu::Pipeline::create(program, state));
|
_hitEffectPipeline.reset(gpu::Pipeline::create(program, state));
|
||||||
}
|
}
|
||||||
|
@ -77,9 +79,6 @@ void HitEffect::run(const render::SceneContextPointer& sceneContext, const rende
|
||||||
glm::vec2 bottomLeft(-1.0f, -1.0f);
|
glm::vec2 bottomLeft(-1.0f, -1.0f);
|
||||||
glm::vec2 topRight(1.0f, 1.0f);
|
glm::vec2 topRight(1.0f, 1.0f);
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, color);
|
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, color);
|
||||||
|
|
||||||
|
|
||||||
// Ready to render
|
|
||||||
args->_context->render((batch));
|
args->_context->render((batch));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ public:
|
||||||
const gpu::PipelinePointer& getHitEffectPipeline();
|
const gpu::PipelinePointer& getHitEffectPipeline();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
gpu::PipelinePointer _hitEffectPipeline;
|
gpu::PipelinePointer _hitEffectPipeline;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,7 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
|
||||||
_drawStatusJobIndex = _jobs.size() - 1;
|
_drawStatusJobIndex = _jobs.size() - 1;
|
||||||
|
|
||||||
_jobs.push_back(Job(new DrawOverlay3D::JobModel("DrawOverlay3D")));
|
_jobs.push_back(Job(new DrawOverlay3D::JobModel("DrawOverlay3D")));
|
||||||
|
|
||||||
_jobs.push_back(Job(new HitEffect::JobModel("HitEffect")));
|
_jobs.push_back(Job(new HitEffect::JobModel("HitEffect")));
|
||||||
_jobs.back().setEnabled(false);
|
_jobs.back().setEnabled(false);
|
||||||
_drawHitEffectJobIndex = _jobs.size() -1;
|
_drawHitEffectJobIndex = _jobs.size() -1;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
<$VERSION_HEADER$>
|
<$VERSION_HEADER$>
|
||||||
// Generated on <$_SCRIBE_DATE$>
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
//
|
//
|
||||||
|
|
||||||
// hit_effect.frag
|
// hit_effect.frag
|
||||||
// fragment shader
|
// fragment shader
|
||||||
//
|
//
|
||||||
|
@ -12,6 +13,7 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
<@include DeferredBufferWrite.slh@>
|
<@include DeferredBufferWrite.slh@>
|
||||||
|
|
||||||
in vec2 varQuadPosition;
|
in vec2 varQuadPosition;
|
||||||
|
|
|
@ -33,6 +33,7 @@ void registerMetaTypes(QScriptEngine* engine) {
|
||||||
qScriptRegisterMetaType(engine, vec4toScriptValue, vec4FromScriptValue);
|
qScriptRegisterMetaType(engine, vec4toScriptValue, vec4FromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, vec3toScriptValue, vec3FromScriptValue);
|
qScriptRegisterMetaType(engine, vec3toScriptValue, vec3FromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, qVectorVec3ToScriptValue, qVectorVec3FromScriptValue);
|
qScriptRegisterMetaType(engine, qVectorVec3ToScriptValue, qVectorVec3FromScriptValue);
|
||||||
|
qScriptRegisterMetaType(engine, qVectorFloatToScriptValue, qVectorFloatFromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, vec2toScriptValue, vec2FromScriptValue);
|
qScriptRegisterMetaType(engine, vec2toScriptValue, vec2FromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, quatToScriptValue, quatFromScriptValue);
|
qScriptRegisterMetaType(engine, quatToScriptValue, quatFromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, qRectToScriptValue, qRectFromScriptValue);
|
qScriptRegisterMetaType(engine, qRectToScriptValue, qRectFromScriptValue);
|
||||||
|
@ -43,6 +44,7 @@ void registerMetaTypes(QScriptEngine* engine) {
|
||||||
qScriptRegisterMetaType(engine, collisionToScriptValue, collisionFromScriptValue);
|
qScriptRegisterMetaType(engine, collisionToScriptValue, collisionFromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, quuidToScriptValue, quuidFromScriptValue);
|
qScriptRegisterMetaType(engine, quuidToScriptValue, quuidFromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, qSizeFToScriptValue, qSizeFFromScriptValue);
|
qScriptRegisterMetaType(engine, qSizeFToScriptValue, qSizeFFromScriptValue);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QScriptValue vec4toScriptValue(QScriptEngine* engine, const glm::vec4& vec4) {
|
QScriptValue vec4toScriptValue(QScriptEngine* engine, const glm::vec4& vec4) {
|
||||||
|
@ -79,7 +81,7 @@ void vec3FromScriptValue(const QScriptValue &object, glm::vec3 &vec3) {
|
||||||
vec3.z = object.property("z").toVariant().toFloat();
|
vec3.z = object.property("z").toVariant().toFloat();
|
||||||
}
|
}
|
||||||
|
|
||||||
QScriptValue qVectorVec3ToScriptValue(QScriptEngine* engine, const QVector<glm::vec3>& vector){
|
QScriptValue qVectorVec3ToScriptValue(QScriptEngine* engine, const QVector<glm::vec3>& vector) {
|
||||||
QScriptValue array = engine->newArray();
|
QScriptValue array = engine->newArray();
|
||||||
for (int i = 0; i < vector.size(); i++) {
|
for (int i = 0; i < vector.size(); i++) {
|
||||||
array.setProperty(i, vec3toScriptValue(engine, vector.at(i)));
|
array.setProperty(i, vec3toScriptValue(engine, vector.at(i)));
|
||||||
|
@ -87,6 +89,39 @@ QScriptValue qVectorVec3ToScriptValue(QScriptEngine* engine, const QVector<glm::
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector<float> qVectorFloatFromScriptValue(const QScriptValue& array) {
|
||||||
|
if(!array.isArray()) {
|
||||||
|
return QVector<float>();
|
||||||
|
}
|
||||||
|
QVector<float> newVector;
|
||||||
|
int length = array.property("length").toInteger();
|
||||||
|
newVector.reserve(length);
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
if(array.property(i).isNumber()) {
|
||||||
|
newVector << array.property(i).toNumber();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newVector;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScriptValue qVectorFloatToScriptValue(QScriptEngine* engine, const QVector<float>& vector) {
|
||||||
|
QScriptValue array = engine->newArray();
|
||||||
|
for (int i = 0; i < vector.size(); i++) {
|
||||||
|
float num = vector.at(i);
|
||||||
|
array.setProperty(i, QScriptValue(num));
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qVectorFloatFromScriptValue(const QScriptValue& array, QVector<float>& vector) {
|
||||||
|
int length = array.property("length").toInteger();
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
vector << array.property(i).toVariant().toFloat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
QVector<glm::vec3> qVectorVec3FromScriptValue(const QScriptValue& array){
|
QVector<glm::vec3> qVectorVec3FromScriptValue(const QScriptValue& array){
|
||||||
QVector<glm::vec3> newVector;
|
QVector<glm::vec3> newVector;
|
||||||
int length = array.property("length").toInteger();
|
int length = array.property("length").toInteger();
|
||||||
|
|
|
@ -29,6 +29,7 @@ Q_DECLARE_METATYPE(glm::vec2)
|
||||||
Q_DECLARE_METATYPE(glm::quat)
|
Q_DECLARE_METATYPE(glm::quat)
|
||||||
Q_DECLARE_METATYPE(xColor)
|
Q_DECLARE_METATYPE(xColor)
|
||||||
Q_DECLARE_METATYPE(QVector<glm::vec3>)
|
Q_DECLARE_METATYPE(QVector<glm::vec3>)
|
||||||
|
Q_DECLARE_METATYPE(QVector<float>)
|
||||||
|
|
||||||
void registerMetaTypes(QScriptEngine* engine);
|
void registerMetaTypes(QScriptEngine* engine);
|
||||||
|
|
||||||
|
@ -60,6 +61,10 @@ QScriptValue qVectorVec3ToScriptValue(QScriptEngine* engine, const QVector<glm::
|
||||||
void qVectorVec3FromScriptValue(const QScriptValue& array, QVector<glm::vec3>& vector);
|
void qVectorVec3FromScriptValue(const QScriptValue& array, QVector<glm::vec3>& vector);
|
||||||
QVector<glm::vec3> qVectorVec3FromScriptValue( const QScriptValue& array);
|
QVector<glm::vec3> qVectorVec3FromScriptValue( const QScriptValue& array);
|
||||||
|
|
||||||
|
QScriptValue qVectorFloatToScriptValue(QScriptEngine* engine, const QVector<float>& vector);
|
||||||
|
void qVectorFloatFromScriptValue(const QScriptValue& array, QVector<float>& vector);
|
||||||
|
QVector<float> qVectorFloatFromScriptValue(const QScriptValue& array);
|
||||||
|
|
||||||
class PickRay {
|
class PickRay {
|
||||||
public:
|
public:
|
||||||
PickRay() : origin(0.0f), direction(0.0f) { }
|
PickRay() : origin(0.0f), direction(0.0f) { }
|
||||||
|
|
|
@ -109,6 +109,8 @@
|
||||||
#include "sdf_text3D_vert.h"
|
#include "sdf_text3D_vert.h"
|
||||||
#include "sdf_text3D_frag.h"
|
#include "sdf_text3D_frag.h"
|
||||||
|
|
||||||
|
#include "paintStroke_vert.h"
|
||||||
|
#include "paintStroke_frag.h"
|
||||||
|
|
||||||
class RateCounter {
|
class RateCounter {
|
||||||
std::vector<float> times;
|
std::vector<float> times;
|
||||||
|
@ -324,6 +326,8 @@ void QTestWindow::draw() {
|
||||||
testShaderBuild(SkyFromAtmosphere_vert, SkyFromAtmosphere_frag);
|
testShaderBuild(SkyFromAtmosphere_vert, SkyFromAtmosphere_frag);
|
||||||
|
|
||||||
testShaderBuild(Skybox_vert, Skybox_frag);
|
testShaderBuild(Skybox_vert, Skybox_frag);
|
||||||
|
|
||||||
|
testShaderBuild(paintStroke_vert,paintStroke_frag);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue