WebGL: Converting JSON IFS 3D Model Data to Float32Arrays - webgl

I have a project I'm working on that involves rendering 3D models in WebGL, GitHub here. In pulling together several different resources, I've found two different formats for the model data: one with JSON entries like so:
var houseIFS =
{
"vertices": [
[ 2, -1, 2 ],
[ 2, -1, -2 ],
[ 2, 1, -2 ],
[ 2, 1, 2 ],
[ 1.5, 1.5, 0 ],
[ -1.5, 1.5, 0 ],
[ -2, -1, 2 ],
[ -2, 1, 2 ],
[ -2, 1, -2 ],
[ -2, -1, -2 ]
],
"faces": [
[ 0, 1, 2, 3 ],
[ 3, 2, 4 ],
[ 7, 3, 4, 5 ],
[ 2, 8, 5, 4 ],
[ 5, 8, 7 ],
[ 0, 3, 7, 6 ],
[ 0, 6, 9, 1 ],
[ 2, 1, 9, 8 ],
[ 6, 7, 8, 9 ]
],
"normals": [
[ 1, 0, 0 ],
[ 0.7071, 0.7071, 0 ],
[ 0, 0.9701, 0.2425 ],
[ 0, 0.9701, -0.2425 ],
[ -0.7071, 0.7071, 0 ],
[ 0, 0, 1 ],
[ 0, -1, 0 ],
[ 0, 0, -1 ],
[ -1, 0, 0 ]
],
"faceColors": [
[ 1, .8, .8 ],
[ .7, .7, 1 ],
[ 0, 0, 1 ],
[ 0, 0, .7 ],
[ .7, .7, 1 ],
[ 1, 0, 0 ],
[ .4, .4, .4 ],
[ 1, 0, 0 ],
[ 1, .8, .8 ],
]
};
and another with more primitive return types:
/** The return value of each function is an object, model, with properties:
*
* model.vertexPositions -- the vertex coordinates;
* model.vertexNormals -- the normal vectors;
* model.vertexTextureCoords -- the texture coordinates;
* model.indices -- the face indices.
*
* The first three properties are of type Float32Array, while
* model.indices is of type Uint16Array.
*/
I tried to create a method to convert the data from the "modern" version to the "primitive":
function convertPoly(model) {
return {
vertexPositions: new Float32Array(model.vertices),
vertexNormals: new Float32Array(model.normals),
vertexTextureCoords: new Float32Array(model.faces),
indices: new Uint16Array(model.faces)
}
}
but I don't think this is correct, and I don't see anything rendered after trying to render it. How can I compute indices from the vertices or faces? I guess I don't really understand what the indices really represent or how they work (is it triangle vertices of the faces?).

Related

Can a valid GeoJSON Polygon represent an island in a lake in an island?

I was a bit puzzled to find the GeoJSON
{
"type": "Polygon",
"coordinates": [
[
[-0.8, -0.8],
[ 0.8, -0.8],
[ 0.8, 0.8],
[-0.8, 0.8],
[-0.8, -0.8]
],
[
[-0.6, -0.6],
[-0.6, 0.6],
[ 0.6, 0.6],
[ 0.6, -0.6],
[-0.6, -0.6]
],
[
[-0.4, -0.4],
[ 0.4, -0.4],
[ 0.4, 0.4],
[-0.4, 0.4],
[-0.4, -0.4]
]
]
}
an "island in a lake in an island" if you will, rejected by one online validator, but accepted by another.
Looking again at RFC7846
For Polygons with more than one of these rings, the first MUST be
the exterior ring, and any others MUST be interior rings. The
exterior ring bounds the surface, and the interior rings (if
present) bound holes within the surface.
it looks to me that the first validator was correct, the final ring does not bound a hole in the surface defined by the first ring, so is invalid. So am I right in thinking that a valid GeoJSON Polygon cannot represent an island in a lake in an island? (So one would need to use a MultiPolygon to represent it?)
Correct, the inner rings are holes in the exterior ring so cannot have an island in a lake where an inner ring is not a hole.
A valid representation of an island would be a MultiPolygon where the first polygon is the larger polygon with a hole that forms the lake and the second polygon is the smaller polygon inside the first which is the island.
Here is the GeoJSON:
{
"type": "Feature",
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[-0.8, -0.8],
[ 0.8, -0.8],
[ 0.8, 0.8],
[-0.8, 0.8],
[-0.8, -0.8]
],
[
[-0.6, -0.6],
[-0.6, 0.6],
[ 0.6, 0.6],
[ 0.6, -0.6],
[-0.6, -0.6]
]
], [
[
[-0.4, -0.4],
[ 0.4, -0.4],
[ 0.4, 0.4],
[-0.4, 0.4],
[-0.4, -0.4]
]
]
]
}
}

Show Series and colorAxis both in Legend

Is it possible to have both colorAxis and series in the legend? http://jsfiddle.net/6k17dojn/ i see i can only show one at a time when I toggle this setting
colorAxis: {
showInLegend: true,
}
Currently to show a basic legend with colorAxis, you need to add some code to Highcharts core. This plugin below allows you to add colorAxis to a legend if showInLegend property is set to false:
(function(H) {
H.addEvent(H.Legend, 'afterGetAllItems', function(e) {
var colorAxisItems = [],
colorAxis = this.chart.colorAxis[0],
i;
if (colorAxis && colorAxis.options) {
if (colorAxis.options.dataClasses) {
colorAxisItems = colorAxis.getDataClassLegendSymbols();
} else {
colorAxisItems.push(colorAxis);
}
}
i = colorAxisItems.length;
while (i--) {
e.allItems.unshift(colorAxisItems[i]);
}
});
}(Highcharts))
Live demo: http://jsfiddle.net/BlackLabel/hs1zeruy/
API Reference: https://api.highcharts.com/highcharts/colorAxis.showInLegend
Docs: https://www.highcharts.com/docs/extending-highcharts
It's possible, but not with the data you currently work with. A heatmap's data is a set of coordinates, but here, your two series overlap.
Your raw data is :
[
[0,0,0.2, 0.4],
[0,1,0.1, 0.5],
[0,2,0.4, 0.9],
[0,3,0.7, 0.1],
[0,4,0.3, 0.6]
]
From there, you're mapping two series: 2018, and 2019 via the seriesMapping: [{x: 0, y: 1, value: 2}, {x: 0, y: 1, value: 3}] option.
You thus end up with the following two series:
2018 2019 2019 should be
[ [ [
[0, 0, 0.2], [0, 0, 0.4], [1, 0, 0.4],
[0, 1, 0.1], [0, 1, 0.5], [1, 1, 0.5],
[0, 2, 0.4], [0, 2, 0.9], [1, 2, 0.9],
[0, 3, 0.7], [0, 3, 0.1], [1, 3, 0.1],
[0, 4, 0.3] [0, 4, 0.6] [1, 4, 0.6]
] ] ]
Notice that in both cases, the coordinates are the same, but for 2019, the x value should be 1. Since you have 0 as x coordinate for both series, they overlap.
To fix you issue, you need to change your data (or pre-process it, whatever is easier). For example:
var data = '[[0,0,0.2, 0.4],[0,1,0.1, 0.5],[0,2,0.4, 0.9],[0,3,0.7, 0.1],[0,4,0.3, 0.6]]';
var rows = JSON.parse(data);
rows = $.map(rows, function(arr){
return [[
arr[0], arr[1], arr[2], // 2018
arr[0] + 1, arr[1], arr[3], // 2019
]];
});
// and the seriesMapping changes to
data: {
rows: rows,
firstRowAsNames: false,
seriesMapping: [{x: 0, y: 1, value: 2}, {x: 3, y: 4, value: 5}]
},
You can see it in action here: http://jsfiddle.net/Metoule/qgd2ca6p/6/

gltf 2.0 BoxTextured sample

I try to understand the data in the BoxTextured Model for the TEXCOORD_0 accessor.
As seen in the capture, the datas seems correct for POSITION and NORMALS but why values in the TEXCOORD_0 accessor aren't in range of "max": [ 1.0, 1.0 ], "min": [ 0.0, 0.0 ] but have a "max": [ 6.0, 1.0 ] ?
{
"bufferView": 2,
"byteOffset": 0,
"componentType": 5126,
"count": 24,
"max": [
6.0,
1.0
],
"min": [
0.0,
0.0
],
"type": "VEC2"
}
Should those be normalized ?
My texture applied is totally wrong : Rendered with uv test texture.
Where is my misunderstanding ?
Thank you
(I know I have a problem with my face orientation but that's another problem)
The 6.0 comes from the number of faces on the cube. Note that the sampler specifies REPEAT (10497):
"samplers": [
{
"magFilter": 9729,
"minFilter": 9986,
"wrapS": 10497,
"wrapT": 10497
}
],
so the image will be tiled repeatedly. It's just a simple way to get the logo rendered on all six faces of the cube.

LSTM: Figuring out the library?

I'm using the library https://github.com/cazala/synaptic
I am trying to predict the next value (value X) in the following series:
0 0 0 1 0 0 0 1 0 0 0 X
Which should be a 1.
Here is the code:
const options = {
peepholes: Layer.connectionType.ALL_TO_ALL,
hiddenToHidden: false,
outputToHidden: false,
outputToGates: false,
inputToOutput: true,
};
// 1 input, 3 hidden layers (4 nodes per layer), 1 output
const lstm = new Architect.LSTM(1, 4, 4, 4, 1, options);
const trainingArray = [
{
input: [0],
output: [0],
},
{
input: [0],
output: [0],
},
{
input: [0],
output: [1],
},
{
input: [1],
output: [0],
},
{
input: [0],
output: [0],
},
{
input: [0],
output: [0],
},
{
input: [0],
output: [1],
},
{
input: [1],
output: [0],
},
];
const trainingOptions = {
rate: 0.1,
iterations: 100000,
error: 0.05,
cost: null,
crossValidate: null,
};
let results = lstm.trainer.train(trainingArray, trainingOptions);
console.log(results);
array = [
0,
0,
0,
1,
0,
0,
0,
1,
0,
0,
0,
];
results = lstm.activate(array);
console.log(results);
The output in the console:
{ error: 0.049765018466871494, iterations: 673, time: 392 }
[ 0.05010961302724895 ]
I was expecting the result of the activation to be a value closer to 1 than 0 (much closer). I don't know if this is the library of my lack of knowledge with LSTM. Can someone point me in the correct direction?
I read through the source code and figured it out.
const synaptic = require('synaptic');
const Architect = synaptic.Architect;
const Layer = synaptic.Layer;
const lstmOptions = {
peepholes: Layer.connectionType.ALL_TO_ALL,
hiddenToHidden: false,
outputToHidden: false,
outputToGates: false,
inputToOutput: true,
};
const lstm = new Architect.LSTM(1, 4, 4, 4, 1, lstmOptions);
const trainSet = [
{ input: [0], output: [0.1] },
{ input: [1], output: [0.2] },
{ input: [0], output: [0.3] },
{ input: [1], output: [0.4] },
{ input: [0], output: [0.5] },
];
const trainOptions = {
rate: 0.2,
iterations: 10000,
error: 0.005,
cost: null,
crossValidate: null,
};
const trainResults = lstm.trainer.train(trainSet, trainOptions);
console.log(trainResults);
const testResults = [];
testResults[0] = lstm.activate([0]);
testResults[1] = lstm.activate([1]);
testResults[2] = lstm.activate([0]);
testResults[3] = lstm.activate([1]);
testResults[4] = lstm.activate([0]);
console.log(testResults);
Results in:
{ error: 0.004982436660844655, iterations: 2010, time: 384 }
[ [ 0.18288280009908592 ],
[ 0.2948083898027347 ],
[ 0.35061782593064206 ],
[ 0.3900799575806566 ],
[ 0.49454852760556606 ] ]
Which is accurate.

Naming a point on highcharts

I want to name a few points on my time data with irregular intervals. I am trying this as shown on fiddle by appending as
{ [Date.UTC(1970, 9, 27), 0 ] , name: 'point 1'},
but it is not working, any inputs ? I also want to have color for those points.
DEMO
You will have to pass data like:
data: [
{x:Date.UTC(1970, 11, 2), y:2,color:'red', name:'point 1'},
{x:Date.UTC(1970, 11, 3), y:3,color:'blue', name:'point 2'},
{x:Date.UTC(1970, 11, 4), y:4,color:'orange', name:'point 3'},
[Date.UTC(1970, 11, 2), 0.8 ],
[Date.UTC(1970, 11, 9), 0.6 ],
.......
...
Change from:
{ [Date.UTC(1970, 9, 27), 0 ] , name: 'point 1'},
To:
{ x: Date.UTC(1970, 9, 27), y: 0, name: 'point 1'},

Resources