Skip to content

Commit 3adf478

Browse files
Jonne Nauhamrdoob
Jonne Nauha
authored andcommitted
OBJLoader: When a new o/g starts, inherit the currently parsed material. (mrdoob#9013)
Inherited material is overwritten if 'usemtl' declaration is encountered after the object starts but prior to next object start. Exception to this is when faces have been declared to the inherited material, to keep MultiMaterial in sync. Fixes mrdoob#8792 and mrdoob#8871.
1 parent df810c1 commit 3adf478

File tree

1 file changed

+40
-1
lines changed

1 file changed

+40
-1
lines changed

examples/js/loaders/OBJLoader.js

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ THREE.OBJLoader.prototype = {
9595

9696
}
9797

98+
var previousMaterial = ( this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined );
99+
98100
this.object = {
99101
name : name || '',
100102
fromDeclaration : ( fromDeclaration !== false ),
@@ -111,14 +113,36 @@ THREE.OBJLoader.prototype = {
111113

112114
var previous = this._finalize( false );
113115

116+
// New usemtl declaration overwrites an inherited material, except if faces were declared
117+
// after the material, then it must be preserved for proper MultiMaterial continuation.
118+
if ( previous && ( previous.inherited || previous.groupCount <= 0 ) ) {
119+
120+
this.materials.splice( previous.index, 1 );
121+
122+
}
123+
114124
var material = {
115125
index : this.materials.length,
116126
name : name || '',
117127
mtllib : ( Array.isArray( libraries ) && libraries.length > 0 ? libraries[ libraries.length - 1 ] : '' ),
118128
smooth : ( previous !== undefined ? previous.smooth : this.smooth ),
119129
groupStart : ( previous !== undefined ? previous.groupEnd : 0 ),
120130
groupEnd : -1,
121-
groupCount : -1
131+
groupCount : -1,
132+
inherited : false,
133+
134+
clone : function( index ) {
135+
return {
136+
index : ( typeof index === 'number' ? index : this.index ),
137+
name : this.name,
138+
mtllib : this.mtllib,
139+
smooth : this.smooth,
140+
groupStart : this.groupEnd,
141+
groupEnd : -1,
142+
groupCount : -1,
143+
inherited : false
144+
};
145+
}
122146
};
123147

124148
this.materials.push( material );
@@ -144,6 +168,7 @@ THREE.OBJLoader.prototype = {
144168

145169
lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3;
146170
lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart;
171+
lastMultiMaterial.inherited = false;
147172

148173
}
149174

@@ -160,6 +185,20 @@ THREE.OBJLoader.prototype = {
160185
}
161186
};
162187

188+
// Inherit previous objects material.
189+
// Spec tells us that a declared material must be set to all objects until a new material is declared.
190+
// If a usemtl declaration is encountered while this new object is being parsed, it will
191+
// overwrite the inherited material. Exception being that there was already face declarations
192+
// to the inherited material, then it will be preserved for proper MultiMaterial continuation.
193+
194+
if ( previousMaterial && previousMaterial.name && typeof previousMaterial.clone === "function" ) {
195+
196+
var declared = previousMaterial.clone( 0 );
197+
declared.inherited = true;
198+
this.object.materials.push( declared );
199+
200+
}
201+
163202
this.objects.push( this.object );
164203

165204
},

0 commit comments

Comments
 (0)