Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
108 changes: 101 additions & 7 deletions examples/jsm/loaders/collada/ColladaComposer.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ import {
Skeleton,
SkinnedMesh,
SpotLight,
Triangle,
Vector2,
Vector3,
VectorKeyframeTrack,
SRGBColorSpace
SRGBColorSpace,
ShapeUtils
} from 'three';

import { getElementsByTagName, parseFloats } from './ColladaParser.js';
Expand Down Expand Up @@ -1626,6 +1628,7 @@ class ColladaComposer {
count = primitive.count * 3;
break;

case 'polygons':
case 'polylist':

for ( let g = 0; g < primitive.count; g ++ ) {
Expand Down Expand Up @@ -1674,7 +1677,7 @@ class ColladaComposer {

const input = inputs[ name ];

switch ( name ) {
switch ( name ) {

case 'VERTEX':
for ( const key in vertices ) {
Expand Down Expand Up @@ -1856,13 +1859,103 @@ class ColladaComposer {

} else if ( count > 4 ) {

for ( let k = 1, kl = ( count - 2 ); k <= kl; k ++ ) {
const vertices = [];

const a = index + stride * 0;
const b = index + stride * k;
const c = index + stride * ( k + 1 );
// prepare vertices which represent the polygon's contour

pushVector( a ); pushVector( b ); pushVector( c );
for ( let k = 0; k < count; k ++ ) {

const a = index + stride * k;
const positionIndex = indices[ a ] * sourceStride;

const x = sourceArray[ positionIndex ];
const y = sourceArray[ positionIndex + 1 ];
const z = sourceArray[ positionIndex + 2 ];

vertices.push( new Vector3( x, y, z ) );

}

// determine surface normal

const normal = new Vector3();
const _triangle = new Triangle();

_triangle.a = vertices[ 0 ];
_triangle.b = vertices[ 1 ];
_triangle.c = vertices[ 2 ];
_triangle.getNormal( normal );

// project to 2D and triangulate

const vertices2D = [];

if ( Math.abs( normal.x ) > Math.abs( normal.y ) && Math.abs( normal.x ) > Math.abs( normal.z ) ) {

for ( let k = 0; k < count; k ++ ) {

vertices2D.push( new Vector2( vertices[ k ].y, vertices[ k ].z ) );

}

} else if ( Math.abs( normal.y ) > Math.abs( normal.z ) ) {

for ( let k = 0; k < count; k ++ ) {

vertices2D.push( new Vector2( vertices[ k ].x, vertices[ k ].z ) );

}

} else {

for ( let k = 0; k < count; k ++ ) {

vertices2D.push( new Vector2( vertices[ k ].x, vertices[ k ].y ) );

}

}

const isClockWise = ShapeUtils.isClockWise( vertices2D );

if ( isClockWise === true ) {

vertices2D.reverse();

}

const faces = ShapeUtils.triangulateShape( vertices2D, [] );

// build indices

for ( let k = 0; k < faces.length; k ++ ) {

const face = faces[ k ];

let i0, i1, i2;

if ( isClockWise === false ) {

i0 = face[ 0 ];
i1 = face[ 1 ];
i2 = face[ 2 ];


} else {

i0 = count - 1 - face[ 0 ];
i1 = count - 1 - face[ 2 ];
i2 = count - 1 - face[ 1 ];

}

const a = index + stride * i0;
const b = index + stride * i1;
const c = index + stride * i2;

pushVector( a );
pushVector( b );
pushVector( c );

}

Expand Down Expand Up @@ -2627,6 +2720,7 @@ class ColladaComposer {
break;

case 'triangles':
case 'polygons':
case 'polylist':
if ( skinning ) {

Expand Down
9 changes: 6 additions & 3 deletions examples/jsm/loaders/collada/ColladaParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -1231,9 +1231,6 @@ class ColladaParser {
break;

case 'polygons':
console.warn( 'THREE.ColladaLoader: Unsupported primitive type: ', child.nodeName );
break;

case 'lines':
case 'linestrips':
case 'polylist':
Expand Down Expand Up @@ -1353,6 +1350,12 @@ class ColladaParser {

}

if ( primitive.type === 'polygons' ) {

primitive.vcount = [ primitive.p.length / primitive.stride ];

}

return primitive;

}
Expand Down
47 changes: 47 additions & 0 deletions examples/models/collada/test/polygons.dae
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
<asset>
<created>2026-03-09T12:00:00Z</created>
<modified>2026-03-09T12:00:00Z</modified>
<unit name="meter" meter="1.0"/>
<up_axis>Y_UP</up_axis>
</asset>
<library_geometries>
<geometry id="QuadGeom" name="Quad">
<mesh>
<source id="Quad-pos">
<float_array id="Quad-pos-array" count="12">
-1.0 0.0 1.0
1.0 0.0 1.0
1.0 0.0 -1.0
-1.0 0.0 -1.0
</float_array>
<technique_common>
<accessor source="#Quad-pos-array" count="4" stride="3">
<param name="X" type="float"/>
<param name="Y" type="float"/>
<param name="Z" type="float"/>
</accessor>
</technique_common>
</source>
<vertices id="Quad-vertices">
<input semantic="POSITION" source="#Quad-pos"/>
</vertices>
<polygons count="1">
<input semantic="VERTEX" source="#Quad-vertices" offset="0"/>
<p>0 1 2 3</p>
</polygons>
</mesh>
</geometry>
</library_geometries>
<library_visual_scenes>
<visual_scene id="Scene" name="Scene">
<node id="QuadNode" name="QuadNode">
<instance_geometry url="#QuadGeom"/>
</node>
</visual_scene>
</library_visual_scenes>
<scene>
<instance_visual_scene url="#Scene"/>
</scene>
</COLLADA>
49 changes: 49 additions & 0 deletions examples/models/collada/test/polygons_concave.dae
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
<asset>
<created>2026-03-09T12:30:00Z</created>
<modified>2026-03-09T12:30:00Z</modified>
<unit name="meter" meter="1.0"/>
<up_axis>Y_UP</up_axis>
</asset>
<library_geometries>
<geometry id="ConcaveGeom" name="ConcaveL">
<mesh>
<source id="Concave-pos">
<float_array id="Concave-pos-array" count="18">
0.0 0.0 -1.0
-1.0 0.0 -1.0
-1.0 0.0 1.0
2.0 0.0 1.0
2.0 0.0 0.0
0.0 0.0 0.0
</float_array>
<technique_common>
<accessor source="#Concave-pos-array" count="6" stride="3">
<param name="X" type="float"/>
<param name="Y" type="float"/>
<param name="Z" type="float"/>
</accessor>
</technique_common>
</source>
<vertices id="Concave-vertices">
<input semantic="POSITION" source="#Concave-pos"/>
</vertices>
<polygons count="1">
<input semantic="VERTEX" source="#Concave-vertices" offset="0"/>
<p>0 1 2 3 4 5</p>
</polygons>
</mesh>
</geometry>
</library_geometries>
<library_visual_scenes>
<visual_scene id="Scene">
<node id="ConcaveNode">
<instance_geometry url="#ConcaveGeom"/>
</node>
</visual_scene>
</library_visual_scenes>
<scene>
<instance_visual_scene url="#Scene"/>
</scene>
</COLLADA>