Skip to content

Commit 6f4f8a8

Browse files
authored
LDrawLoader: Fix incorrect normals on double sided faces. (#33383)
1 parent 8d4f7b8 commit 6f4f8a8

3 files changed

Lines changed: 786 additions & 48 deletions

File tree

examples/jsm/loaders/LDrawLoader.js

Lines changed: 39 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,21 +1015,9 @@ class LDrawParsedCache {
10151015
faceNormal: null,
10161016
vertices: [ v0, v1, v2 ],
10171017
normals: [ null, null, null ],
1018+
doubleSided: doubleSided,
10181019
} );
1019-
totalFaces ++;
1020-
1021-
if ( doubleSided === true ) {
1022-
1023-
faces.push( {
1024-
material: material,
1025-
colorCode: colorCode,
1026-
faceNormal: null,
1027-
vertices: [ v2, v1, v0 ],
1028-
normals: [ null, null, null ],
1029-
} );
1030-
totalFaces ++;
1031-
1032-
}
1020+
totalFaces += doubleSided ? 2 : 1;
10331021

10341022
break;
10351023

@@ -1065,21 +1053,9 @@ class LDrawParsedCache {
10651053
faceNormal: null,
10661054
vertices: [ v0, v1, v2, v3 ],
10671055
normals: [ null, null, null, null ],
1056+
doubleSided: doubleSided,
10681057
} );
1069-
totalFaces += 2;
1070-
1071-
if ( doubleSided === true ) {
1072-
1073-
faces.push( {
1074-
material: material,
1075-
colorCode: colorCode,
1076-
faceNormal: null,
1077-
vertices: [ v3, v2, v1, v0 ],
1078-
normals: [ null, null, null, null ],
1079-
} );
1080-
totalFaces += 2;
1081-
1082-
}
1058+
totalFaces += doubleSided ? 4 : 2;
10831059

10841060
break;
10851061

@@ -1550,13 +1526,22 @@ function createObject( loader, elements, elementSize, isConditionalSegments = fa
15501526

15511527
}
15521528

1553-
for ( let j = 0, l = vertices.length; j < l; j ++ ) {
1529+
const sideCount = elementSize === 3 && elem.doubleSided ? 2 : 1;
1530+
const sideVertCount = vertices.length;
1531+
const totalVertCount = sideVertCount * sideCount;
15541532

1555-
const v = vertices[ j ];
1556-
const index = offset + j * 3;
1557-
positions[ index + 0 ] = v.x;
1558-
positions[ index + 1 ] = v.y;
1559-
positions[ index + 2 ] = v.z;
1533+
for ( let s = 0; s < sideCount; s ++ ) {
1534+
1535+
for ( let j = 0; j < sideVertCount; j ++ ) {
1536+
1537+
// front side: original order; back side: reversed winding
1538+
const v = vertices[ s === 0 ? j : sideVertCount - 1 - j ];
1539+
const index = offset + ( s * sideVertCount + j ) * 3;
1540+
positions[ index + 0 ] = v.x;
1541+
positions[ index + 1 ] = v.y;
1542+
positions[ index + 2 ] = v.z;
1543+
1544+
}
15601545

15611546
}
15621547

@@ -1589,20 +1574,27 @@ function createObject( loader, elements, elementSize, isConditionalSegments = fa
15891574

15901575
}
15911576

1592-
for ( let j = 0, l = elemNormals.length; j < l; j ++ ) {
1577+
const normalCount = elemNormals.length;
1578+
for ( let s = 0; s < sideCount; s ++ ) {
15931579

1594-
// use face normal if a vertex normal is not provided
1595-
let n = elem.faceNormal;
1596-
if ( elemNormals[ j ] ) {
1580+
const sign = s === 0 ? 1 : - 1;
1581+
for ( let j = 0; j < normalCount; j ++ ) {
15971582

1598-
n = elemNormals[ j ].norm;
1583+
// back side reuses the front normals in reversed order, with negated direction
1584+
const idx = s === 0 ? j : normalCount - 1 - j;
1585+
let n = elem.faceNormal;
1586+
if ( elemNormals[ idx ] ) {
15991587

1600-
}
1588+
n = elemNormals[ idx ].norm;
16011589

1602-
const index = offset + j * 3;
1603-
normals[ index + 0 ] = n.x;
1604-
normals[ index + 1 ] = n.y;
1605-
normals[ index + 2 ] = n.z;
1590+
}
1591+
1592+
const index = offset + ( s * normalCount + j ) * 3;
1593+
normals[ index + 0 ] = sign * n.x;
1594+
normals[ index + 1 ] = sign * n.y;
1595+
normals[ index + 2 ] = sign * n.z;
1596+
1597+
}
16061598

16071599
}
16081600

@@ -1650,15 +1642,15 @@ function createObject( loader, elements, elementSize, isConditionalSegments = fa
16501642

16511643
prevMaterial = elem.colorCode;
16521644
index0 = offset / 3;
1653-
numGroupVerts = vertices.length;
1645+
numGroupVerts = totalVertCount;
16541646

16551647
} else {
16561648

1657-
numGroupVerts += vertices.length;
1649+
numGroupVerts += totalVertCount;
16581650

16591651
}
16601652

1661-
offset += 3 * vertices.length;
1653+
offset += 3 * totalVertCount;
16621654

16631655
}
16641656

0 commit comments

Comments
 (0)