Skip to content

Commit 1e77d98

Browse files
committed
interpolate custom vertex attributes on triangles crossing the IDL
1 parent 34ef097 commit 1e77d98

File tree

2 files changed

+234
-56
lines changed

2 files changed

+234
-56
lines changed

Source/Core/GeometryPipeline.js

+100-56
Original file line numberDiff line numberDiff line change
@@ -1919,13 +1919,46 @@ define([
19191919
var p0Scratch = new Cartesian3();
19201920
var p1Scratch = new Cartesian3();
19211921
var p2Scratch = new Cartesian3();
1922-
var barycentricScratch = new Cartesian3();
1922+
function interpolateAndPackCartesian3(i0, i1, i2, coords, sourceValues, currentValues, insertedIndex, normalize) {
1923+
var p0 = Cartesian3.fromArray(sourceValues, i0 * 3, p0Scratch);
1924+
var p1 = Cartesian3.fromArray(sourceValues, i1 * 3, p1Scratch);
1925+
var p2 = Cartesian3.fromArray(sourceValues, i2 * 3, p2Scratch);
1926+
1927+
Cartesian3.multiplyByScalar(p0, coords.x, p0);
1928+
Cartesian3.multiplyByScalar(p1, coords.y, p1);
1929+
Cartesian3.multiplyByScalar(p2, coords.z, p2);
1930+
1931+
var value = Cartesian3.add(p0, p1, p0);
1932+
Cartesian3.add(value, p2, value);
1933+
1934+
if (normalize) {
1935+
Cartesian3.normalize(value, value);
1936+
}
1937+
1938+
Cartesian3.pack(value, currentValues, insertedIndex * 3);
1939+
}
1940+
19231941
var s0Scratch = new Cartesian2();
19241942
var s1Scratch = new Cartesian2();
19251943
var s2Scratch = new Cartesian2();
1944+
function interpolateAndPackCartesian2(i0, i1, i2, coords, sourceValues, currentValues, insertedIndex) {
1945+
var s0 = Cartesian2.fromArray(sourceValues, i0 * 2, s0Scratch);
1946+
var s1 = Cartesian2.fromArray(sourceValues, i1 * 2, s1Scratch);
1947+
var s2 = Cartesian2.fromArray(sourceValues, i2 * 2, s2Scratch);
1948+
1949+
Cartesian2.multiplyByScalar(s0, coords.x, s0);
1950+
Cartesian2.multiplyByScalar(s1, coords.y, s1);
1951+
Cartesian2.multiplyByScalar(s2, coords.z, s2);
19261952

1927-
function computeTriangleAttributes(i0, i1, i2, point, positions, normals, tangents, bitangents, texCoords, extrudeDirections, currentAttributes, insertedIndex) {
1928-
if (!defined(normals) && !defined(tangents) && !defined(bitangents) && !defined(texCoords) && !defined(extrudeDirections)) {
1953+
var value = Cartesian2.add(s0, s1, s0);
1954+
Cartesian2.add(value, s2, value);
1955+
1956+
Cartesian2.pack(value, currentValues, insertedIndex * 2);
1957+
}
1958+
1959+
var barycentricScratch = new Cartesian3();
1960+
function computeTriangleAttributes(i0, i1, i2, point, positions, normals, tangents, bitangents, texCoords, extrudeDirections, currentAttributes, customAttributeNames, customAttributesLength, allAttributes, insertedIndex) {
1961+
if (!defined(normals) && !defined(tangents) && !defined(bitangents) && !defined(texCoords) && !defined(extrudeDirections) && customAttributesLength === 0) {
19291962
return;
19301963
}
19311964

@@ -1935,19 +1968,7 @@ define([
19351968
var coords = barycentricCoordinates(point, p0, p1, p2, barycentricScratch);
19361969

19371970
if (defined(normals)) {
1938-
var n0 = Cartesian3.fromArray(normals, i0 * 3, p0Scratch);
1939-
var n1 = Cartesian3.fromArray(normals, i1 * 3, p1Scratch);
1940-
var n2 = Cartesian3.fromArray(normals, i2 * 3, p2Scratch);
1941-
1942-
Cartesian3.multiplyByScalar(n0, coords.x, n0);
1943-
Cartesian3.multiplyByScalar(n1, coords.y, n1);
1944-
Cartesian3.multiplyByScalar(n2, coords.z, n2);
1945-
1946-
var normal = Cartesian3.add(n0, n1, n0);
1947-
Cartesian3.add(normal, n2, normal);
1948-
Cartesian3.normalize(normal, normal);
1949-
1950-
Cartesian3.pack(normal, currentAttributes.normal.values, insertedIndex * 3);
1971+
interpolateAndPackCartesian3(i0, i1, i2, coords, normals, currentAttributes.normal.values, insertedIndex, true);
19511972
}
19521973

19531974
if (defined(extrudeDirections)) {
@@ -1974,50 +1995,55 @@ define([
19741995
}
19751996

19761997
if (defined(tangents)) {
1977-
var t0 = Cartesian3.fromArray(tangents, i0 * 3, p0Scratch);
1978-
var t1 = Cartesian3.fromArray(tangents, i1 * 3, p1Scratch);
1979-
var t2 = Cartesian3.fromArray(tangents, i2 * 3, p2Scratch);
1980-
1981-
Cartesian3.multiplyByScalar(t0, coords.x, t0);
1982-
Cartesian3.multiplyByScalar(t1, coords.y, t1);
1983-
Cartesian3.multiplyByScalar(t2, coords.z, t2);
1984-
1985-
var tangent = Cartesian3.add(t0, t1, t0);
1986-
Cartesian3.add(tangent, t2, tangent);
1987-
Cartesian3.normalize(tangent, tangent);
1988-
1989-
Cartesian3.pack(tangent, currentAttributes.tangent.values, insertedIndex * 3);
1998+
interpolateAndPackCartesian3(i0, i1, i2, coords, tangents, currentAttributes.tangent.values, insertedIndex, true);
19901999
}
19912000

19922001
if (defined(bitangents)) {
1993-
var b0 = Cartesian3.fromArray(bitangents, i0 * 3, p0Scratch);
1994-
var b1 = Cartesian3.fromArray(bitangents, i1 * 3, p1Scratch);
1995-
var b2 = Cartesian3.fromArray(bitangents, i2 * 3, p2Scratch);
1996-
1997-
Cartesian3.multiplyByScalar(b0, coords.x, b0);
1998-
Cartesian3.multiplyByScalar(b1, coords.y, b1);
1999-
Cartesian3.multiplyByScalar(b2, coords.z, b2);
2000-
2001-
var bitangent = Cartesian3.add(b0, b1, b0);
2002-
Cartesian3.add(bitangent, b2, bitangent);
2003-
Cartesian3.normalize(bitangent, bitangent);
2004-
2005-
Cartesian3.pack(bitangent, currentAttributes.bitangent.values, insertedIndex * 3);
2002+
interpolateAndPackCartesian3(i0, i1, i2, coords, bitangents, currentAttributes.bitangent.values, insertedIndex, true);
20062003
}
20072004

20082005
if (defined(texCoords)) {
2009-
var s0 = Cartesian2.fromArray(texCoords, i0 * 2, s0Scratch);
2010-
var s1 = Cartesian2.fromArray(texCoords, i1 * 2, s1Scratch);
2011-
var s2 = Cartesian2.fromArray(texCoords, i2 * 2, s2Scratch);
2012-
2013-
Cartesian2.multiplyByScalar(s0, coords.x, s0);
2014-
Cartesian2.multiplyByScalar(s1, coords.y, s1);
2015-
Cartesian2.multiplyByScalar(s2, coords.z, s2);
2006+
interpolateAndPackCartesian2(i0, i1, i2, coords, texCoords, currentAttributes.st.values, insertedIndex);
2007+
}
20162008

2017-
var texCoord = Cartesian2.add(s0, s1, s0);
2018-
Cartesian2.add(texCoord, s2, texCoord);
2009+
if (customAttributesLength > 0) {
2010+
for (var i = 0; i < customAttributesLength; i++) {
2011+
var attributeName = customAttributeNames[i];
2012+
genericInterpolate(i0, i1, i2, coords, insertedIndex, allAttributes[attributeName], currentAttributes[attributeName]);
2013+
}
2014+
}
2015+
}
20192016

2020-
Cartesian2.pack(texCoord, currentAttributes.st.values, insertedIndex * 2);
2017+
var q0Scratch = new Cartesian4();
2018+
var q1Scratch = new Cartesian4();
2019+
var q2Scratch = new Cartesian4();
2020+
function genericInterpolate(i0, i1, i2, coords, insertedIndex, sourceAttribute, currentAttribute) {
2021+
var componentsPerAttribute = sourceAttribute.componentsPerAttribute;
2022+
var sourceValues = sourceAttribute.values;
2023+
var currentValues = currentAttribute.values;
2024+
switch(componentsPerAttribute) {
2025+
case 4:
2026+
var q0 = Cartesian4.fromArray(sourceValues, i0 * 4, q0Scratch);
2027+
var q1 = Cartesian4.fromArray(sourceValues, i1 * 4, q1Scratch);
2028+
var q2 = Cartesian4.fromArray(sourceValues, i2 * 4, q2Scratch);
2029+
2030+
Cartesian4.multiplyByScalar(q0, coords.x, q0);
2031+
Cartesian4.multiplyByScalar(q1, coords.y, q1);
2032+
Cartesian4.multiplyByScalar(q2, coords.z, q2);
2033+
2034+
var value = Cartesian4.add(q0, q1, q0);
2035+
Cartesian4.add(value, q2, value);
2036+
2037+
Cartesian4.pack(value, currentValues, insertedIndex * 4);
2038+
break;
2039+
case 3:
2040+
interpolateAndPackCartesian3(i0, i1, i2, coords, sourceValues, currentValues, insertedIndex, false);
2041+
break;
2042+
case 2:
2043+
interpolateAndPackCartesian2(i0, i1, i2, coords, sourceValues, currentValues, insertedIndex);
2044+
break;
2045+
default:
2046+
currentValues[insertedIndex] = sourceValues[i0] * coords.x + sourceValues[i1] * coords.y + sourceValues[i2] * coords.z;
20212047
}
20222048
}
20232049

@@ -2044,6 +2070,14 @@ define([
20442070
return insertIndex;
20452071
}
20462072

2073+
var NAMED_ATTRIBUTES = {
2074+
position : true,
2075+
normal : true,
2076+
bitangent : true,
2077+
tangent : true,
2078+
st : true,
2079+
extrudeDirection : true
2080+
};
20472081
function splitLongitudeTriangles(instance) {
20482082
var geometry = instance.geometry;
20492083
var attributes = geometry.attributes;
@@ -2055,6 +2089,16 @@ define([
20552089
var extrudeDirections = (defined(attributes.extrudeDirection)) ? attributes.extrudeDirection.values : undefined;
20562090
var indices = geometry.indices;
20572091

2092+
var customAttributeNames = [];
2093+
for (var attributeName in attributes) {
2094+
if (attributes.hasOwnProperty(attributeName)) {
2095+
if (!NAMED_ATTRIBUTES[attributeName] && defined(attributes[attributeName])) {
2096+
customAttributeNames.push(attributeName);
2097+
}
2098+
}
2099+
}
2100+
var customAttributesLength = customAttributeNames.length;
2101+
20582102
var eastGeometry = copyGeometryForSplit(geometry);
20592103
var westGeometry = copyGeometryForSplit(geometry);
20602104

@@ -2106,7 +2150,7 @@ define([
21062150
}
21072151

21082152
insertedIndex = insertSplitPoint(currentAttributes, currentIndices, currentIndexMap, indices, resultIndex < 3 ? i + resultIndex : -1, point);
2109-
computeTriangleAttributes(i0, i1, i2, point, positions, normals, tangents, bitangents, texCoords, extrudeDirections, currentAttributes, insertedIndex);
2153+
computeTriangleAttributes(i0, i1, i2, point, positions, normals, tangents, bitangents, texCoords, extrudeDirections, currentAttributes, customAttributeNames, customAttributesLength, attributes, insertedIndex);
21102154
}
21112155
} else {
21122156
if (defined(result)) {
@@ -2126,13 +2170,13 @@ define([
21262170
}
21272171

21282172
insertedIndex = insertSplitPoint(currentAttributes, currentIndices, currentIndexMap, indices, i, p0);
2129-
computeTriangleAttributes(i0, i1, i2, p0, positions, normals, tangents, bitangents, texCoords, extrudeDirections, currentAttributes, insertedIndex);
2173+
computeTriangleAttributes(i0, i1, i2, p0, positions, normals, tangents, bitangents, texCoords, extrudeDirections, currentAttributes, customAttributeNames, customAttributesLength, attributes, insertedIndex);
21302174

21312175
insertedIndex = insertSplitPoint(currentAttributes, currentIndices, currentIndexMap, indices, i + 1, p1);
2132-
computeTriangleAttributes(i0, i1, i2, p1, positions, normals, tangents, bitangents, texCoords, extrudeDirections, currentAttributes, insertedIndex);
2176+
computeTriangleAttributes(i0, i1, i2, p1, positions, normals, tangents, bitangents, texCoords, extrudeDirections, currentAttributes, customAttributeNames, customAttributesLength, attributes, insertedIndex);
21332177

21342178
insertedIndex = insertSplitPoint(currentAttributes, currentIndices, currentIndexMap, indices, i + 2, p2);
2135-
computeTriangleAttributes(i0, i1, i2, p2, positions, normals, tangents, bitangents, texCoords, extrudeDirections, currentAttributes, insertedIndex);
2179+
computeTriangleAttributes(i0, i1, i2, p2, positions, normals, tangents, bitangents, texCoords, extrudeDirections, currentAttributes, customAttributeNames, customAttributesLength, attributes, insertedIndex);
21362180
}
21372181
}
21382182

Specs/Core/GeometryPipelineSpec.js

+134
Original file line numberDiff line numberDiff line change
@@ -1871,6 +1871,140 @@ defineSuite([
18711871
expect(splitInstance).toBe(instance);
18721872
});
18731873

1874+
it('splitLongitude interpolates custom attributes for geometry split by the IDL', function() {
1875+
var p0 = Cartesian3.fromDegrees(-179.0, 0.0);
1876+
var p1 = Cartesian3.fromDegrees(179.0, 0.0);
1877+
var p2 = Cartesian3.fromDegrees(-179.0, 1.0);
1878+
1879+
var positions = new Float64Array([
1880+
p0.x, p0.y, p0.z,
1881+
p1.x, p1.y, p1.z,
1882+
p2.x, p2.y, p2.z
1883+
]);
1884+
1885+
var vec4s = new Uint8Array([
1886+
0, 0, 0, 0,
1887+
0, 0, 0, 255,
1888+
0, 0, 0, 0
1889+
]);
1890+
1891+
var vec3s = new Uint8Array([
1892+
0, 0, 0,
1893+
0, 0, 255,
1894+
0, 0, 0
1895+
]);
1896+
1897+
var vec2s = new Uint8Array([
1898+
0, 0,
1899+
0, 255,
1900+
0, 0
1901+
]);
1902+
1903+
var scalars = new Uint8Array([0, 255, 0]);
1904+
1905+
var instance = new GeometryInstance({
1906+
geometry : new Geometry({
1907+
attributes : {
1908+
position : new GeometryAttribute({
1909+
componentDatatype : ComponentDatatype.DOUBLE,
1910+
componentsPerAttribute : 3,
1911+
values : positions
1912+
}),
1913+
vec4s: new GeometryAttribute({
1914+
componentDatatype: ComponentDatatype.UNSIGNED_BYTE,
1915+
componentsPerAttribute: 4,
1916+
values: vec4s
1917+
}),
1918+
vec3s: new GeometryAttribute({
1919+
componentDatatype: ComponentDatatype.UNSIGNED_BYTE,
1920+
componentsPerAttribute: 3,
1921+
values: vec3s
1922+
}),
1923+
vec2s: new GeometryAttribute({
1924+
componentDatatype: ComponentDatatype.UNSIGNED_BYTE,
1925+
componentsPerAttribute: 2,
1926+
values: vec2s
1927+
}),
1928+
scalars: new GeometryAttribute({
1929+
componentDatatype: ComponentDatatype.UNSIGNED_BYTE,
1930+
componentsPerAttribute: 1,
1931+
values: scalars
1932+
})
1933+
},
1934+
indices : new Uint16Array([0, 1, 2]),
1935+
primitiveType : PrimitiveType.TRIANGLES,
1936+
boundingSphere : BoundingSphere.fromVertices(positions)
1937+
})
1938+
});
1939+
1940+
var splitInstance = GeometryPipeline.splitLongitude(instance);
1941+
var eastHemisphereGeometry = splitInstance.eastHemisphereGeometry;
1942+
expect(eastHemisphereGeometry.indices.length).toEqual(3);
1943+
1944+
var newVec4s = eastHemisphereGeometry.attributes.vec4s.values;
1945+
var newVec3s = eastHemisphereGeometry.attributes.vec3s.values;
1946+
var newVec2s = eastHemisphereGeometry.attributes.vec2s.values;
1947+
var newScalars = eastHemisphereGeometry.attributes.scalars.values;
1948+
var i;
1949+
var index;
1950+
1951+
// Expect eastern hemisphere vertices to all be 255 or 127 at the end of the value
1952+
expect(newScalars.indexOf(127)).not.toBe(-1);
1953+
expect(newVec4s.indexOf(127)).not.toBe(-1);
1954+
expect(newVec3s.indexOf(127)).not.toBe(-1);
1955+
expect(newVec2s.indexOf(127)).not.toBe(-1);
1956+
for (i = 0; i < 3; i++) {
1957+
expect(newScalars[i] === 255 || newScalars[i] === 127).toBe(true);
1958+
1959+
index = i * 2;
1960+
expect(newVec2s[index]).toBe(0);
1961+
expect(newVec2s[index + 1] === 255 || newVec2s[index + 1] === 127).toBe(true);
1962+
1963+
index = i * 3;
1964+
expect(newVec3s[index]).toBe(0);
1965+
expect(newVec3s[index + 1]).toBe(0);
1966+
expect(newVec3s[index + 2] === 255 || newVec3s[index + 2] === 127).toBe(true);
1967+
1968+
index = i * 4;
1969+
expect(newVec4s[index]).toBe(0);
1970+
expect(newVec4s[index + 1]).toBe(0);
1971+
expect(newVec4s[index + 2]).toBe(0);
1972+
expect(newVec4s[index + 3] === 255 || newVec4s[index + 3] === 127).toBe(true);
1973+
}
1974+
1975+
var westHemisphereGeometry = splitInstance.westHemisphereGeometry;
1976+
expect(westHemisphereGeometry.indices.length).toEqual(6);
1977+
1978+
newVec4s = westHemisphereGeometry.attributes.vec4s.values;
1979+
newVec3s = westHemisphereGeometry.attributes.vec3s.values;
1980+
newVec2s = westHemisphereGeometry.attributes.vec2s.values;
1981+
newScalars = westHemisphereGeometry.attributes.scalars.values;
1982+
1983+
// Expect eastern hemisphere vertices to all be 0 or 127 at the end of the value
1984+
expect(newScalars.indexOf(127)).not.toBe(-1);
1985+
expect(newVec4s.indexOf(127)).not.toBe(-1);
1986+
expect(newVec3s.indexOf(127)).not.toBe(-1);
1987+
expect(newVec2s.indexOf(127)).not.toBe(-1);
1988+
for (i = 0; i < 4; i++) {
1989+
expect(newScalars[i] === 0 || newScalars[i] === 127).toBe(true);
1990+
1991+
index = i * 2;
1992+
expect(newVec2s[index]).toBe(0);
1993+
expect(newVec2s[index + 1] === 0 || newVec2s[index + 1] === 127).toBe(true);
1994+
1995+
index = i * 3;
1996+
expect(newVec3s[index]).toBe(0);
1997+
expect(newVec3s[index + 1]).toBe(0);
1998+
expect(newVec3s[index + 2] === 0 || newVec3s[index + 2] === 127).toBe(true);
1999+
2000+
index = i * 4;
2001+
expect(newVec4s[index]).toBe(0);
2002+
expect(newVec4s[index + 1]).toBe(0);
2003+
expect(newVec4s[index + 2]).toBe(0);
2004+
expect(newVec4s[index + 3] === 0 || newVec4s[index + 3] === 127).toBe(true);
2005+
}
2006+
});
2007+
18742008
it('splitLongitude provides indices for an un-indexed triangle list', function() {
18752009
var instance = new GeometryInstance({
18762010
geometry : new Geometry({

0 commit comments

Comments
 (0)