Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

setAttribute works on FloatVertexAttribute #610

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion src/gfx_webgl.js
Original file line number Diff line number Diff line change
Expand Up @@ -406,8 +406,29 @@ x3dom.gfx_webgl = (function () {
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(szArr), gl.STATIC_DRAW);
}

shape._dirty.specialAttribs = false;
}
// Special attribs is FloatVertexAttribute
var AttribNodes = geoNode._mesh._dynamicFields;
var attribNode, attribName;
for (attribName in AttribNodes) {
attribNode = AttribNodes[attribName];
if (attribNode !== undefined && attribNode.value.length) {
// Remove old attribute buffer
var attribs = new Float32Array(attribNode.value);
var attribWebGLNode = shape._webgl.dynamicFields.find(
function(a){ return a.name == attribName;});
if (attribWebGLNode.buf.toString() == "[object WebGLBuffer]")
gl.deleteBuffer(attribWebGLNode.buf);
gl.deleteBuffer(attribWebGLNode.buf);
attribWebGLNode.buf = gl.createBuffer();

gl.bindBuffer(gl.ARRAY_BUFFER, attribWebGLNode.buf);
gl.bufferData(gl.ARRAY_BUFFER, attribs, gl.STATIC_DRAW);

attribs = null;
}
}
shape._dirty.specialAttribs = false;
// Maybe other special attribs here, though e.g. AFAIK only BG (which not handled here) has ids.
}
}
Expand Down
24 changes: 23 additions & 1 deletion src/nodes/CADGeometry/IndexedQuadSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,29 @@ x3dom.registerNodeType(
node._dirty.texcoords = true;
});
}
else if (fieldName.startsWith("attrib"))
{
var attrName = fieldName.slice(7);
var attrNode = this._cf.attrib.nodes.find(
function (a) {return a._vf.name == attrName;}
);
var attr_data= attrNode._vf.value;
var attr_numComp= attrNode._vf.numComponents;

this._mesh._dynamicFields[attrName].value = [];
this._mesh._dynamicFields[attrName].numComponents = attr_numComp;
indexes = this._vf.index;
for (var i=0; i < indexes.length; ++i) {
for (var j=0; j < attr_numComp;j++ ) {
this._mesh._dynamicFields[attrName].value.push(
attr_data[attr_numComp*indexes[i]+j]);
}
}
Array.forEach(this._parentNodes, function (node) {
node._dirty.specialAttribs = true;
});
}
}
}
)
);
);
16 changes: 16 additions & 0 deletions src/nodes/CADGeometry/QuadSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,22 @@ x3dom.registerNodeType(
node._dirty.texcoords = true;
});
}
else if (fieldName.startsWith("attrib"))
{
var attrName = fieldName.slice(7);
var attrNode = this._cf.attrib.nodes.find(
function (a) {return a._vf.name == attrName;}
);
var attr_data= attrNode._vf.value;
var attr_numComp= attrNode._vf.numComponents;

this._mesh._dynamicFields[attrName].numComponents = attr_numComp;
this._mesh._dynamicFields[attrName].value= attr_data.toGL();

Array.forEach(this._parentNodes, function (node) {
node._dirty.specialAttribs = true;
});
}
}
}
)
Expand Down
135 changes: 27 additions & 108 deletions src/nodes/Geometry3D/IndexedFaceSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ x3dom.registerNodeType(
{
if (fieldName != "coord" && fieldName != "normal" &&
fieldName != "texCoord" && fieldName != "color" &&
fieldName != "coordIndex")
fieldName != "coordIndex" && !fieldName.startsWith("attrib_"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why use startsWith instead of != and why the underscore in "attrib_" ? I do not think there is a field with such a name ?

{
x3dom.debug.logWarning("IndexedFaceSet: fieldChanged for " +
fieldName + " not yet implemented!");
Expand Down Expand Up @@ -791,8 +791,21 @@ x3dom.registerNodeType(
hasColor = false;
}
this._mesh._numColComponents = numColComponents;
if (fieldName.startsWith("attrib")) {
var attrName = fieldName.slice(7);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. But the name of the attribute is not provided after an underscore ("attrib_temperature") but only in the name field of the attrib child node.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name is given during the call of FiledChanged on the FloatVertexAttribute element
then the FloatVertexAttribute call the fieldChanged from IndexedFaceSet (the code above) with attrib__name_
see : 16fefd1

fieldChanged: function (fieldName) {
                 var that = this;
                 if (fieldName == "value" ||  fieldName == "numComponents") {
                     Array.forEach(this._parentNodes, function (node) {
                         node.fieldChanged("attrib_"+that._vf.name);
                     });
                 }
             }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. While that probably works. I do not think the node.fieldChanged() function is intended to be reused for internal purposes like this. Why not make a new function updateAttrib(name) or in IndexedFaceSet.js (and all possible parentNodes of FloatVertexAttribute) ? Or do the update right here ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea of the new function updateAttrib(name) is not bad, it can be similar to the handleAttibs in X3domComposedGeometryNode.
The only problem is in IFS, I cannot imagine a (proper) way to know which attribute needs update.
The ugly solution is to save in the node the name of the modified attribute (in _vf for exemple).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, the name in node.updateAttrib(name) would have the name of the changed attribute, no ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you call node.updateAttrib in the IFS, the only information given is FieldChanged("attribs").
A solution would be to write the function node.updateAttrib(name) in FloatVertexAttribute.js, and call it before (or after) the call of FieldChanged on IndexedFaceSet.

var attrNode = this._cf.attrib.nodes.find(
function (a) {return a._vf.name == attrName;}
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To find out which attribute changed, it is probably necessary to implement fieldChanged() in FloatVertexAttribute.js .
An option may be to just assume all attribs have changed and update all.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are no way to know which attribute changed in the FieldChanged of IndexedFaceSet, and this is made to avoid to update/compute all the other attributes.

if (attrNode) {
var attr_data = attrNode._vf.value;
var attr_numComp = attrNode._vf.numComponents;
var hasAttributes = this._mesh._dynamicFields[attrName] !== undefined;
this._mesh._dynamicFields[attrName].numComponents = attr_numComp;
this._mesh._dynamicFields[attrName].value = [];
}
}

var i, j, t, cnt, faceCnt;
var i, j, k, t, cnt, faceCnt;
var p0, p1, p2, n0, n1, n2, t0, t1, t2, c0, c1, c2;

if(this._vf.convex) {
Expand Down Expand Up @@ -865,8 +878,6 @@ x3dom.registerNodeType(
else if (hasColorInd && !colPerVert) { c2 = +colorInd[faceCnt]; }
else if (colPerVert) { c2 = p2; }
else { c2 = faceCnt; }
t = 3;

//this._mesh._indices[0].push(cnt++, cnt++, cnt++);

this._mesh._positions[0].push(positions[p0].x);
Expand Down Expand Up @@ -932,111 +943,18 @@ x3dom.registerNodeType(
this._mesh._texCoords[0].push(texCoords[t2].z);
}
}

//faceCnt++;
break;
case 3:
p1 = p2;
t1 = t2;
if (normPerVert) {
n1 = n2;
}
if (colPerVert) {
c1 = c2;
}
p2 = +indexes[i];

if (hasNormalInd && normPerVert) {
n2 = +normalInd[i];
} else if (hasNormalInd && !normPerVert) {
/*n2 = +normalInd[faceCnt];*/
} else if (normPerVert) {
n2 = p2;
} else {
n2 = faceCnt;
}

if (hasTexCoordInd) {
t2 = +texCoordInd[i];
} else {
t2 = p2;
}

if (hasColorInd && colPerVert) {
c2 = +colorInd[i];
} else if (hasColorInd && !colPerVert) {
/*c2 = +colorInd[faceCnt];*/
} else if (colPerVert) {
c2 = p2;
} else {
c2 = faceCnt;
}

//this._mesh._indices[0].push(cnt++, cnt++, cnt++);

this._mesh._positions[0].push(positions[p0].x);
this._mesh._positions[0].push(positions[p0].y);
this._mesh._positions[0].push(positions[p0].z);
this._mesh._positions[0].push(positions[p1].x);
this._mesh._positions[0].push(positions[p1].y);
this._mesh._positions[0].push(positions[p1].z);
this._mesh._positions[0].push(positions[p2].x);
this._mesh._positions[0].push(positions[p2].y);
this._mesh._positions[0].push(positions[p2].z);

if (hasNormal) {
this._mesh._normals[0].push(normals[n0].x);
this._mesh._normals[0].push(normals[n0].y);
this._mesh._normals[0].push(normals[n0].z);
this._mesh._normals[0].push(normals[n1].x);
this._mesh._normals[0].push(normals[n1].y);
this._mesh._normals[0].push(normals[n1].z);
this._mesh._normals[0].push(normals[n2].x);
this._mesh._normals[0].push(normals[n2].y);
this._mesh._normals[0].push(normals[n2].z);
}
//else {
this._mesh._multiIndIndices.push(p0, p1, p2);
//}

if (hasColor) {
this._mesh._colors[0].push(colors[c0].r);
this._mesh._colors[0].push(colors[c0].g);
this._mesh._colors[0].push(colors[c0].b);
if (numColComponents === 4) {
this._mesh._colors[0].push(colors[c0].a);
}
this._mesh._colors[0].push(colors[c1].r);
this._mesh._colors[0].push(colors[c1].g);
this._mesh._colors[0].push(colors[c1].b);
if (numColComponents === 4) {
this._mesh._colors[0].push(colors[c1].a);
}
this._mesh._colors[0].push(colors[c2].r);
this._mesh._colors[0].push(colors[c2].g);
this._mesh._colors[0].push(colors[c2].b);
if (numColComponents === 4) {
this._mesh._colors[0].push(colors[c2].a);
}
}

if (hasTexCoord) {
this._mesh._texCoords[0].push(texCoords[t0].x);
this._mesh._texCoords[0].push(texCoords[t0].y);
if (numTexComponents === 3) {
this._mesh._texCoords[0].push(texCoords[t0].z);
}
this._mesh._texCoords[0].push(texCoords[t1].x);
this._mesh._texCoords[0].push(texCoords[t1].y);
if (numTexComponents === 3) {
this._mesh._texCoords[0].push(texCoords[t1].z);
}
this._mesh._texCoords[0].push(texCoords[t2].x);
this._mesh._texCoords[0].push(texCoords[t2].y);
if (numTexComponents === 3) {
this._mesh._texCoords[0].push(texCoords[t2].z);
if (hasAttributes) {
var pInd = [p0,p1,p2];
for (j=0;j<3;j++) {
for (k = 0; k < attr_numComp; k++){
this._mesh._dynamicFields[attrName].value.push(
attr_data[attr_numComp*pInd[j]+k]
);
}
}
}
p1 = p2;
t1 = t2;

//faceCnt++;
break;
Expand Down Expand Up @@ -1147,6 +1065,7 @@ x3dom.registerNodeType(

Array.forEach(this._parentNodes, function (node) {
node.setGeoDirty();
if (hasAttributes) node._dirty.specialAttribs = true;
});
}
else {
Expand Down Expand Up @@ -1245,4 +1164,4 @@ x3dom.registerNodeType(
}
}
)
);
);
23 changes: 23 additions & 0 deletions src/nodes/Rendering/IndexedTriangleSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,29 @@ x3dom.registerNodeType(
node._dirty.texcoords = true;
});
}
else if (fieldName.startsWith("attrib"))
{
var attrName = fieldName.slice(7);
var attrNode = this._cf.attrib.nodes.find(
function (a) {return a._vf.name == attrName;}
);
var attr_data= attrNode._vf.value;
var attr_numComp= attrNode._vf.numComponents;

this._mesh._dynamicFields[attrName].value = [];
this._mesh._dynamicFields[attrName].numComponents = attr_numComp;
indexes = this._vf.index;
for (i=0; i < indexes.length; ++i) {
for (var j=0; j < attr_numComp;j++ ) {
this._mesh._dynamicFields[attrName].value.push(
attr_data[attr_numComp* indexes[i]+j]);
}
}

Array.forEach(this._parentNodes, function (node) {
node._dirty.specialAttribs = true;
});
}
// TODO: index
}
}
Expand Down
69 changes: 66 additions & 3 deletions src/nodes/Rendering/IndexedTriangleStripSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ x3dom.registerNodeType(
"IndexedTriangleStripSet",
"Rendering",
defineClass(x3dom.nodeTypes.X3DComposedGeometryNode,

/**
* Constructor for IndexedTriangleStripSet
* @constructs x3dom.nodeTypes.IndexedTriangleStripSet
Expand Down Expand Up @@ -41,7 +41,7 @@ x3dom.registerNodeType(

this._hasIndexOffset = false;
this._indexOffset = null;

},
{
hasIndexOffset: function() {
Expand Down Expand Up @@ -329,7 +329,8 @@ x3dom.registerNodeType(
fieldChanged: function(fieldName)
{
if (fieldName != "coord" && fieldName != "normal" &&
fieldName != "texCoord" && fieldName != "color")
fieldName != "texCoord" && fieldName != "color" &&
!fieldName.startsWith("attrib"))
{
x3dom.debug.logWarning("IndexedTriangleStripSet: fieldChanged for " +
fieldName + " not yet implemented!");
Expand Down Expand Up @@ -760,6 +761,52 @@ x3dom.registerNodeType(
node._dirty.texcoords = true;
});
}
if (fieldName.startsWith("attrib")) {
var indexes = this._vf.index;
var attrName = fieldName.slice(7);
var attrNode = this._cf.attrib.nodes.find(
function (a) {return a._vf.name == attrName;}
);
var attr_data= attrNode._vf.value;
var attr_numComp= attrNode._vf.numComponents;
var hasAttributes = this._mesh._dynamicFields[attrName];
this._mesh._dynamicFields[attrName].numComponents = attr_numComp;

var count = 0;
var index = [0, 0, 0];
this._mesh._dynamicFields[attrName].value = [];
for (i=0; i < indexes.length; ++i)
{
switch (count) {
case 0:
index[0] = indexes[i]*attr_numComp;
count++;
break;
case 1:
index[1] = indexes[i]*attr_numComp;
count++;
break;
case -1:
count = 0;
break;
default:
index[2] = indexes[i]*attr_numComp;
for (var l=0; l< 3; l++)
for (var k=0; k< attr_numComp; k++) {
this._mesh._dynamicFields[attrName].value.push(
attr_data[index[l]+k]);
}
if (count % 2 )
index[0]= index[1], index[1] = index[2];
else index[0] = index[2];
count = indexes[i+1] ==-1? -1: count+1;
break;
}
}
Array.forEach(this._parentNodes, function (node) {
node._dirty.specialAttribs = true;
});
}
}
else
{
Expand Down Expand Up @@ -861,6 +908,22 @@ x3dom.registerNodeType(
node._dirty.texcoords = true;
});
}
else if (fieldName.startsWith("attrib"))
{
attrName = fieldName.slice(7);
attrNode = this._cf.attrib.nodes.find(
function (a) {return a._vf.name == attrName;}
);
attr_data= attrNode._vf.value;
attr_numComp= attrNode._vf.numComponents;

this._mesh._dynamicFields[attrName].numComponents = attr_numComp;
this._mesh._dynamicFields[attrName].value= attr_data.toGL();

Array.forEach(this._parentNodes, function (node) {
node._dirty.specialAttribs = true;
});
}
}
}
}
Expand Down
Loading