buildMaterial method
Implementation
Future<Material?> buildMaterial(Map<String,dynamic> data ) async{
final effect = await getEffect( data['url'] );
final Map<String,dynamic> technique = effect['profile']['technique'];
Material? material;
switch ( technique['type'] ) {
case 'phong':
case 'blinn':
material = MeshPhongMaterial();
break;
case 'lambert':
material = MeshLambertMaterial();
break;
default:
material = MeshBasicMaterial();
break;
}
material.name = data['name'] ?? '';
Future<Texture?> getTexture( textureObject, [colorSpace]) async{
final sampler = effect['profile']['samplers'][ textureObject['id'] ];
var image;
// get image
if ( sampler != null ) {
final surface = effect['profile']['surfaces'][ sampler['source'] ];
image = await getImage( surface['init_from'] );
}
else {
console.warning( 'ColladaLoader: Undefined sampler. Access image directly (see #12530).' );
image = await getImage( textureObject['id'] );
}
// create texture if image is avaiable
if ( image != null ) {
final loader = getTextureLoader( image );
final Texture texture = (await loader.unknown( image ))!;
final extra = textureObject['extra'];
if ( extra != null && extra['technique'] != null && !isEmpty( extra['technique'] )) {
final technique = extra['technique'];
texture.wrapS = technique['wrapU'] ? RepeatWrapping : ClampToEdgeWrapping;
texture.wrapT = technique['wrapV'] ? RepeatWrapping : ClampToEdgeWrapping;
texture.offset.setValues( technique['offsetU'] ?? 0, technique['offsetV'] ?? 0 );
texture.repeat.setValues( technique['repeatU'] ?? 1, technique['repeatV'] ?? 1 );
}
else {
texture.wrapS = RepeatWrapping;
texture.wrapT = RepeatWrapping;
}
if ( colorSpace != null ) {
texture.colorSpace = colorSpace;
}
return texture;
}
else {
console.warning( 'ColladaLoader: Couldn\'t create texture with ID: ${textureObject['id']}');
return null;
}
}
final Map<String,dynamic> parameters = technique['parameters'];
for ( final key in parameters.keys ) {
final Map<String,dynamic> parameter = parameters[ key ];
switch ( key ) {
case 'diffuse':
if ( parameter['color'] != null ) material.color.copyFromArray( parameter['color'] );
if ( parameter['texture'] != null ) material.map = await getTexture( parameter['texture'], SRGBColorSpace );
break;
case 'specular':
if ( parameter['color'] != null && material.specular != null ) material.specular?.copyFromArray( parameter['color'] );
if ( parameter['texture'] != null) material.specularMap = await getTexture( parameter['texture'] );
break;
case 'bump':
if ( parameter['texture'] != null ) material.normalMap = await getTexture( parameter['texture'] );
break;
case 'ambient':
if ( parameter['texture'] != null ) material.lightMap = await getTexture( parameter['texture'], SRGBColorSpace );
break;
case 'shininess':
if ( parameter['float'] != null && material.shininess != null ) material.shininess = parameter['float'];
break;
case 'emission':
if ( parameter['color'] != null && material.emissive != null ) material.emissive?.copyFromArray( parameter['color'] );
if ( parameter['texture'] != null ) material.emissiveMap = await getTexture( parameter['texture'], SRGBColorSpace );
break;
}
}
material.color.convertSRGBToLinear();
if ( material.specular != null) material.specular?.convertSRGBToLinear();
if ( material.emissive != null) material.emissive?.convertSRGBToLinear();
Map<String,dynamic>? transparent = parameters[ 'transparent' ];
Map<String,dynamic>? transparency = parameters[ 'transparency' ];
// <transparency> does not exist but <transparent>
if ( transparency == null && transparent != null) {
transparency = {
'float': 1
};
}
// <transparent> does not exist but <transparency>
if ( transparent == null && transparency != null) {
transparent = {
'opaque': 'A_ONE',
'data': {
'color': [ 1, 1, 1, 1 ]
} };
}
if ( transparent != null && transparency != null) {
// handle case if a texture exists but no color
if ( transparent['data']?['texture'] != null) {
material.transparent = true;
}
else {
final List<double> color = transparent['data']['color'];
switch ( transparent['opaque'] ) {
case 'A_ONE':
material.opacity = color[ 3 ] * transparency['float'];
break;
case 'RGB_ZERO':
material.opacity = 1 - ( color[ 0 ] * transparency['float'] );
break;
case 'A_ZERO':
material.opacity = 1 - ( color[ 3 ] * transparency['float'] );
break;
case 'RGB_ONE':
material.opacity = color[ 0 ] * transparency['float'];
break;
default:
console.warning( 'ColladaLoader: Invalid opaque type "%s" of transparent tag. ${transparent['opaque']}');
}
if ( material.opacity < 1 ) material.transparent = true;
}
}
if ( technique['extra']?['technique'] != null ) {
final techniques = technique['extra']['technique'];
for ( final k in techniques ) {
final v = techniques[ k ];
switch ( k ) {
case 'double_sided':
material.side = ( v == 1 ? DoubleSide : FrontSide );
break;
case 'bump':
material.normalMap = await getTexture( v.texture );
material.normalScale = Vector2( 1, 1 );
break;
}
}
}
return material;
}