Autodesk Viewer API, not rendering markup to screenshot canvas for new version - markup

Codes runs upto version 2.15.* of the Viewer but doesn't run on higher version. The markup doesn't shows up with the image.
/**
* Get's the markup data as a base 64 image.
*
* #param viewer
* #returns {Promise}
*/
service.getDataFromMarkup = function (viewer) {
if (!viewer) {
throw new Error('Viewer instance not provided');
}
let base64Img = viewer.getScreenShotBuffer();
return loadImageWithData(base64Img).then(img => {
let canvas = document.createElement('canvas');
let context = canvas.getContext('2d');
let markupCore = viewer.loadedExtensions['Autodesk.Viewing.MarkupsCore'];
let viewerBounds = viewer.container.getBoundingClientRect();
markupCore.generateData();
canvas.width = viewerBounds.width;
canvas.height = viewerBounds.height;
context.drawImage(img, 0, 0, viewerBounds.width, viewerBounds.height);
markupCore.renderToCanvas(context);
return canvas.toDataURL();
});
};
/**
* Returns an <img> DOM element with the provided image as a source.
*
* #param src
* #returns {*}
*/
function loadImageWithData(src) {
return $q((resolve) => {
let img = new Image();
// Resolve with img element when the
// source image has been completely loaded.
img.onload = function () {
resolve(img);
};
img.src = src;
});
}

Prepared a testing sample code that works fine on Viewer 3.3.
Note I'm using a string var markupSVG that contains the definition of the markup in SVG, the code restores this markup, capture the screenshot and restores the Viewer (by hiding the markups). Left with Viewer, right with canvas.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Snapshot with Markup</title>
<link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/style.min.css?v=v3.3" type="text/css">
</head>
<body>
<body onload="initializeViewer();" style="margin:0px; overflow:hidden">
<div style="width:49vw; height:100vh; position:relative; display:inline-block;">
<div id="viewer3d" style="margin:0;">
</div>
</div>
<div style="width:49vw; height:100vh;display:inline-block;">
<canvas id="snapshot" style="position:absolute;"></canvas>
<button onclick="snaphot();" style="position:absolute;">Snapshot!</button>
</div>
</body>
<!-- The Viewer JS -->
<script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/three.min.js"></script>
<script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/viewer3D.js?v=v3.3"></script>
<!-- Developer JS -->
<script>
var viewer;
function initializeViewer() {
// initialize the viewer in "offline" mode (no security from Forge)
var myViewerDiv = document.getElementById('viewer3d');
viewer = new Autodesk.Viewing.Private.GuiViewer3D(myViewerDiv);
var options = {
'env': 'Local',
'document': 'http://autodesk-forge.github.io/viewer-javascript-offline.sample/shaver/0.svf'
};
Autodesk.Viewing.Initializer(options, function () {
viewer.start(options.document, options);
viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, function () {
viewer.utilities.fitToView();
});
});
}
function snaphot() {
var screenshot = new Image();
screenshot.onload = function () {
viewer.loadExtension('Autodesk.Viewing.MarkupsCore').then(function (markupCore) {
// load the markups
markupCore.show();
markupCore.loadMarkups(markupSVG, "layerName");
// ideally should also restore state of Viewer for this markup
// prepare to render the markups
var canvas = document.getElementById('snapshot');
canvas.width = viewer.container.clientWidth;
canvas.height = viewer.container.clientHeight;
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(screenshot, 0, 0, canvas.width, canvas.height);
markupCore.renderToCanvas(ctx);
// hide the markups
markupCore.hide();
});
};
// Get the full image
viewer.getScreenShot(viewer.container.clientWidth, viewer.container.clientHeight, function (blobURL) {
screenshot.src = blobURL;
});
}
var markupSVG = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" baseProfile="full" style="position:absolute; left:0; top:0; transform:scale(1,-1); -ms-transform:scale(1,-1); -webkit-transform:scale(1,-1); -moz-transform:scale(1,-1); -o-transform:scale(1,-1); transformOrigin:0, 0; -ms-transformOrigin:0, 0; -webkit-transformOrigin:0, 0; -moz-transformOrigin:0, 0; -o-transformOrigin:0, 0; " width="510" height="960" viewBox="-531.25 -1000 1062.5 2000" cursor="crosshair" pointer-events="painted"><metadata><markup_document xmlns="http://www.w3.org/1999/xhtml" data-model-version="4"></markup_document></metadata><g cursor="inherit" pointer-events="stroke"><metadata><markup_element xmlns="http://www.w3.org/1999/xhtml" stroke-width="10.416666666666629" stroke-linejoin="miter" stroke-color="#ff0000" stroke-opacity="1" fill-color="#ff0000" fill-opacity="0" type="cloud" position="-48.958333333333336 307.2916666666667" size="418.75 377.08333333333337" rotation="0"></markup_element></metadata><path id="markup" d="M -183.75000000000003 -142.59259259259264 a 20.416666666666668 20.37037037037037 0 1 1 20.416666666666668 -20.37037037037037 c 2.0416666666666674 -23.819444444444446 38.79166666666668 -23.819444444444446 40.83333333333334 0 c 2.0416666666666674 -23.819444444444446 38.79166666666668 -23.819444444444446 40.83333333333334 0 c 2.0416666666666674 -23.819444444444446 38.79166666666668 -23.819444444444446 40.83333333333334 0 c 2.0416666666666674 -23.819444444444446 38.79166666666668 -23.819444444444446 40.83333333333334 0 c 2.0416666666666674 -23.819444444444446 38.79166666666668 -23.819444444444446 40.83333333333334 0 c 2.0416666666666674 -23.819444444444446 38.79166666666668 -23.819444444444446 40.83333333333334 0 c 2.0416666666666674 -23.819444444444446 38.79166666666668 -23.819444444444446 40.83333333333334 0 c 2.0416666666666674 -23.819444444444446 38.79166666666668 -23.819444444444446 40.83333333333334 0 a 20.416666666666668 20.37037037037037 0 1 1 20.416666666666668 20.37037037037037 c 23.76543209876543 2.037037037037037 23.76543209876543 38.7037037037037 0 40.74074074074074 c 23.76543209876543 2.037037037037037 23.76543209876543 38.7037037037037 0 40.74074074074074 c 23.76543209876543 2.037037037037037 23.76543209876543 38.7037037037037 0 40.74074074074074 c 23.76543209876543 2.037037037037037 23.76543209876543 38.7037037037037 0 40.74074074074074 c 23.76543209876543 2.037037037037037 23.76543209876543 38.7037037037037 0 40.74074074074074 c 23.76543209876543 2.037037037037037 23.76543209876543 38.7037037037037 0 40.74074074074074 c 23.76543209876543 2.037037037037037 23.76543209876543 38.7037037037037 0 40.74074074074074 a 20.416666666666668 20.37037037037037 0 1 1 -20.416666666666668 20.37037037037037 c -2.0416666666666674 23.819444444444446 -38.79166666666668 23.819444444444446 -40.83333333333334 0 c -2.0416666666666674 23.819444444444446 -38.79166666666668 23.819444444444446 -40.83333333333334 0 c -2.0416666666666674 23.819444444444446 -38.79166666666668 23.819444444444446 -40.83333333333334 0 c -2.0416666666666674 23.819444444444446 -38.79166666666668 23.819444444444446 -40.83333333333334 0 c -2.0416666666666674 23.819444444444446 -38.79166666666668 23.819444444444446 -40.83333333333334 0 c -2.0416666666666674 23.819444444444446 -38.79166666666668 23.819444444444446 -40.83333333333334 0 c -2.0416666666666674 23.819444444444446 -38.79166666666668 23.819444444444446 -40.83333333333334 0 c -2.0416666666666674 23.819444444444446 -38.79166666666668 23.819444444444446 -40.83333333333334 0 a 20.416666666666668 20.37037037037037 0 1 1 -20.416666666666668 -20.37037037037037 c -23.76543209876543 -2.037037037037037 -23.76543209876543 -38.7037037037037 0 -40.74074074074074 c -23.76543209876543 -2.037037037037037 -23.76543209876543 -38.7037037037037 0 -40.74074074074074 c -23.76543209876543 -2.037037037037037 -23.76543209876543 -38.7037037037037 0 -40.74074074074074 c -23.76543209876543 -2.037037037037037 -23.76543209876543 -38.7037037037037 0 -40.74074074074074 c -23.76543209876543 -2.037037037037037 -23.76543209876543 -38.7037037037037 0 -40.74074074074074 c -23.76543209876543 -2.037037037037037 -23.76543209876543 -38.7037037037037 0 -40.74074074074074 c -23.76543209876543 -2.037037037037037 -23.76543209876543 -38.7037037037037 0 -40.74074074074074 z" stroke-width="10.416666666666629" stroke="rgba(255,0,0,1)" fill="none" transform="translate( -48.958333333333336 , 307.2916666666667 ) rotate( 0 )"/></g></svg>';
</script>
</body>
</html>

Related

handling objects offscreen for a view frustum

I have a view frustum that works great when looking at stuff from a distance. But for example, when i stand in the middle of a square, my current system struggles to place vertices which are behind me.
For example the image below demonstrates looking at a tile from a distance vs standing on top of it ...
My proccess for putting things onto screen can be described in 5 steps
cross product the co-ordinates of the object with my camera matrix
cross product the result of 1 with my projection_matrix
normalize the result of 2 by dividing through the 4th dimension of my co-ordinates (my w co-ordinate)
cull results of 3 (its not causing the problem, i tried without culling)
cross product 4 with to_screen_matrix
Basically the problem i have, is this procces is great at putting things on the screen but sometimes an object isnt on the screen... what co-ordinates should be used then?
Below is a drawing of what i think the problem is
below is my screen_projection function
return_screen_projection(dont_cull = false){
var position = cross_product(this.position , player.camera_matrix())
position = cross_product(position , projection.projection_matrix) // does this just convert the position to cameras reference frame.
for (let i = 0; i < position.length; i++) {
position[i] = position[i]/position[3]
}
if (dont_cull == false){
for (let i = 0; i < position.length; i++) {
if (i != 1){
if (this.is_this_object_behind_player()){for (let ii = 0; ii < position.length; ii++) {position[ii] = -9999;} console.log("culling1")}
if (position[i] > 2){for (let ii = 0; ii < position.length; ii++) {position[ii] = -9999;} console.log("culling2")}
if (position[i] < -2){for (let ii = 0; ii < position.length; ii++) {position[ii] = -9999;} console.log("culling3")}
}
} // also all examples say set position = 0 if culling
}
position = cross_product(position , projection.to_screen_matrix)
return [position[0],position[1]]
}
how could i better handle the position of a vertex offscreen, when some vertexes of the object im dealing with are on screen?
################## extra info below
below is a blob of 300 lines of code (sorry , i cant make it more minimal and reproducable with just a copy n paste)
running the below in a web browser will give you an example of the problem (w,a,s,d) to move (you start mired in the middle of an object, you may wish to step back to see better the first time)
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/11.3.3/math.js"></script>
<script async src="https://unpkg.com/es-module-shims#1.3.6/dist/es-module-shims.js"></script>
</head>
<body>
<div id="canvas div" style = "position: relative; left: 0px; float:left; top: 0px;" >
<h1> first person below </h1>
<canvas id="mi_canvas" width="300" height="300" style="border-style: solid;"></canvas> <br>
</div>
<script>
var floor_y_pos = 9
canvas = document.getElementById("mi_canvas");
ctx = canvas.getContext("2d");
render_distance = 1000;
fov = math.pi / 2
class Projection{
constructor(){
var NEAR = player.near_plane
var FAR = player.far_plane
var RIGHT = Math.tan(player.h_fov/2)
var LEFT = - RIGHT
var TOP = Math.tan(player.v_fov /2)
var BOTTOM = -TOP
var m00 = 2*NEAR / (RIGHT - LEFT)
var m02 = (RIGHT + LEFT)/(RIGHT - LEFT)
var m11 = 2*NEAR / (TOP - BOTTOM)
var m12 = (TOP + BOTTOM) /(TOP - BOTTOM)
var m22 = (FAR * NEAR) / (FAR - NEAR)
var m23 = -2 * NEAR * FAR / (FAR-NEAR)
this.projection_matrix = [
[-m00,0,m02,0],
[0,m11,0,0],
[m02,m12,-m22,-1],
[0,0,m23,0]
]
var HW=player.H_WIDTH
var HH = player.H_HEIGHT
this.to_screen_matrix = [
[HW,0,0,0],
[0,HH,0,0],
[0,0,1,0],
[HW,HH,0,1]
]
}
}
function multiply(a, b) {
var aNumRows = a.length, aNumCols = a[0].length,
bNumRows = b.length, bNumCols = b[0].length,
m = new Array(aNumRows); // initialize array of rows
for (var r = 0; r < aNumRows; ++r) {
m[r] = new Array(bNumCols); // initialize the current row
for (var c = 0; c < bNumCols; ++c) {
m[r][c] = 0; // initialize the current cell
for (var i = 0; i < aNumCols; ++i) {
m[r][c] += a[r][i] * b[i][c];
}
}
}
return m;
}
function mi_position_matrix_multiplier(A, B)
{
var new_matrix = []
for (var new_num_ind = 0; new_num_ind < A.length; ++new_num_ind)
{
this_num = 0;
for (var a_ind = 0; a_ind < A.length; ++a_ind)
{
this_num += (A[a_ind] * B[a_ind][new_num_ind])
}
new_matrix.push(this_num)
}
return new_matrix;
}
function pythagoras(thing1, thing2)
{
dist = (((thing1[0]-thing2[0])**2)+((thing1[1]-thing2[1])**2))**0.5
return dist
}
class vertex{
constructor(x, y,z , id){
this.id = id
this.position = [x,y,z,1]
this.min_dist = 1.5 // minimum possible distance between player and object
}
is_this_object_behind_player(){
var arrow_length = 0.0001;
var pointing_position = [player.position[0]+(player.forward[0]*arrow_length) , player.position[2]-(player.forward[2]*arrow_length)]
var dist1 = pythagoras([this.position[0],this.position[2]], pointing_position)
var dist2 = pythagoras([this.position[0],this.position[2]], [player.position[0],player.position[2]])
if (dist1 < dist2){
return true;}
else if (dist1 > dist2){
return false;}
else{}
}
return_screen_projection(dont_cull = false){
var position = mi_position_matrix_multiplier(this.position , player.camera_matrix())
position = mi_position_matrix_multiplier(position , projection.projection_matrix) // does this just convert the position to cameras reference frame.
for (let i = 0; i < position.length; i++) {
position[i] = position[i]/position[3]
}
if (dont_cull == false){
for (let i = 0; i < position.length; i++) {
if (i != 1){
if (this.is_this_object_behind_player()){for (let ii = 0; ii < position.length; ii++) {position[ii] = -9999;} console.log("culling1")}
if (position[i] > 2){for (let ii = 0; ii < position.length; ii++) {position[ii] = -9999;} console.log("culling2")}
if (position[i] < -2){for (let ii = 0; ii < position.length; ii++) {position[ii] = -9999;} console.log("culling3")}
}
} // also all examples say set position = 0 if culling
}
position = mi_position_matrix_multiplier(position , projection.to_screen_matrix)
return [position[0],position[1]]
}
}
class player{
constructor(){
this.position =[0,0,0,1.0]
this.forward = [0,0,1,1]
this.up = [0,1,0,1]
this.right =[1,0,0,1]
this.h_fov = 3.1415926535/3
this.v_fov = this.h_fov * (canvas.height / canvas.width)
this.near_plane = 1
this.far_plane = 100
this.moving_speed = 0.2
this.rotation_speed = 0.1
this.H_WIDTH = canvas.width/2
this.H_HEIGHT = canvas.height/2
this.anglePitch = 0
this.angleYaw = 0
}
set_camera_angle(){
var rotate = multiply(rotate_x(this.anglePitch) , rotate_y(this.angleYaw))
this.forward = [0, 0, 1, 1]
this.up = [0, 1, 0, 1]
this.right = [1, 0, 0, 1]
this.forward = mi_position_matrix_multiplier(this.forward , rotate)
this.right = mi_position_matrix_multiplier(this.right , rotate)
this.up = mi_position_matrix_multiplier(this.up , rotate)
}
camera_yaw(angle){
this.angleYaw += angle}
translate_matrix(self){
var x = this.position[0];
var y = this.position[1];
var z = this.position[2];
var w = this.position[3];
return [
[1,0,0,0],
[0,1,0,1],
[0,0,1,0],
[-x,-y,z, 1]
]}
rotate_matrix(){
var rx = this.right[0]
var ry = this.right[1]
var rz = this.right[2]
var w = this.right[3]
var fx = this.forward[0]
var fy = this.forward[1]
var fz = this.forward[2]
var w = this.forward[3]
var ux = this.up[0]
var uy = this.up[1]
var uz = this.up[2]
var w = this.up[3]
return [
[rx,ux,fx,0],
[ry,uy,fy,0],
[rz,uz,fz,0],
[0,0,0,1]
]
}
camera_matrix(){
return multiply(this.translate_matrix(), this.rotate_matrix());
}
move(event)
{
var key_code = parseInt(event.keyCode)
if (key_code == 37 || key_code == 39 || key_code == 83 || key_code == 87 || key_code == 119|| key_code == 115)
{
var dx = Math.cos(this.angleYaw)*this.moving_speed
var dy = Math.sin(this.angleYaw)*this.moving_speed
// console.log("that were moving = dx , dy = "+dx.toString()+" , "+dy.toString())
if ( key_code == 37 || key_code == 87 || key_code == 119) {
this.position[0] += -dy
this.position[2] += dx
}
if (key_code == 39 || key_code == 83 || key_code == 115) {
for (let i = 0; i < this.position.length; i++) {
this.position[0] += dy
this.position[2] += -dx
}
}
}
else {
if ( key_code == 38 || key_code == 65 || key_code == 97) {
this.camera_yaw(-this.rotation_speed)
}
if (key_code == 40 || key_code == 68 || key_code == 100) {
this.camera_yaw(this.rotation_speed)
}
this.set_camera_angle()
}
}
}
function translate(pos){
tx,ty,tz=pos
return np.array([
[1,0,0,0],
[0,1,0,0],
[0,0,1,0],
[tx,ty,tz,1]
])}
function rotate_x(angle){
return [
[1,0,0,0],
[0,Math.cos(angle),Math.sin(angle),0],
[0,-Math.sin(angle),Math.cos(angle),0],
[0,0,0,1]
]
}
function rotate_y(a){
return [
[math.cos(a),0, -math.sin(a),0],
[0,1,0,0],
[math.sin(a), 0 , math.cos(a),0],
[0,0,0,1]
]
}
function update_matrix_info_debug(matrix_name, matrix){
if (matrix[0].length > 1)
{
for (let x = 1; x < matrix.length+1; x++) {
for (let y = 1; y < matrix.length+1; y++) {
document.getElementById(matrix_name.toString()+"_"+x.toString()+y.toString()).innerHTML = matrix[x-1][y-1]
}
}
}
else {
for (let x = 1; x < matrix.length+1; x++) {document.getElementById(matrix_name.toString()+"_"+"1"+x.toString()).innerHTML = matrix[x-1]}
}
}
class two_d_surdace {
constructor(verex1,verex2,verex3,verex4 , colour){
this.vertices = [verex1,verex2,verex3,verex4]
this.colour = colour
}
draw_all_faces(){
var each_point = []
for (let i = 0; i < this.vertices.length; i++) {
each_point.push(this.vertices[i].return_screen_projection(true))
}
ctx.fillStyle = this.colour;
var moved_to_first_yet = false
for (let vertex = 0; vertex < this.vertices.length; vertex++)
{
if (moved_to_first_yet == false)
{
moved_to_first_yet = true
ctx.moveTo( each_point[vertex][0],each_point[vertex][1]);
}
else{ctx.lineTo( each_point[vertex][0],each_point[vertex][1]);}
}
ctx.closePath();
ctx.fill();
}
}
function if_off_screen(x, y)
{
if (x> canvas.width || x < 0){ return true;}
if (y > canvas.height || y < 0){ return true;}
return false;
}
function if_most_of_these_numbers_are_off_screen(numbers){
var threshold = 1; //Math.floor(numbers.length*0.49)
var counter = 0
for (let i = 0; i < numbers.length; i++) { if (if_off_screen(numbers[i][0], numbers[i][1])){ counter +=1} else{} }
if (counter >= threshold){return true}
return false;
}
player = new player();
projection = new Projection()
floor = new two_d_surdace(new vertex(50,floor_y_pos,50) , new vertex(-50,floor_y_pos,50) , new vertex(-50,floor_y_pos,-50) , new vertex(50,floor_y_pos,-50) , '#F90' )
$(document).on("keypress", function (event) {
player.move(event)
ctx.beginPath();
ctx.clearRect(0, 0, canvas.width, canvas.height);
floor.draw_all_faces()
});
</script>
</body>

How to output an image caption in custom typoscript template?

I use an image from page resources as a header image of the page. I could not find a solution to output the image caption (description). Here is the code.
lib.headerImage = COA
lib.headerImage {
30 = FILES
30 {
references {
table = pages
uid.data = page:uid
fieldName = media
}
begin = 0
renderObj = IMAGE
renderObj {
file {
import.data = file:current:uid
treatIdAsReference = 1
maxW = 640
maxH = 360
}
altText.data = file:current:alternative
titleText.data = file:current:title
layoutKey = picture
layout {
picture {
element = <picture class="header-image__picture">###SOURCECOLLECTION###<img src="###SRC###" ###PARAMS### ###ALTPARAMS### />###CAPTION###</picture>
source = <source srcset="###SRC###" media="###MEDIAQUERY###" />
}
}
sourceCollection {
big {
maxW = 2000
maxH = 1080
mediaQuery = (min-width: 1025px)
}
small {
maxW = 640
maxH = 360
mediaQuery = (max-width: 767px)
}
}
}
maxItems = 1
}
wrap = <div class="header-image">|</div>
}
Is it possible somehow to output the caption in the mark ###CAPTION### ?
or somewhere below the image? or it is better to use FLUID instead of typoscript ?
I found a solution. I put the image object inside COA
renderObj = COA
renderObj {
10 = IMAGE
10 {
file {
import.data = file:current:uid
treatIdAsReference = 1
maxW = 640
maxH = 360
}
altText.data = file:current:alternative
titleText.data = file:current:title
layoutKey = picture
layout {
picture {
element = <picture class="header-image__picture">###SOURCECOLLECTION###<img src="###SRC###" ###PARAMS### ###ALTPARAMS### /></picture>
source = <source srcset="###SRC###" media="###MEDIAQUERY###" />
}
}
sourceCollection {
big {
maxW = 2000
maxH = 1080
mediaQuery = (min-width: 1025px)
}
small {
maxW = 640
maxH = 360
mediaQuery = (max-width: 767px)
}
}
}
20 = TEXT
20.data = file:current:description
}

Porting ESP32 CameraWebServer example to https

I am trying to run the Arduino-ESP32 CameraWebServer example on https instead of http. I started by including esp_https_server.h instead of esp_http_server.h and changing the startCameraServer() function as follows:
void startCameraServer(){
#ifndef _ESP_HTTPS_SERVER_H_
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
#else
httpd_ssl_config config = HTTPD_SSL_CONFIG_DEFAULT();
config.cacert_len = cert->getCertLength();
config.cacert_pem = cert->getCertData();
config.prvtkey_len = cert->getPKLength();
config.prvtkey_pem = cert->getPKData();
#endif
httpd_uri_t index_uri = { .uri = "/", .method = HTTP_GET, .handler = index_handler, .user_ctx = NULL };
httpd_uri_t status_uri = { .uri = "/status", .method = HTTP_GET, .handler = status_handler, .user_ctx = NULL };
httpd_uri_t cmd_uri = { .uri = "/control", .method = HTTP_GET, .handler = cmd_handler, .user_ctx = NULL };
httpd_uri_t capture_uri = { .uri = "/capture", .method = HTTP_GET, .handler = capture_handler, .user_ctx = NULL };
httpd_uri_t stream_uri = { .uri = "/stream", .method = HTTP_GET, .handler = stream_handler, .user_ctx = NULL };
ra_filter_init(&ra_filter, 20);
mtmn_config.type = FAST;
mtmn_config.min_face = 80;
mtmn_config.pyramid = 0.707;
mtmn_config.pyramid_times = 4;
mtmn_config.p_threshold.score = 0.6;
mtmn_config.p_threshold.nms = 0.7;
mtmn_config.p_threshold.candidate_number = 20;
mtmn_config.r_threshold.score = 0.7;
mtmn_config.r_threshold.nms = 0.7;
mtmn_config.r_threshold.candidate_number = 10;
mtmn_config.o_threshold.score = 0.7;
mtmn_config.o_threshold.nms = 0.7;
mtmn_config.o_threshold.candidate_number = 1;
face_id_init(&id_list, FACE_ID_SAVE_NUMBER, ENROLL_CONFIRM_TIMES);
#ifndef _ESP_HTTPS_SERVER_H_
Serial.printf("Starting web server on port: '%d'\n", config.server_port);
if (httpd_start(&camera_httpd, &config) == ESP_OK) {
#else
Serial.printf("Starting web server on port: '%d'\n", config.port_secure);
if (httpd_ssl_start(&camera_httpd, &config) == ESP_OK) {
#endif
httpd_register_uri_handler(camera_httpd, &index_uri);
httpd_register_uri_handler(camera_httpd, &cmd_uri);
httpd_register_uri_handler(camera_httpd, &status_uri);
httpd_register_uri_handler(camera_httpd, &capture_uri);
}
#ifndef _ESP_HTTPS_SERVER_H_
config.server_port += 1;
config.ctrl_port += 1;
Serial.printf("Starting stream server on port: '%d'\n", config.server_port);
if (httpd_start(&stream_httpd, &config) == ESP_OK) {
#else
config.port_secure += 1;
config.httpd.ctrl_port += 1;
Serial.printf("Starting stream server on port: '%d'\n", config.port_secure);
if (httpd_ssl_start(&stream_httpd, &config) == ESP_OK) {
#endif
httpd_register_uri_handler(stream_httpd, &stream_uri);
}
}
If I include esp_http_server.h the original code will compile and everything runs fine. If I include esp_https_server.h the changes will compile and the webserver nicely comes up at port 443. The menu shows and I can get a still from the camera. The only thing that doesn't work is what it's all about: the live stream. The video window shows but only with a broken image icon. I see no messages in the terminal window in PlatformIO or anything in the browser's console. The stream_handler function, defined in stream_uri, is called when using http but not when using https.
My knowledge about webserver software is very minimalistic, I have no idea where to look further.
Does anybody know if I could get this working, any ideas?

Amchart with two lines

i have an amchart with two lines:
<script type="text/javascript">
var chart;
var graph;
var chartData2 = [
{"year":"2014-10-04 23:30:03", "v1":9.1, "v2":0},
{"year":"2014-10-04 23:45:02", "v1":8.8, "v2":86.2},
...
{"year":"2014-10-05 23:30:02", "v1":8.7, "v2":98.7},
{"year":"2014-10-05 23:45:02", "v1":8.5, "v2":98.7},
{"year":"2014-10-06 00:00:01", "v1":8.4, "v2":98.5},
{"year":"2014-10-06 00:15:02", "v1":8.5, "v2":98.3},
{"year":"2014-10-06 00:30:01", "v1":8.4, "v2":97.9}
];
AmCharts.ready(function () {
// SERIAL CHART
chart = new AmCharts.AmSerialChart();
chart.pathToImages = "../amcharts/images/";
chart.dataProvider = chartData2;
chart.marginLeft = 10;
chart.categoryField = "year";
chart.dataDateFormat = "JJ:NN:SS";
//chart.addListener("dataUpdated", zoomChart);
// AXES
// category
var categoryAxis = chart.categoryAxis;
categoryAxis.parseDates = true;
categoryAxis.minPeriod = "100";
categoryAxis.dashLength = 3;
categoryAxis.minorGridEnabled = true;
categoryAxis.minorGridAlpha = 0.1;
// value
var valueAxis = new AmCharts.ValueAxis();
valueAxis.id = "ax1";
valueAxis.axisAlpha = 0;
valueAxis.inside = true;
valueAxis.dashLength = 3;
valueAxis.position = "right";
chart.addValueAxis(valueAxis);
var valueAxis2 = new AmCharts.ValueAxis();
valueAxis2.id = "ax2";
valueAxis2.axisAlpha = 0;
valueAxis2.inside = true;
valueAxis2.dashLength = 3;
valueAxis2.baseValue = -20;
valueAxis2.position = "left";
chart.addValueAxis(valueAxis2);
// GRAPH
graph = new AmCharts.AmGraph();
graph.valueaxis = "ax1";
graph.type = "smoothedLine";
graph.lineColor = "#d1655d";
graph.negativeLineColor = "#637bb6";
graph.bullet = "square";
graph.bulletSize = 8;
graph.bulletBorderColor = "#FFFFFF";
graph.bulletBorderAlpha = 1;
graph.bulletBorderThickness = 2;
graph.lineThickness = 2;
graph.valueField = "v1";
graph.title = "title v1";
graph.balloonText = "[[category]]<br><b><span style='font-size:14px;'>[[value]]</span></b>";
chart.addGraph(graph);
graph2 = new AmCharts.AmGraph();
graph2.valueAxis = "ax2";
graph2.type = "smoothedLine";
graph2.lineColor = "#d1655d";
graph2.negativeLineColor = "#637bb6";
graph2.bullet = "round";
graph2.bulletSize = 8;
graph2.bulletBorderColor = "#FFFFFF";
graph2.bulletBorderAlpha = 1;
graph2.bulletBorderThickness = 2;
graph2.lineThickness = 2;
graph2.valueField = "v2";
graph2.title = "title v2";
graph2.balloonText = "[[category]]<br><b><span style='font-size:14px;'>[[value]]</span></b>";
chart.addGraph(graph2);
// CURSOR
var chartCursor = new AmCharts.ChartCursor();
chartCursor.cursorAlpha = 0;
chartCursor.cursorPosition = "mouse";
chartCursor.categoryBalloonDateFormat = "JJ:NN:SS";
chart.addChartCursor(chartCursor);
// SCROLLBAR
var chartScrollbar = new AmCharts.ChartScrollbar();
chart.addChartScrollbar(chartScrollbar);
chart.creditsPosition = "bottom-right";
// WRITE
chart.write("chartdiv2");
});
I can see the x-and y-axis, but no lines with values. Can anyone please help me?
Two problems:
dataDateFormat is incorrect, should be: chart.dataDateFormat = "YYYY-MM-DD JJ:NN:SS";
minPeriod is incorrect, should be: categoryAxis.minPeriod = "ss";

loading multiple collada objects at the same time Three.js

i have to load the same collada object multiple times.
Here is the code
var ai = [];
function setupAI() {
var c = getMapSector(cam.position);
var loader = new THREE.ColladaLoader();
loader.options.convertUpAxis = true;
loader.load('models/monster.DAE',function colladaReady( collada ){
var op = collada.scene;
skin = collada.skins [ 0 ];
for (var i = 0; i < NUMAI; i++) {
var o = THREE.SceneUtils.cloneObject(op);
o.scale.x = o.scale.y = o.scale.z = 0.006;
o.updateMatrix();
do {
var x = getRandBetween(0, mapW-1);
var z = getRandBetween(0, mapH-1);
} while (map[x][z] > 0 || (x == c.x && z == c.z));
x = Math.floor(x - mapW/2) * UNITSIZE;
z = Math.floor(z - mapW/2) * UNITSIZE;
o.position.set(x, UNITSIZE * 0.15, z);
o.health = 100;
//o.path = getAIpath(o);
o.pathPos = 1;
o.lastRandomX = Math.random();
o.lastRandomZ = Math.random();
o.lastShot = Date.now(); // Higher-fidelity timers aren't a big deal here.
ai.push(o);
scene.add(o);
}
});
}
but this gives error in this line
var o = THREE.SceneUtils.cloneObject(op);
but if i put loader inside the loop it becomes heavy and not load in browser.

Resources