@babylonjs/loaders 9.27.1 → 9.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BVH/bvhLoader.js +1 -3
- package/BVH/bvhLoader.js.map +1 -1
- package/OBJ/mtlFileLoader.d.ts +8 -1
- package/OBJ/mtlFileLoader.js +55 -13
- package/OBJ/mtlFileLoader.js.map +1 -1
- package/OBJ/objFileLoader.pure.d.ts +5 -0
- package/OBJ/objFileLoader.pure.js +87 -65
- package/OBJ/objFileLoader.pure.js.map +1 -1
- package/OBJ/objLoadingOptions.d.ts +6 -0
- package/OBJ/objLoadingOptions.js.map +1 -1
- package/OBJ/solidParser.js +17 -6
- package/OBJ/solidParser.js.map +1 -1
- package/SPLAT/splatFileLoader.pure.js +86 -82
- package/SPLAT/splatFileLoader.pure.js.map +1 -1
- package/STL/stlFileLoader.pure.d.ts +1 -0
- package/STL/stlFileLoader.pure.js +18 -16
- package/STL/stlFileLoader.pure.js.map +1 -1
- package/glTF/1.0/glTFLoader.pure.js +30 -37
- package/glTF/1.0/glTFLoader.pure.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_lights_area.pure.js +16 -23
- package/glTF/2.0/Extensions/EXT_lights_area.pure.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_lights_ies.pure.js +1 -3
- package/glTF/2.0/Extensions/EXT_lights_ies.pure.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_gaussian_splatting.pure.js +1 -3
- package/glTF/2.0/Extensions/KHR_gaussian_splatting.pure.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphExporter.d.ts +7 -0
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphExporter.js +17 -3
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphExporter.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityNodeReference.d.ts +13 -0
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityNodeReference.js +16 -0
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityNodeReference.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_lights_punctual.pure.js +18 -25
- package/glTF/2.0/Extensions/KHR_lights_punctual.pure.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_node_hoverability.pure.js +3 -10
- package/glTF/2.0/Extensions/KHR_node_hoverability.pure.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_node_selectability.pure.js +2 -5
- package/glTF/2.0/Extensions/KHR_node_selectability.pure.js.map +1 -1
- package/glTF/2.0/glTFLoader.pure.js +15 -37
- package/glTF/2.0/glTFLoader.pure.js.map +1 -1
- package/package.json +3 -3
package/BVH/bvhLoader.js
CHANGED
|
@@ -260,10 +260,8 @@ function ReadNode(lines, firstLine, parent, context) {
|
|
|
260
260
|
export function ReadBvh(text, scene, assetContainer, loadingOptions) {
|
|
261
261
|
const lines = text.split("\n");
|
|
262
262
|
const { loopMode } = loadingOptions;
|
|
263
|
-
|
|
264
|
-
const skeleton = new Skeleton("", "", scene);
|
|
263
|
+
const skeleton = scene._executeWithBlockedEntityCollection(!!assetContainer, () => new Skeleton("", "", scene));
|
|
265
264
|
skeleton._parentContainer = assetContainer;
|
|
266
|
-
scene._blockEntityCollection = false;
|
|
267
265
|
const context = new LoaderContext(skeleton);
|
|
268
266
|
context.loopMode = loopMode;
|
|
269
267
|
// read model structure
|
package/BVH/bvhLoader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bvhLoader.js","sourceRoot":"","sources":["../../../../dev/loaders/src/BVH/bvhLoader.ts"],"names":[],"mappings":"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","sourcesContent":["import { type IAnimationKey } from \"core/Animations\";\nimport { Animation } from \"core/Animations/animation\";\nimport { Bone } from \"core/Bones/bone\";\nimport { Skeleton } from \"core/Bones/skeleton\";\nimport { Matrix, Quaternion, Vector3 } from \"core/Maths/math.vector\";\nimport { type Scene } from \"core/scene\";\nimport { type Nullable } from \"core/types\";\nimport { type BVHLoadingOptions } from \"./bvhLoadingOptions\";\nimport { Tools } from \"core/Misc/tools\";\nimport { type AssetContainer } from \"core/assetContainer\";\n\nconst _XPosition = \"Xposition\";\nconst _YPosition = \"Yposition\";\nconst _ZPosition = \"Zposition\";\nconst _XRotation = \"Xrotation\";\nconst _YRotation = \"Yrotation\";\nconst _ZRotation = \"Zrotation\";\n\nconst _HierarchyNode = \"HIERARCHY\";\nconst _MotionNode = \"MOTION\";\n\nclass LoaderContext {\n loopMode: number = Animation.ANIMATIONLOOPMODE_CYCLE;\n list: IBVHNode[] = [];\n root: IBVHNode = CreateBVHNode();\n numFrames: number = 0;\n frameRate: number = 0;\n skeleton: Skeleton;\n\n constructor(skeleton: Skeleton) {\n this.skeleton = skeleton;\n }\n}\n\ninterface IBVHNode {\n name: string;\n type: string;\n offset: Vector3;\n channels: string[];\n children: IBVHNode[];\n frames: IBVHKeyFrame[];\n parent: Nullable<IBVHNode>;\n}\n\ninterface IBVHKeyFrame {\n frame: number;\n position: Vector3;\n rotation: Quaternion;\n}\n\nfunction CreateBVHNode(): IBVHNode {\n return {\n name: \"\",\n type: \"\",\n offset: new Vector3(),\n channels: [],\n children: [],\n frames: [],\n parent: null,\n };\n}\n\nfunction CreateBVHKeyFrame(): IBVHKeyFrame {\n return {\n frame: 0,\n position: new Vector3(),\n rotation: new Quaternion(),\n };\n}\n\n/**\n * Converts the BVH node's offset to a Babylon matrix\n * @param node - The BVH node to convert\n * @returns The converted matrix\n */\nfunction BoneOffset(node: IBVHNode): Matrix {\n const x = node.offset.x;\n const y = node.offset.y;\n const z = node.offset.z;\n return Matrix.Translation(x, y, z);\n}\n\n/**\n * Creates animations for the BVH node\n * @param node - The BVH node to create animations for\n * @param context - The loader context\n * @returns The created animations\n */\nfunction CreateAnimations(node: IBVHNode, context: LoaderContext): Animation[] {\n if (node.frames.length === 0) {\n return [];\n }\n\n const animations: Animation[] = [];\n\n // Create position animation if there are position channels\n const hasPosition = node.channels.some((c) => c === _XPosition || c === _YPosition || c === _ZPosition);\n\n // Create rotation animation if there are rotation channels\n const hasRotation = node.channels.some((c) => c === _XRotation || c === _YRotation || c === _ZRotation);\n\n const posAnim = new Animation(`${node.name}_pos`, \"position\", context.frameRate, Animation.ANIMATIONTYPE_VECTOR3, context.loopMode);\n\n const rotAnim = new Animation(`${node.name}_rot`, \"rotationQuaternion\", context.frameRate, Animation.ANIMATIONTYPE_QUATERNION, context.loopMode);\n\n const posKeys: IAnimationKey[] = [];\n const rotKeys: IAnimationKey[] = [];\n\n for (let i = 0; i < node.frames.length; i++) {\n const frame = node.frames[i];\n\n if (hasPosition && frame.position) {\n posKeys.push({\n frame: frame.frame,\n value: frame.position.clone(),\n });\n }\n\n if (hasRotation) {\n rotKeys.push({\n frame: frame.frame,\n value: frame.rotation.clone(),\n });\n }\n }\n\n if (posKeys.length > 0) {\n posAnim.setKeys(posKeys);\n animations.push(posAnim);\n }\n\n if (rotKeys.length > 0) {\n rotAnim.setKeys(rotKeys);\n animations.push(rotAnim);\n }\n\n return animations;\n}\n\n/**\n * Converts a BVH node to a Babylon bone\n * @param node - The BVH node to convert\n * @param parent - The parent bone\n * @param context - The loader context\n */\nfunction ConvertNode(node: IBVHNode, parent: Nullable<Bone>, context: LoaderContext) {\n const matrix = BoneOffset(node);\n const bone = new Bone(node.name, context.skeleton, parent, matrix);\n\n // Create animation for this bone\n const animations = CreateAnimations(node, context);\n for (const animation of animations) {\n if (animation.getKeys() && animation.getKeys().length > 0) {\n bone.animations.push(animation);\n }\n }\n\n for (const child of node.children) {\n ConvertNode(child, bone, context);\n }\n}\n\n/**\n * Recursively reads data from a single frame into the bone hierarchy.\n * The bone hierarchy has to be structured in the same order as the BVH file.\n * keyframe data is stored in bone.frames.\n * @param data - splitted string array (frame values), values are shift()ed\n * @param frameNumber - playback time for this keyframe\n * @param bone - the bone to read frame data from\n * @param tokenIndex - the index of the token to read\n */\nfunction ReadFrameData(data: string[], frameNumber: number, bone: IBVHNode, tokenIndex: { i: number }) {\n if (bone.type === \"ENDSITE\") {\n // end sites have no motion data\n return;\n }\n\n // add keyframe\n const keyframe = CreateBVHKeyFrame();\n keyframe.frame = frameNumber;\n keyframe.position = new Vector3();\n keyframe.rotation = new Quaternion();\n\n bone.frames.push(keyframe);\n\n let combinedRotation = Matrix.Identity();\n\n // parse values for each channel in node\n for (let i = 0; i < bone.channels.length; ++i) {\n const channel = bone.channels[i];\n const value = data[tokenIndex.i++];\n if (!value) {\n continue;\n }\n const parsedValue = parseFloat(value.trim());\n if (channel.endsWith(\"position\")) {\n switch (channel) {\n case _XPosition:\n keyframe.position.x = parsedValue;\n break;\n case _YPosition:\n keyframe.position.y = parsedValue;\n break;\n case _ZPosition:\n keyframe.position.z = parsedValue;\n break;\n }\n } else if (channel.endsWith(\"rotation\")) {\n const angle = Tools.ToRadians(parsedValue);\n let rotationMatrix: Matrix;\n switch (channel) {\n case _XRotation:\n rotationMatrix = Matrix.RotationX(angle);\n break;\n case _YRotation:\n rotationMatrix = Matrix.RotationY(angle);\n break;\n case _ZRotation:\n rotationMatrix = Matrix.RotationZ(angle);\n break;\n }\n combinedRotation = rotationMatrix!.multiply(combinedRotation);\n }\n }\n\n Quaternion.FromRotationMatrixToRef(combinedRotation, keyframe.rotation);\n\n // parse child nodes\n for (const child of bone.children) {\n ReadFrameData(data, frameNumber, child, tokenIndex);\n }\n}\n\n/**\n * Recursively parses the HIERARCHY section of the BVH file\n * @param lines - all lines of the file. lines are consumed as we go along\n * @param firstLine - line containing the node type and name e.g. \"JOINT hip\"\n * @param parent - the parent node for hierarchy\n * @param context - the loader context containing the list of nodes and other data\n * @returns a BVH node including children\n */\nfunction ReadNode(lines: string[], firstLine: string, parent: Nullable<IBVHNode>, context: LoaderContext): IBVHNode {\n const node = CreateBVHNode();\n node.parent = parent;\n context.list.push(node);\n\n // parse node type and name.\n let tokens: string[] | undefined = firstLine.trim().split(/\\s+/);\n\n if (tokens[0].toUpperCase() === \"END\" && tokens[1].toUpperCase() === \"SITE\") {\n node.type = \"ENDSITE\";\n node.name = \"ENDSITE\"; // bvh end sites have no name\n } else {\n node.name = tokens[1];\n node.type = tokens[0].toUpperCase();\n }\n\n // opening bracket\n if (lines.shift()?.trim() != \"{\") {\n throw new Error(\"Expected opening { after type & name\");\n }\n\n // parse OFFSET\n const tokensSplit = lines.shift()?.trim().split(/\\s+/);\n if (!tokensSplit) {\n throw new Error(\"Unexpected end of file: missing OFFSET\");\n }\n tokens = tokensSplit;\n\n if (tokens[0].toUpperCase() != \"OFFSET\") {\n throw new Error(\"Expected OFFSET, but got: \" + tokens[0]);\n }\n if (tokens.length != 4) {\n throw new Error(\"OFFSET: Invalid number of values\");\n }\n\n const offset = new Vector3(parseFloat(tokens[1]), parseFloat(tokens[2]), parseFloat(tokens[3]));\n\n if (isNaN(offset.x) || isNaN(offset.y) || isNaN(offset.z)) {\n throw new Error(\"OFFSET: Invalid values\");\n }\n\n node.offset = offset;\n\n // parse CHANNELS definitions\n if (node.type != \"ENDSITE\") {\n tokens = lines.shift()?.trim().split(/\\s+/);\n if (!tokens) {\n throw new Error(\"Unexpected end of file: missing CHANNELS\");\n }\n\n if (tokens[0].toUpperCase() != \"CHANNELS\") {\n throw new Error(\"Expected CHANNELS definition\");\n }\n\n const numChannels = parseInt(tokens[1]);\n // Skip CHANNELS and the number of channels\n node.channels = tokens.splice(2, numChannels);\n node.children = [];\n }\n\n // read children\n while (lines.length > 0) {\n const line = lines.shift()?.trim();\n\n if (line === \"}\") {\n // Finish reading the node\n return node;\n } else if (line) {\n node.children.push(ReadNode(lines, line, node, context));\n }\n }\n\n throw new Error(\"Unexpected end of file: missing closing brace\");\n}\n\n/**\n * Reads a BVH file, returns a skeleton\n * @param text - The BVH file content\n * @param scene - The scene to add the skeleton to\n * @param assetContainer - The asset container to add the skeleton to\n * @param loadingOptions - The loading options\n * @returns The skeleton\n */\nexport function ReadBvh(text: string, scene: Scene, assetContainer: Nullable<AssetContainer>, loadingOptions: BVHLoadingOptions): Skeleton {\n const lines = text.split(\"\\n\");\n\n const { loopMode } = loadingOptions;\n\n scene._blockEntityCollection = !!assetContainer;\n const skeleton = new Skeleton(\"\", \"\", scene);\n skeleton._parentContainer = assetContainer;\n scene._blockEntityCollection = false;\n\n const context = new LoaderContext(skeleton);\n context.loopMode = loopMode;\n\n // read model structure\n const firstLine = lines.shift();\n if (!firstLine || firstLine.trim().toUpperCase() !== _HierarchyNode) {\n throw new Error(\"HIERARCHY expected\");\n }\n\n const nodeLine = lines.shift();\n if (!nodeLine) {\n throw new Error(\"Unexpected end of file after HIERARCHY\");\n }\n const root = ReadNode(lines, nodeLine.trim(), null, context);\n\n // read motion data\n const motionLine = lines.shift();\n if (!motionLine || motionLine.trim().toUpperCase() !== _MotionNode) {\n throw new Error(\"MOTION expected\");\n }\n\n const framesLine = lines.shift();\n if (!framesLine) {\n throw new Error(\"Unexpected end of file before frame count\");\n }\n const framesTokens = framesLine.trim().split(/[\\s]+/);\n if (framesTokens.length < 2) {\n throw new Error(\"Invalid frame count line\");\n }\n\n // number of frames\n const numFrames = parseInt(framesTokens[1]);\n if (isNaN(numFrames)) {\n throw new Error(\"Failed to read number of frames.\");\n }\n context.numFrames = numFrames;\n\n // frame time\n const frameTimeLine = lines.shift();\n if (!frameTimeLine) {\n throw new Error(\"Unexpected end of file before frame time\");\n }\n const frameTimeTokens = frameTimeLine.trim().split(/[\\s]+/);\n if (frameTimeTokens.length < 3) {\n throw new Error(\"Invalid frame time line\");\n }\n const frameTime = parseFloat(frameTimeTokens[2]);\n if (isNaN(frameTime)) {\n throw new Error(\"Failed to read frame time.\");\n }\n if (frameTime <= 0) {\n throw new Error(\"Failed to read frame time. Invalid value \" + frameTime);\n }\n\n context.frameRate = 1 / frameTime;\n\n // read frame data line by line\n for (let i = 0; i < numFrames; ++i) {\n const frameLine = lines.shift();\n if (!frameLine) {\n continue;\n }\n const tokens = frameLine.trim().split(/[\\s]+/) || [];\n ReadFrameData(tokens, i, root, { i: 0 });\n }\n\n context.root = root;\n\n ConvertNode(context.root, null, context);\n\n context.skeleton.returnToRest();\n return context.skeleton;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"bvhLoader.js","sourceRoot":"","sources":["../../../../dev/loaders/src/BVH/bvhLoader.ts"],"names":[],"mappings":"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","sourcesContent":["import { type IAnimationKey } from \"core/Animations\";\nimport { Animation } from \"core/Animations/animation\";\nimport { Bone } from \"core/Bones/bone\";\nimport { Skeleton } from \"core/Bones/skeleton\";\nimport { Matrix, Quaternion, Vector3 } from \"core/Maths/math.vector\";\nimport { type Scene } from \"core/scene\";\nimport { type Nullable } from \"core/types\";\nimport { type BVHLoadingOptions } from \"./bvhLoadingOptions\";\nimport { Tools } from \"core/Misc/tools\";\nimport { type AssetContainer } from \"core/assetContainer\";\n\nconst _XPosition = \"Xposition\";\nconst _YPosition = \"Yposition\";\nconst _ZPosition = \"Zposition\";\nconst _XRotation = \"Xrotation\";\nconst _YRotation = \"Yrotation\";\nconst _ZRotation = \"Zrotation\";\n\nconst _HierarchyNode = \"HIERARCHY\";\nconst _MotionNode = \"MOTION\";\n\nclass LoaderContext {\n loopMode: number = Animation.ANIMATIONLOOPMODE_CYCLE;\n list: IBVHNode[] = [];\n root: IBVHNode = CreateBVHNode();\n numFrames: number = 0;\n frameRate: number = 0;\n skeleton: Skeleton;\n\n constructor(skeleton: Skeleton) {\n this.skeleton = skeleton;\n }\n}\n\ninterface IBVHNode {\n name: string;\n type: string;\n offset: Vector3;\n channels: string[];\n children: IBVHNode[];\n frames: IBVHKeyFrame[];\n parent: Nullable<IBVHNode>;\n}\n\ninterface IBVHKeyFrame {\n frame: number;\n position: Vector3;\n rotation: Quaternion;\n}\n\nfunction CreateBVHNode(): IBVHNode {\n return {\n name: \"\",\n type: \"\",\n offset: new Vector3(),\n channels: [],\n children: [],\n frames: [],\n parent: null,\n };\n}\n\nfunction CreateBVHKeyFrame(): IBVHKeyFrame {\n return {\n frame: 0,\n position: new Vector3(),\n rotation: new Quaternion(),\n };\n}\n\n/**\n * Converts the BVH node's offset to a Babylon matrix\n * @param node - The BVH node to convert\n * @returns The converted matrix\n */\nfunction BoneOffset(node: IBVHNode): Matrix {\n const x = node.offset.x;\n const y = node.offset.y;\n const z = node.offset.z;\n return Matrix.Translation(x, y, z);\n}\n\n/**\n * Creates animations for the BVH node\n * @param node - The BVH node to create animations for\n * @param context - The loader context\n * @returns The created animations\n */\nfunction CreateAnimations(node: IBVHNode, context: LoaderContext): Animation[] {\n if (node.frames.length === 0) {\n return [];\n }\n\n const animations: Animation[] = [];\n\n // Create position animation if there are position channels\n const hasPosition = node.channels.some((c) => c === _XPosition || c === _YPosition || c === _ZPosition);\n\n // Create rotation animation if there are rotation channels\n const hasRotation = node.channels.some((c) => c === _XRotation || c === _YRotation || c === _ZRotation);\n\n const posAnim = new Animation(`${node.name}_pos`, \"position\", context.frameRate, Animation.ANIMATIONTYPE_VECTOR3, context.loopMode);\n\n const rotAnim = new Animation(`${node.name}_rot`, \"rotationQuaternion\", context.frameRate, Animation.ANIMATIONTYPE_QUATERNION, context.loopMode);\n\n const posKeys: IAnimationKey[] = [];\n const rotKeys: IAnimationKey[] = [];\n\n for (let i = 0; i < node.frames.length; i++) {\n const frame = node.frames[i];\n\n if (hasPosition && frame.position) {\n posKeys.push({\n frame: frame.frame,\n value: frame.position.clone(),\n });\n }\n\n if (hasRotation) {\n rotKeys.push({\n frame: frame.frame,\n value: frame.rotation.clone(),\n });\n }\n }\n\n if (posKeys.length > 0) {\n posAnim.setKeys(posKeys);\n animations.push(posAnim);\n }\n\n if (rotKeys.length > 0) {\n rotAnim.setKeys(rotKeys);\n animations.push(rotAnim);\n }\n\n return animations;\n}\n\n/**\n * Converts a BVH node to a Babylon bone\n * @param node - The BVH node to convert\n * @param parent - The parent bone\n * @param context - The loader context\n */\nfunction ConvertNode(node: IBVHNode, parent: Nullable<Bone>, context: LoaderContext) {\n const matrix = BoneOffset(node);\n const bone = new Bone(node.name, context.skeleton, parent, matrix);\n\n // Create animation for this bone\n const animations = CreateAnimations(node, context);\n for (const animation of animations) {\n if (animation.getKeys() && animation.getKeys().length > 0) {\n bone.animations.push(animation);\n }\n }\n\n for (const child of node.children) {\n ConvertNode(child, bone, context);\n }\n}\n\n/**\n * Recursively reads data from a single frame into the bone hierarchy.\n * The bone hierarchy has to be structured in the same order as the BVH file.\n * keyframe data is stored in bone.frames.\n * @param data - splitted string array (frame values), values are shift()ed\n * @param frameNumber - playback time for this keyframe\n * @param bone - the bone to read frame data from\n * @param tokenIndex - the index of the token to read\n */\nfunction ReadFrameData(data: string[], frameNumber: number, bone: IBVHNode, tokenIndex: { i: number }) {\n if (bone.type === \"ENDSITE\") {\n // end sites have no motion data\n return;\n }\n\n // add keyframe\n const keyframe = CreateBVHKeyFrame();\n keyframe.frame = frameNumber;\n keyframe.position = new Vector3();\n keyframe.rotation = new Quaternion();\n\n bone.frames.push(keyframe);\n\n let combinedRotation = Matrix.Identity();\n\n // parse values for each channel in node\n for (let i = 0; i < bone.channels.length; ++i) {\n const channel = bone.channels[i];\n const value = data[tokenIndex.i++];\n if (!value) {\n continue;\n }\n const parsedValue = parseFloat(value.trim());\n if (channel.endsWith(\"position\")) {\n switch (channel) {\n case _XPosition:\n keyframe.position.x = parsedValue;\n break;\n case _YPosition:\n keyframe.position.y = parsedValue;\n break;\n case _ZPosition:\n keyframe.position.z = parsedValue;\n break;\n }\n } else if (channel.endsWith(\"rotation\")) {\n const angle = Tools.ToRadians(parsedValue);\n let rotationMatrix: Matrix;\n switch (channel) {\n case _XRotation:\n rotationMatrix = Matrix.RotationX(angle);\n break;\n case _YRotation:\n rotationMatrix = Matrix.RotationY(angle);\n break;\n case _ZRotation:\n rotationMatrix = Matrix.RotationZ(angle);\n break;\n }\n combinedRotation = rotationMatrix!.multiply(combinedRotation);\n }\n }\n\n Quaternion.FromRotationMatrixToRef(combinedRotation, keyframe.rotation);\n\n // parse child nodes\n for (const child of bone.children) {\n ReadFrameData(data, frameNumber, child, tokenIndex);\n }\n}\n\n/**\n * Recursively parses the HIERARCHY section of the BVH file\n * @param lines - all lines of the file. lines are consumed as we go along\n * @param firstLine - line containing the node type and name e.g. \"JOINT hip\"\n * @param parent - the parent node for hierarchy\n * @param context - the loader context containing the list of nodes and other data\n * @returns a BVH node including children\n */\nfunction ReadNode(lines: string[], firstLine: string, parent: Nullable<IBVHNode>, context: LoaderContext): IBVHNode {\n const node = CreateBVHNode();\n node.parent = parent;\n context.list.push(node);\n\n // parse node type and name.\n let tokens: string[] | undefined = firstLine.trim().split(/\\s+/);\n\n if (tokens[0].toUpperCase() === \"END\" && tokens[1].toUpperCase() === \"SITE\") {\n node.type = \"ENDSITE\";\n node.name = \"ENDSITE\"; // bvh end sites have no name\n } else {\n node.name = tokens[1];\n node.type = tokens[0].toUpperCase();\n }\n\n // opening bracket\n if (lines.shift()?.trim() != \"{\") {\n throw new Error(\"Expected opening { after type & name\");\n }\n\n // parse OFFSET\n const tokensSplit = lines.shift()?.trim().split(/\\s+/);\n if (!tokensSplit) {\n throw new Error(\"Unexpected end of file: missing OFFSET\");\n }\n tokens = tokensSplit;\n\n if (tokens[0].toUpperCase() != \"OFFSET\") {\n throw new Error(\"Expected OFFSET, but got: \" + tokens[0]);\n }\n if (tokens.length != 4) {\n throw new Error(\"OFFSET: Invalid number of values\");\n }\n\n const offset = new Vector3(parseFloat(tokens[1]), parseFloat(tokens[2]), parseFloat(tokens[3]));\n\n if (isNaN(offset.x) || isNaN(offset.y) || isNaN(offset.z)) {\n throw new Error(\"OFFSET: Invalid values\");\n }\n\n node.offset = offset;\n\n // parse CHANNELS definitions\n if (node.type != \"ENDSITE\") {\n tokens = lines.shift()?.trim().split(/\\s+/);\n if (!tokens) {\n throw new Error(\"Unexpected end of file: missing CHANNELS\");\n }\n\n if (tokens[0].toUpperCase() != \"CHANNELS\") {\n throw new Error(\"Expected CHANNELS definition\");\n }\n\n const numChannels = parseInt(tokens[1]);\n // Skip CHANNELS and the number of channels\n node.channels = tokens.splice(2, numChannels);\n node.children = [];\n }\n\n // read children\n while (lines.length > 0) {\n const line = lines.shift()?.trim();\n\n if (line === \"}\") {\n // Finish reading the node\n return node;\n } else if (line) {\n node.children.push(ReadNode(lines, line, node, context));\n }\n }\n\n throw new Error(\"Unexpected end of file: missing closing brace\");\n}\n\n/**\n * Reads a BVH file, returns a skeleton\n * @param text - The BVH file content\n * @param scene - The scene to add the skeleton to\n * @param assetContainer - The asset container to add the skeleton to\n * @param loadingOptions - The loading options\n * @returns The skeleton\n */\nexport function ReadBvh(text: string, scene: Scene, assetContainer: Nullable<AssetContainer>, loadingOptions: BVHLoadingOptions): Skeleton {\n const lines = text.split(\"\\n\");\n\n const { loopMode } = loadingOptions;\n\n const skeleton = scene._executeWithBlockedEntityCollection(!!assetContainer, () => new Skeleton(\"\", \"\", scene));\n skeleton._parentContainer = assetContainer;\n\n const context = new LoaderContext(skeleton);\n context.loopMode = loopMode;\n\n // read model structure\n const firstLine = lines.shift();\n if (!firstLine || firstLine.trim().toUpperCase() !== _HierarchyNode) {\n throw new Error(\"HIERARCHY expected\");\n }\n\n const nodeLine = lines.shift();\n if (!nodeLine) {\n throw new Error(\"Unexpected end of file after HIERARCHY\");\n }\n const root = ReadNode(lines, nodeLine.trim(), null, context);\n\n // read motion data\n const motionLine = lines.shift();\n if (!motionLine || motionLine.trim().toUpperCase() !== _MotionNode) {\n throw new Error(\"MOTION expected\");\n }\n\n const framesLine = lines.shift();\n if (!framesLine) {\n throw new Error(\"Unexpected end of file before frame count\");\n }\n const framesTokens = framesLine.trim().split(/[\\s]+/);\n if (framesTokens.length < 2) {\n throw new Error(\"Invalid frame count line\");\n }\n\n // number of frames\n const numFrames = parseInt(framesTokens[1]);\n if (isNaN(numFrames)) {\n throw new Error(\"Failed to read number of frames.\");\n }\n context.numFrames = numFrames;\n\n // frame time\n const frameTimeLine = lines.shift();\n if (!frameTimeLine) {\n throw new Error(\"Unexpected end of file before frame time\");\n }\n const frameTimeTokens = frameTimeLine.trim().split(/[\\s]+/);\n if (frameTimeTokens.length < 3) {\n throw new Error(\"Invalid frame time line\");\n }\n const frameTime = parseFloat(frameTimeTokens[2]);\n if (isNaN(frameTime)) {\n throw new Error(\"Failed to read frame time.\");\n }\n if (frameTime <= 0) {\n throw new Error(\"Failed to read frame time. Invalid value \" + frameTime);\n }\n\n context.frameRate = 1 / frameTime;\n\n // read frame data line by line\n for (let i = 0; i < numFrames; ++i) {\n const frameLine = lines.shift();\n if (!frameLine) {\n continue;\n }\n const tokens = frameLine.trim().split(/[\\s]+/) || [];\n ReadFrameData(tokens, i, root, { i: 0 });\n }\n\n context.root = root;\n\n ConvertNode(context.root, null, context);\n\n context.skeleton.returnToRest();\n return context.skeleton;\n}\n"]}
|
package/OBJ/mtlFileLoader.d.ts
CHANGED
|
@@ -24,8 +24,12 @@ export declare class MTLFileLoader {
|
|
|
24
24
|
* @param data defines the mtl data to parse
|
|
25
25
|
* @param rootUrl defines the rooturl to use in order to load relative dependencies
|
|
26
26
|
* @param assetContainer defines the asset container to store the material in (can be null)
|
|
27
|
+
* @param invertTextureY defines whether referenced textures are inverted on the Y axis
|
|
28
|
+
* @param materialNames defines which materials to load, or all materials if omitted
|
|
29
|
+
* @param trackTextureLoading collects texture loading promises and starts delayed textures when true; defaults to false
|
|
30
|
+
* @returns the texture loading promises, or an empty array when trackTextureLoading is false
|
|
27
31
|
*/
|
|
28
|
-
parseMTL(scene: Scene, data: string | ArrayBuffer, rootUrl: string, assetContainer: Nullable<AssetContainer
|
|
32
|
+
parseMTL(scene: Scene, data: string | ArrayBuffer, rootUrl: string, assetContainer: Nullable<AssetContainer>, invertTextureY?: boolean, materialNames?: ReadonlySet<string>, trackTextureLoading?: boolean): Promise<void>[];
|
|
29
33
|
/**
|
|
30
34
|
* Gets the texture for the material.
|
|
31
35
|
*
|
|
@@ -35,6 +39,9 @@ export declare class MTLFileLoader {
|
|
|
35
39
|
* @param rootUrl The root url to load from
|
|
36
40
|
* @param value The value stored in the mtl
|
|
37
41
|
* @param scene
|
|
42
|
+
* @param assetContainer The asset container to store the texture in
|
|
43
|
+
* @param invertTextureY Whether to invert the texture on the Y axis
|
|
44
|
+
* @param textureLoadPromises The promises to wait for when loading asynchronously
|
|
38
45
|
* @returns The Texture
|
|
39
46
|
*/
|
|
40
47
|
private static _GetTexture;
|
package/OBJ/mtlFileLoader.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Color3 } from "@babylonjs/core/Maths/math.color.js";
|
|
2
2
|
import { Texture } from "@babylonjs/core/Materials/Textures/texture.js";
|
|
3
3
|
import { StandardMaterial } from "@babylonjs/core/Materials/standardMaterial.js";
|
|
4
|
+
import { Constants } from "@babylonjs/core/Engines/constants.js";
|
|
5
|
+
import { Deferred } from "@babylonjs/core/Misc/deferred.js";
|
|
4
6
|
/**
|
|
5
7
|
* Class reading and parsing the MTL file bundled with the obj file.
|
|
6
8
|
*/
|
|
@@ -21,10 +23,15 @@ export class MTLFileLoader {
|
|
|
21
23
|
* @param data defines the mtl data to parse
|
|
22
24
|
* @param rootUrl defines the rooturl to use in order to load relative dependencies
|
|
23
25
|
* @param assetContainer defines the asset container to store the material in (can be null)
|
|
26
|
+
* @param invertTextureY defines whether referenced textures are inverted on the Y axis
|
|
27
|
+
* @param materialNames defines which materials to load, or all materials if omitted
|
|
28
|
+
* @param trackTextureLoading collects texture loading promises and starts delayed textures when true; defaults to false
|
|
29
|
+
* @returns the texture loading promises, or an empty array when trackTextureLoading is false
|
|
24
30
|
*/
|
|
25
|
-
parseMTL(scene, data, rootUrl, assetContainer) {
|
|
31
|
+
parseMTL(scene, data, rootUrl, assetContainer, invertTextureY = MTLFileLoader.INVERT_TEXTURE_Y, materialNames, trackTextureLoading = false) {
|
|
32
|
+
const textureLoadPromises = trackTextureLoading ? [] : null;
|
|
26
33
|
if (data instanceof ArrayBuffer) {
|
|
27
|
-
return;
|
|
34
|
+
return textureLoadPromises ?? [];
|
|
28
35
|
}
|
|
29
36
|
//Split the lines from the file
|
|
30
37
|
const lines = data.split("\n");
|
|
@@ -55,12 +62,18 @@ export class MTLFileLoader {
|
|
|
55
62
|
//Add the previous material in the material array.
|
|
56
63
|
this.materials.push(material);
|
|
57
64
|
}
|
|
65
|
+
if (materialNames && !materialNames.has(value)) {
|
|
66
|
+
material = null;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
58
69
|
//Create a new material.
|
|
59
70
|
// value is the name of the material read in the mtl file
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
71
|
+
material = scene._executeWithBlockedEntityCollection(!!assetContainer, () => {
|
|
72
|
+
material = new StandardMaterial(value, scene);
|
|
73
|
+
material._parentContainer = assetContainer;
|
|
74
|
+
assetContainer?.materials.push(material);
|
|
75
|
+
return material;
|
|
76
|
+
});
|
|
64
77
|
}
|
|
65
78
|
else if (key === "kd" && material) {
|
|
66
79
|
// Diffuse color (color under white light) using RGB values
|
|
@@ -104,16 +117,16 @@ export class MTLFileLoader {
|
|
|
104
117
|
else if (key === "map_ka" && material) {
|
|
105
118
|
// ambient texture map with a loaded image
|
|
106
119
|
//We must first get the folder of the image
|
|
107
|
-
material.ambientTexture = MTLFileLoader._GetTexture(rootUrl, value, scene);
|
|
120
|
+
material.ambientTexture = MTLFileLoader._GetTexture(rootUrl, value, scene, assetContainer, invertTextureY, textureLoadPromises);
|
|
108
121
|
}
|
|
109
122
|
else if (key === "map_kd" && material) {
|
|
110
123
|
// Diffuse texture map with a loaded image
|
|
111
|
-
material.diffuseTexture = MTLFileLoader._GetTexture(rootUrl, value, scene);
|
|
124
|
+
material.diffuseTexture = MTLFileLoader._GetTexture(rootUrl, value, scene, assetContainer, invertTextureY, textureLoadPromises);
|
|
112
125
|
}
|
|
113
126
|
else if (key === "map_ks" && material) {
|
|
114
127
|
// Specular texture map with a loaded image
|
|
115
128
|
//We must first get the folder of the image
|
|
116
|
-
material.specularTexture = MTLFileLoader._GetTexture(rootUrl, value, scene);
|
|
129
|
+
material.specularTexture = MTLFileLoader._GetTexture(rootUrl, value, scene, assetContainer, invertTextureY, textureLoadPromises);
|
|
117
130
|
}
|
|
118
131
|
else if (key === "map_ns") {
|
|
119
132
|
//Specular
|
|
@@ -133,14 +146,14 @@ export class MTLFileLoader {
|
|
|
133
146
|
bumpMultiplier = values[bumpMultiplierIndex + 1];
|
|
134
147
|
values.splice(bumpMultiplierIndex, 2); // remove
|
|
135
148
|
}
|
|
136
|
-
material.bumpTexture = MTLFileLoader._GetTexture(rootUrl, values.join(" "), scene);
|
|
149
|
+
material.bumpTexture = MTLFileLoader._GetTexture(rootUrl, values.join(" "), scene, assetContainer, invertTextureY, textureLoadPromises);
|
|
137
150
|
if (material.bumpTexture && bumpMultiplier !== null) {
|
|
138
151
|
material.bumpTexture.level = parseFloat(bumpMultiplier);
|
|
139
152
|
}
|
|
140
153
|
}
|
|
141
154
|
else if (key === "map_d" && material) {
|
|
142
155
|
// The dissolve of the material
|
|
143
|
-
material.opacityTexture = MTLFileLoader._GetTexture(rootUrl, value, scene);
|
|
156
|
+
material.opacityTexture = MTLFileLoader._GetTexture(rootUrl, value, scene, assetContainer, invertTextureY, textureLoadPromises);
|
|
144
157
|
//Options for illumination
|
|
145
158
|
}
|
|
146
159
|
else if (key === "illum") {
|
|
@@ -187,6 +200,7 @@ export class MTLFileLoader {
|
|
|
187
200
|
if (material) {
|
|
188
201
|
this.materials.push(material);
|
|
189
202
|
}
|
|
203
|
+
return textureLoadPromises ?? [];
|
|
190
204
|
}
|
|
191
205
|
/**
|
|
192
206
|
* Gets the texture for the material.
|
|
@@ -197,9 +211,12 @@ export class MTLFileLoader {
|
|
|
197
211
|
* @param rootUrl The root url to load from
|
|
198
212
|
* @param value The value stored in the mtl
|
|
199
213
|
* @param scene
|
|
214
|
+
* @param assetContainer The asset container to store the texture in
|
|
215
|
+
* @param invertTextureY Whether to invert the texture on the Y axis
|
|
216
|
+
* @param textureLoadPromises The promises to wait for when loading asynchronously
|
|
200
217
|
* @returns The Texture
|
|
201
218
|
*/
|
|
202
|
-
static _GetTexture(rootUrl, value, scene) {
|
|
219
|
+
static _GetTexture(rootUrl, value, scene, assetContainer, invertTextureY, textureLoadPromises) {
|
|
203
220
|
if (!value) {
|
|
204
221
|
return null;
|
|
205
222
|
}
|
|
@@ -221,7 +238,32 @@ export class MTLFileLoader {
|
|
|
221
238
|
else {
|
|
222
239
|
url += value;
|
|
223
240
|
}
|
|
224
|
-
|
|
241
|
+
const deferred = textureLoadPromises ? new Deferred() : null;
|
|
242
|
+
if (deferred) {
|
|
243
|
+
// Parsing may throw before returning the array. Observe rejection without changing the original promise returned to the caller.
|
|
244
|
+
// eslint-disable-next-line github/no-then
|
|
245
|
+
void deferred.promise.catch(() => undefined);
|
|
246
|
+
textureLoadPromises.push(deferred.promise);
|
|
247
|
+
}
|
|
248
|
+
const texture = scene._executeWithBlockedEntityCollection(!!assetContainer, () => {
|
|
249
|
+
const result = new Texture(url, scene, {
|
|
250
|
+
invertY: invertTextureY,
|
|
251
|
+
onLoad: deferred?.resolve,
|
|
252
|
+
onError: (message, exception) => {
|
|
253
|
+
if (deferred) {
|
|
254
|
+
deferred.reject(new Error(`${url}: ${exception?.message || message || "Failed to load texture"}`));
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
result._parentContainer = assetContainer;
|
|
259
|
+
assetContainer?.textures.push(result);
|
|
260
|
+
return result;
|
|
261
|
+
});
|
|
262
|
+
// A container is not rendered yet, so delayed loading cannot wait for a material bind.
|
|
263
|
+
if (deferred && texture.delayLoadState === Constants.DELAYLOADSTATE_NOTLOADED) {
|
|
264
|
+
texture.delayLoad();
|
|
265
|
+
}
|
|
266
|
+
return texture;
|
|
225
267
|
}
|
|
226
268
|
}
|
|
227
269
|
/**
|
package/OBJ/mtlFileLoader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mtlFileLoader.js","sourceRoot":"","sources":["../../../../dev/loaders/src/OBJ/mtlFileLoader.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Nullable } from \"core/types\";\r\nimport { Color3 } from \"core/Maths/math.color\";\r\nimport { Texture } from \"core/Materials/Textures/texture\";\r\nimport { StandardMaterial } from \"core/Materials/standardMaterial\";\r\n\r\nimport { type Scene } from \"core/scene\";\r\nimport { type AssetContainer } from \"core/assetContainer\";\r\n/**\r\n * Class reading and parsing the MTL file bundled with the obj file.\r\n */\r\nexport class MTLFileLoader {\r\n /**\r\n * Invert Y-Axis of referenced textures on load\r\n */\r\n public static INVERT_TEXTURE_Y = true;\r\n\r\n /**\r\n * All material loaded from the mtl will be set here\r\n */\r\n public materials: StandardMaterial[] = [];\r\n\r\n /**\r\n * This function will read the mtl file and create each material described inside\r\n * This function could be improve by adding :\r\n * -some component missing (Ni, Tf...)\r\n * -including the specific options available\r\n *\r\n * @param scene defines the scene the material will be created in\r\n * @param data defines the mtl data to parse\r\n * @param rootUrl defines the rooturl to use in order to load relative dependencies\r\n * @param assetContainer defines the asset container to store the material in (can be null)\r\n */\r\n public parseMTL(scene: Scene, data: string | ArrayBuffer, rootUrl: string, assetContainer: Nullable<AssetContainer>): void {\r\n if (data instanceof ArrayBuffer) {\r\n return;\r\n }\r\n\r\n //Split the lines from the file\r\n const lines = data.split(\"\\n\");\r\n // whitespace char ie: [ \\t\\r\\n\\f]\r\n const delimiterPattern = /\\s+/;\r\n //Array with RGB colors\r\n let color: number[];\r\n //New material\r\n let material: Nullable<StandardMaterial> = null;\r\n\r\n //Look at each line\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i].trim();\r\n\r\n // Blank line or comment\r\n if (line.length === 0 || line.charAt(0) === \"#\") {\r\n continue;\r\n }\r\n\r\n //Get the first parameter (keyword)\r\n const pos = line.indexOf(\" \");\r\n let key = pos >= 0 ? line.substring(0, pos) : line;\r\n key = key.toLowerCase();\r\n\r\n //Get the data following the key\r\n const value: string = pos >= 0 ? line.substring(pos + 1).trim() : \"\";\r\n\r\n //This mtl keyword will create the new material\r\n if (key === \"newmtl\") {\r\n //Check if it is the first material.\r\n // Materials specifications are described after this keyword.\r\n if (material) {\r\n //Add the previous material in the material array.\r\n this.materials.push(material);\r\n }\r\n //Create a new material.\r\n // value is the name of the material read in the mtl file\r\n\r\n scene._blockEntityCollection = !!assetContainer;\r\n material = new StandardMaterial(value, scene);\r\n material._parentContainer = assetContainer;\r\n scene._blockEntityCollection = false;\r\n } else if (key === \"kd\" && material) {\r\n // Diffuse color (color under white light) using RGB values\r\n\r\n //value = \"r g b\"\r\n color = value.split(delimiterPattern, 3).map(parseFloat);\r\n //color = [r,g,b]\r\n //Set tghe color into the material\r\n material.diffuseColor = Color3.FromArray(color);\r\n } else if (key === \"ka\" && material) {\r\n // Ambient color (color under shadow) using RGB values\r\n\r\n //value = \"r g b\"\r\n color = value.split(delimiterPattern, 3).map(parseFloat);\r\n //color = [r,g,b]\r\n //Set tghe color into the material\r\n material.ambientColor = Color3.FromArray(color);\r\n } else if (key === \"ks\" && material) {\r\n // Specular color (color when light is reflected from shiny surface) using RGB values\r\n\r\n //value = \"r g b\"\r\n color = value.split(delimiterPattern, 3).map(parseFloat);\r\n //color = [r,g,b]\r\n //Set the color into the material\r\n material.specularColor = Color3.FromArray(color);\r\n } else if (key === \"ke\" && material) {\r\n // Emissive color using RGB values\r\n color = value.split(delimiterPattern, 3).map(parseFloat);\r\n material.emissiveColor = Color3.FromArray(color);\r\n } else if (key === \"ns\" && material) {\r\n //value = \"Integer\"\r\n material.specularPower = parseFloat(value);\r\n } else if (key === \"d\" && material) {\r\n //d is dissolve for current material. It mean alpha for BABYLON\r\n material.alpha = parseFloat(value);\r\n\r\n //Texture\r\n //This part can be improved by adding the possible options of texture\r\n } else if (key === \"map_ka\" && material) {\r\n // ambient texture map with a loaded image\r\n //We must first get the folder of the image\r\n material.ambientTexture = MTLFileLoader._GetTexture(rootUrl, value, scene);\r\n } else if (key === \"map_kd\" && material) {\r\n // Diffuse texture map with a loaded image\r\n material.diffuseTexture = MTLFileLoader._GetTexture(rootUrl, value, scene);\r\n } else if (key === \"map_ks\" && material) {\r\n // Specular texture map with a loaded image\r\n //We must first get the folder of the image\r\n material.specularTexture = MTLFileLoader._GetTexture(rootUrl, value, scene);\r\n } else if (key === \"map_ns\") {\r\n //Specular\r\n //Specular highlight component\r\n //We must first get the folder of the image\r\n //\r\n //Not supported by BABYLON\r\n //\r\n // continue;\r\n } else if (key === \"map_bump\" && material) {\r\n //The bump texture\r\n const values = value.split(delimiterPattern);\r\n const bumpMultiplierIndex = values.indexOf(\"-bm\");\r\n let bumpMultiplier: Nullable<string> = null;\r\n\r\n if (bumpMultiplierIndex >= 0) {\r\n bumpMultiplier = values[bumpMultiplierIndex + 1];\r\n values.splice(bumpMultiplierIndex, 2); // remove\r\n }\r\n\r\n material.bumpTexture = MTLFileLoader._GetTexture(rootUrl, values.join(\" \"), scene);\r\n if (material.bumpTexture && bumpMultiplier !== null) {\r\n material.bumpTexture.level = parseFloat(bumpMultiplier);\r\n }\r\n } else if (key === \"map_d\" && material) {\r\n // The dissolve of the material\r\n material.opacityTexture = MTLFileLoader._GetTexture(rootUrl, value, scene);\r\n\r\n //Options for illumination\r\n } else if (key === \"illum\") {\r\n //Illumination\r\n if (value === \"0\") {\r\n //That mean Kd == Kd\r\n } else if (value === \"1\") {\r\n //Color on and Ambient on\r\n } else if (value === \"2\") {\r\n //Highlight on\r\n } else if (value === \"3\") {\r\n //Reflection on and Ray trace on\r\n } else if (value === \"4\") {\r\n //Transparency: Glass on, Reflection: Ray trace on\r\n } else if (value === \"5\") {\r\n //Reflection: Fresnel on and Ray trace on\r\n } else if (value === \"6\") {\r\n //Transparency: Refraction on, Reflection: Fresnel off and Ray trace on\r\n } else if (value === \"7\") {\r\n //Transparency: Refraction on, Reflection: Fresnel on and Ray trace on\r\n } else if (value === \"8\") {\r\n //Reflection on and Ray trace off\r\n } else if (value === \"9\") {\r\n //Transparency: Glass on, Reflection: Ray trace off\r\n } else if (value === \"10\") {\r\n //Casts shadows onto invisible surfaces\r\n }\r\n } else {\r\n // console.log(\"Unhandled expression at line : \" + i +'\\n' + \"with value : \" + line);\r\n }\r\n }\r\n //At the end of the file, add the last material\r\n if (material) {\r\n this.materials.push(material);\r\n }\r\n }\r\n\r\n /**\r\n * Gets the texture for the material.\r\n *\r\n * If the material is imported from input file,\r\n * We sanitize the url to ensure it takes the texture from aside the material.\r\n *\r\n * @param rootUrl The root url to load from\r\n * @param value The value stored in the mtl\r\n * @param scene\r\n * @returns The Texture\r\n */\r\n private static _GetTexture(rootUrl: string, value: string, scene: Scene): Nullable<Texture> {\r\n if (!value) {\r\n return null;\r\n }\r\n\r\n let url = rootUrl;\r\n // Load from input file.\r\n if (rootUrl === \"file:\") {\r\n let lastDelimiter = value.lastIndexOf(\"\\\\\");\r\n if (lastDelimiter === -1) {\r\n lastDelimiter = value.lastIndexOf(\"/\");\r\n }\r\n\r\n if (lastDelimiter > -1) {\r\n url += value.substring(lastDelimiter + 1);\r\n } else {\r\n url += value;\r\n }\r\n }\r\n // Not from input file.\r\n else {\r\n url += value;\r\n }\r\n\r\n return new Texture(url, scene, false, MTLFileLoader.INVERT_TEXTURE_Y);\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"mtlFileLoader.js","sourceRoot":"","sources":["../../../../dev/loaders/src/OBJ/mtlFileLoader.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Nullable } from \"core/types\";\r\nimport { Color3 } from \"core/Maths/math.color\";\r\nimport { Texture } from \"core/Materials/Textures/texture\";\r\nimport { StandardMaterial } from \"core/Materials/standardMaterial\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { Deferred } from \"core/Misc/deferred\";\r\n\r\nimport { type Scene } from \"core/scene\";\r\nimport { type AssetContainer } from \"core/assetContainer\";\r\n/**\r\n * Class reading and parsing the MTL file bundled with the obj file.\r\n */\r\nexport class MTLFileLoader {\r\n /**\r\n * Invert Y-Axis of referenced textures on load\r\n */\r\n public static INVERT_TEXTURE_Y = true;\r\n\r\n /**\r\n * All material loaded from the mtl will be set here\r\n */\r\n public materials: StandardMaterial[] = [];\r\n\r\n /**\r\n * This function will read the mtl file and create each material described inside\r\n * This function could be improve by adding :\r\n * -some component missing (Ni, Tf...)\r\n * -including the specific options available\r\n *\r\n * @param scene defines the scene the material will be created in\r\n * @param data defines the mtl data to parse\r\n * @param rootUrl defines the rooturl to use in order to load relative dependencies\r\n * @param assetContainer defines the asset container to store the material in (can be null)\r\n * @param invertTextureY defines whether referenced textures are inverted on the Y axis\r\n * @param materialNames defines which materials to load, or all materials if omitted\r\n * @param trackTextureLoading collects texture loading promises and starts delayed textures when true; defaults to false\r\n * @returns the texture loading promises, or an empty array when trackTextureLoading is false\r\n */\r\n public parseMTL(\r\n scene: Scene,\r\n data: string | ArrayBuffer,\r\n rootUrl: string,\r\n assetContainer: Nullable<AssetContainer>,\r\n invertTextureY = MTLFileLoader.INVERT_TEXTURE_Y,\r\n materialNames?: ReadonlySet<string>,\r\n trackTextureLoading = false\r\n ): Promise<void>[] {\r\n const textureLoadPromises: Nullable<Promise<void>[]> = trackTextureLoading ? [] : null;\r\n if (data instanceof ArrayBuffer) {\r\n return textureLoadPromises ?? [];\r\n }\r\n\r\n //Split the lines from the file\r\n const lines = data.split(\"\\n\");\r\n // whitespace char ie: [ \\t\\r\\n\\f]\r\n const delimiterPattern = /\\s+/;\r\n //Array with RGB colors\r\n let color: number[];\r\n //New material\r\n let material: Nullable<StandardMaterial> = null;\r\n\r\n //Look at each line\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i].trim();\r\n\r\n // Blank line or comment\r\n if (line.length === 0 || line.charAt(0) === \"#\") {\r\n continue;\r\n }\r\n\r\n //Get the first parameter (keyword)\r\n const pos = line.indexOf(\" \");\r\n let key = pos >= 0 ? line.substring(0, pos) : line;\r\n key = key.toLowerCase();\r\n\r\n //Get the data following the key\r\n const value: string = pos >= 0 ? line.substring(pos + 1).trim() : \"\";\r\n\r\n //This mtl keyword will create the new material\r\n if (key === \"newmtl\") {\r\n //Check if it is the first material.\r\n // Materials specifications are described after this keyword.\r\n if (material) {\r\n //Add the previous material in the material array.\r\n this.materials.push(material);\r\n }\r\n if (materialNames && !materialNames.has(value)) {\r\n material = null;\r\n continue;\r\n }\r\n //Create a new material.\r\n // value is the name of the material read in the mtl file\r\n\r\n material = scene._executeWithBlockedEntityCollection(!!assetContainer, () => {\r\n material = new StandardMaterial(value, scene);\r\n material._parentContainer = assetContainer;\r\n assetContainer?.materials.push(material);\r\n return material;\r\n });\r\n } else if (key === \"kd\" && material) {\r\n // Diffuse color (color under white light) using RGB values\r\n\r\n //value = \"r g b\"\r\n color = value.split(delimiterPattern, 3).map(parseFloat);\r\n //color = [r,g,b]\r\n //Set tghe color into the material\r\n material.diffuseColor = Color3.FromArray(color);\r\n } else if (key === \"ka\" && material) {\r\n // Ambient color (color under shadow) using RGB values\r\n\r\n //value = \"r g b\"\r\n color = value.split(delimiterPattern, 3).map(parseFloat);\r\n //color = [r,g,b]\r\n //Set tghe color into the material\r\n material.ambientColor = Color3.FromArray(color);\r\n } else if (key === \"ks\" && material) {\r\n // Specular color (color when light is reflected from shiny surface) using RGB values\r\n\r\n //value = \"r g b\"\r\n color = value.split(delimiterPattern, 3).map(parseFloat);\r\n //color = [r,g,b]\r\n //Set the color into the material\r\n material.specularColor = Color3.FromArray(color);\r\n } else if (key === \"ke\" && material) {\r\n // Emissive color using RGB values\r\n color = value.split(delimiterPattern, 3).map(parseFloat);\r\n material.emissiveColor = Color3.FromArray(color);\r\n } else if (key === \"ns\" && material) {\r\n //value = \"Integer\"\r\n material.specularPower = parseFloat(value);\r\n } else if (key === \"d\" && material) {\r\n //d is dissolve for current material. It mean alpha for BABYLON\r\n material.alpha = parseFloat(value);\r\n\r\n //Texture\r\n //This part can be improved by adding the possible options of texture\r\n } else if (key === \"map_ka\" && material) {\r\n // ambient texture map with a loaded image\r\n //We must first get the folder of the image\r\n material.ambientTexture = MTLFileLoader._GetTexture(rootUrl, value, scene, assetContainer, invertTextureY, textureLoadPromises);\r\n } else if (key === \"map_kd\" && material) {\r\n // Diffuse texture map with a loaded image\r\n material.diffuseTexture = MTLFileLoader._GetTexture(rootUrl, value, scene, assetContainer, invertTextureY, textureLoadPromises);\r\n } else if (key === \"map_ks\" && material) {\r\n // Specular texture map with a loaded image\r\n //We must first get the folder of the image\r\n material.specularTexture = MTLFileLoader._GetTexture(rootUrl, value, scene, assetContainer, invertTextureY, textureLoadPromises);\r\n } else if (key === \"map_ns\") {\r\n //Specular\r\n //Specular highlight component\r\n //We must first get the folder of the image\r\n //\r\n //Not supported by BABYLON\r\n //\r\n // continue;\r\n } else if (key === \"map_bump\" && material) {\r\n //The bump texture\r\n const values = value.split(delimiterPattern);\r\n const bumpMultiplierIndex = values.indexOf(\"-bm\");\r\n let bumpMultiplier: Nullable<string> = null;\r\n\r\n if (bumpMultiplierIndex >= 0) {\r\n bumpMultiplier = values[bumpMultiplierIndex + 1];\r\n values.splice(bumpMultiplierIndex, 2); // remove\r\n }\r\n\r\n material.bumpTexture = MTLFileLoader._GetTexture(rootUrl, values.join(\" \"), scene, assetContainer, invertTextureY, textureLoadPromises);\r\n if (material.bumpTexture && bumpMultiplier !== null) {\r\n material.bumpTexture.level = parseFloat(bumpMultiplier);\r\n }\r\n } else if (key === \"map_d\" && material) {\r\n // The dissolve of the material\r\n material.opacityTexture = MTLFileLoader._GetTexture(rootUrl, value, scene, assetContainer, invertTextureY, textureLoadPromises);\r\n\r\n //Options for illumination\r\n } else if (key === \"illum\") {\r\n //Illumination\r\n if (value === \"0\") {\r\n //That mean Kd == Kd\r\n } else if (value === \"1\") {\r\n //Color on and Ambient on\r\n } else if (value === \"2\") {\r\n //Highlight on\r\n } else if (value === \"3\") {\r\n //Reflection on and Ray trace on\r\n } else if (value === \"4\") {\r\n //Transparency: Glass on, Reflection: Ray trace on\r\n } else if (value === \"5\") {\r\n //Reflection: Fresnel on and Ray trace on\r\n } else if (value === \"6\") {\r\n //Transparency: Refraction on, Reflection: Fresnel off and Ray trace on\r\n } else if (value === \"7\") {\r\n //Transparency: Refraction on, Reflection: Fresnel on and Ray trace on\r\n } else if (value === \"8\") {\r\n //Reflection on and Ray trace off\r\n } else if (value === \"9\") {\r\n //Transparency: Glass on, Reflection: Ray trace off\r\n } else if (value === \"10\") {\r\n //Casts shadows onto invisible surfaces\r\n }\r\n } else {\r\n // console.log(\"Unhandled expression at line : \" + i +'\\n' + \"with value : \" + line);\r\n }\r\n }\r\n //At the end of the file, add the last material\r\n if (material) {\r\n this.materials.push(material);\r\n }\r\n\r\n return textureLoadPromises ?? [];\r\n }\r\n\r\n /**\r\n * Gets the texture for the material.\r\n *\r\n * If the material is imported from input file,\r\n * We sanitize the url to ensure it takes the texture from aside the material.\r\n *\r\n * @param rootUrl The root url to load from\r\n * @param value The value stored in the mtl\r\n * @param scene\r\n * @param assetContainer The asset container to store the texture in\r\n * @param invertTextureY Whether to invert the texture on the Y axis\r\n * @param textureLoadPromises The promises to wait for when loading asynchronously\r\n * @returns The Texture\r\n */\r\n private static _GetTexture(\r\n rootUrl: string,\r\n value: string,\r\n scene: Scene,\r\n assetContainer: Nullable<AssetContainer>,\r\n invertTextureY: boolean,\r\n textureLoadPromises?: Nullable<Promise<void>[]>\r\n ): Nullable<Texture> {\r\n if (!value) {\r\n return null;\r\n }\r\n\r\n let url = rootUrl;\r\n // Load from input file.\r\n if (rootUrl === \"file:\") {\r\n let lastDelimiter = value.lastIndexOf(\"\\\\\");\r\n if (lastDelimiter === -1) {\r\n lastDelimiter = value.lastIndexOf(\"/\");\r\n }\r\n\r\n if (lastDelimiter > -1) {\r\n url += value.substring(lastDelimiter + 1);\r\n } else {\r\n url += value;\r\n }\r\n }\r\n // Not from input file.\r\n else {\r\n url += value;\r\n }\r\n\r\n const deferred = textureLoadPromises ? new Deferred<void>() : null;\r\n if (deferred) {\r\n // Parsing may throw before returning the array. Observe rejection without changing the original promise returned to the caller.\r\n // eslint-disable-next-line github/no-then\r\n void deferred.promise.catch(() => undefined);\r\n textureLoadPromises!.push(deferred.promise);\r\n }\r\n\r\n const texture = scene._executeWithBlockedEntityCollection(!!assetContainer, () => {\r\n const result = new Texture(url, scene, {\r\n invertY: invertTextureY,\r\n onLoad: deferred?.resolve,\r\n onError: (message, exception) => {\r\n if (deferred) {\r\n deferred.reject(new Error(`${url}: ${exception?.message || message || \"Failed to load texture\"}`));\r\n }\r\n },\r\n });\r\n result._parentContainer = assetContainer;\r\n assetContainer?.textures.push(result);\r\n return result;\r\n });\r\n\r\n // A container is not rendered yet, so delayed loading cannot wait for a material bind.\r\n if (deferred && texture.delayLoadState === Constants.DELAYLOADSTATE_NOTLOADED) {\r\n texture.delayLoad();\r\n }\r\n return texture;\r\n }\r\n}\r\n"]}
|
|
@@ -25,6 +25,11 @@ export declare class OBJFileLoader implements ISceneLoaderPluginAsync, ISceneLoa
|
|
|
25
25
|
*/
|
|
26
26
|
static get INVERT_TEXTURE_Y(): boolean;
|
|
27
27
|
static set INVERT_TEXTURE_Y(value: boolean);
|
|
28
|
+
/**
|
|
29
|
+
* Wait for referenced textures to finish loading before completing the OBJ load.
|
|
30
|
+
* Defaults to false for backwards compatibility.
|
|
31
|
+
*/
|
|
32
|
+
static WAIT_FOR_TEXTURES: boolean;
|
|
28
33
|
/**
|
|
29
34
|
* Include in meshes the vertex colors available in some OBJ files. This is not part of OBJ standard.
|
|
30
35
|
*/
|
|
@@ -45,6 +45,7 @@ export class OBJFileLoader {
|
|
|
45
45
|
importVertexColors: OBJFileLoader.IMPORT_VERTEX_COLORS,
|
|
46
46
|
invertY: OBJFileLoader.INVERT_Y,
|
|
47
47
|
invertTextureY: OBJFileLoader.INVERT_TEXTURE_Y,
|
|
48
|
+
waitForTextures: OBJFileLoader.WAIT_FOR_TEXTURES,
|
|
48
49
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
49
50
|
UVScaling: OBJFileLoader.UV_SCALING,
|
|
50
51
|
materialLoadingFailsSilently: OBJFileLoader.MATERIAL_LOADING_FAILS_SILENTLY,
|
|
@@ -118,13 +119,20 @@ export class OBJFileLoader {
|
|
|
118
119
|
//get the meshes from OBJ file
|
|
119
120
|
// eslint-disable-next-line github/no-then
|
|
120
121
|
return this._parseSolidAsync(meshesNames, scene, data, rootUrl).then((meshes) => {
|
|
122
|
+
const geometries = [];
|
|
123
|
+
for (let i = 0; i < meshes.length; ++i) {
|
|
124
|
+
const geometry = meshes[i].geometry;
|
|
125
|
+
if (geometry) {
|
|
126
|
+
geometries.push(geometry);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
121
129
|
return {
|
|
122
130
|
meshes: meshes,
|
|
123
131
|
particleSystems: [],
|
|
124
132
|
skeletons: [],
|
|
125
133
|
animationGroups: [],
|
|
126
134
|
transformNodes: [],
|
|
127
|
-
geometries:
|
|
135
|
+
geometries: geometries,
|
|
128
136
|
lights: [],
|
|
129
137
|
spriteManagers: [],
|
|
130
138
|
};
|
|
@@ -152,38 +160,21 @@ export class OBJFileLoader {
|
|
|
152
160
|
* @param rootUrl The root url for scene and resources
|
|
153
161
|
* @returns The loaded asset container
|
|
154
162
|
*/
|
|
155
|
-
|
|
156
|
-
loadAssetContainerAsync(scene, data, rootUrl) {
|
|
163
|
+
async loadAssetContainerAsync(scene, data, rootUrl) {
|
|
157
164
|
const container = new AssetContainer(scene);
|
|
158
165
|
this._assetContainer = container;
|
|
159
|
-
|
|
160
|
-
//
|
|
161
|
-
.
|
|
162
|
-
result.meshes.forEach((mesh) => container.meshes.push(mesh));
|
|
163
|
-
result.meshes.forEach((mesh) => {
|
|
164
|
-
const material = mesh.material;
|
|
165
|
-
if (material) {
|
|
166
|
-
// Materials
|
|
167
|
-
if (container.materials.indexOf(material) == -1) {
|
|
168
|
-
container.materials.push(material);
|
|
169
|
-
// Textures
|
|
170
|
-
const textures = material.getActiveTextures();
|
|
171
|
-
textures.forEach((t) => {
|
|
172
|
-
if (container.textures.indexOf(t) == -1) {
|
|
173
|
-
container.textures.push(t);
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
this._assetContainer = null;
|
|
166
|
+
try {
|
|
167
|
+
// Resources are collected as they are created, including before texture loading settles.
|
|
168
|
+
await this.importMeshAsync(null, scene, data, rootUrl);
|
|
180
169
|
return container;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
.
|
|
184
|
-
this._assetContainer = null;
|
|
170
|
+
}
|
|
171
|
+
catch (ex) {
|
|
172
|
+
container.dispose();
|
|
185
173
|
throw ex;
|
|
186
|
-
}
|
|
174
|
+
}
|
|
175
|
+
finally {
|
|
176
|
+
this._assetContainer = null;
|
|
177
|
+
}
|
|
187
178
|
}
|
|
188
179
|
/**
|
|
189
180
|
* Read the OBJ file and create an Array of meshes.
|
|
@@ -213,43 +204,31 @@ export class OBJFileLoader {
|
|
|
213
204
|
const mtlPromises = [];
|
|
214
205
|
// Check if we have a file to load
|
|
215
206
|
if (fileToLoad !== "" && !this._loadingOptions.skipMaterials) {
|
|
216
|
-
//Load the
|
|
207
|
+
// Load the MTL and optionally wait for the textures used by the selected meshes.
|
|
217
208
|
mtlPromises.push(new Promise((resolve, reject) => {
|
|
218
|
-
this._loadMTL(fileToLoad, rootUrl, (dataLoaded) => {
|
|
209
|
+
this._loadMTL(fileToLoad, rootUrl, async (dataLoaded) => {
|
|
219
210
|
try {
|
|
220
211
|
//Create materials thanks MTLLoader function
|
|
221
|
-
materialsFromMTLFile.parseMTL(scene, this._decode(dataLoaded), rootUrl, this._assetContainer);
|
|
222
|
-
//
|
|
223
|
-
for (let n = 0; n < materialsFromMTLFile.materials.length; n
|
|
224
|
-
|
|
225
|
-
let
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
while ((_index = materialToUse.indexOf(materialsFromMTLFile.materials[n].name, startIndex)) > -1) {
|
|
232
|
-
_indices.push(_index);
|
|
233
|
-
startIndex = _index + 1;
|
|
234
|
-
}
|
|
235
|
-
//If the material is not used dispose it
|
|
236
|
-
if (_index === -1 && _indices.length === 0) {
|
|
237
|
-
//If the material is not needed, remove it
|
|
238
|
-
materialsFromMTLFile.materials[n].dispose();
|
|
239
|
-
}
|
|
240
|
-
else {
|
|
241
|
-
for (let o = 0; o < _indices.length; o++) {
|
|
242
|
-
//Apply the material to the Mesh for each mesh with the material
|
|
243
|
-
const mesh = babylonMeshesArray[_indices[o]];
|
|
244
|
-
const material = materialsFromMTLFile.materials[n];
|
|
245
|
-
mesh.material = material;
|
|
246
|
-
if (!mesh.getTotalIndices()) {
|
|
247
|
-
// No indices, we need to turn on point cloud
|
|
248
|
-
material.pointsCloud = true;
|
|
249
|
-
}
|
|
212
|
+
const textureLoadPromises = materialsFromMTLFile.parseMTL(scene, this._decode(dataLoaded), rootUrl, this._assetContainer, this._loadingOptions.invertTextureY, new Set(materialToUse), this._loadingOptions.waitForTextures);
|
|
213
|
+
// Parsing creates the selected materials synchronously; only their textures are pending.
|
|
214
|
+
for (let n = 0; n < materialsFromMTLFile.materials.length; ++n) {
|
|
215
|
+
const material = materialsFromMTLFile.materials[n];
|
|
216
|
+
for (let index = materialToUse.indexOf(material.name); index !== -1; index = materialToUse.indexOf(material.name, index + 1)) {
|
|
217
|
+
const mesh = babylonMeshesArray[index];
|
|
218
|
+
mesh.material = material;
|
|
219
|
+
if (!mesh.getTotalIndices()) {
|
|
220
|
+
// No indices, we need to turn on point cloud
|
|
221
|
+
material.pointsCloud = true;
|
|
250
222
|
}
|
|
251
223
|
}
|
|
252
224
|
}
|
|
225
|
+
if (this._loadingOptions.waitForTextures) {
|
|
226
|
+
const results = await Promise.allSettled(textureLoadPromises);
|
|
227
|
+
const rejected = results.find((result) => result.status === "rejected");
|
|
228
|
+
if (rejected) {
|
|
229
|
+
throw rejected.reason;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
253
232
|
resolve();
|
|
254
233
|
}
|
|
255
234
|
catch (e) {
|
|
@@ -281,17 +260,55 @@ export class OBJFileLoader {
|
|
|
281
260
|
// Iterate over the mesh, determine if it is a line mesh, clone or modify the material to line rendering.
|
|
282
261
|
babylonMeshesArray.forEach((mesh) => {
|
|
283
262
|
if (isLine(mesh)) {
|
|
284
|
-
let mat = mesh.material
|
|
263
|
+
let mat = mesh.material;
|
|
264
|
+
if (!mat) {
|
|
265
|
+
mat = scene._executeWithBlockedEntityCollection(!!this._assetContainer, () => {
|
|
266
|
+
mat = new StandardMaterial(mesh.name + "_line", scene);
|
|
267
|
+
mat._parentContainer = this._assetContainer;
|
|
268
|
+
this._assetContainer?.materials.push(mat);
|
|
269
|
+
return mat;
|
|
270
|
+
});
|
|
271
|
+
}
|
|
285
272
|
// If another mesh is using this material and it is not a line then we need to clone it.
|
|
286
273
|
const needClone = mat.getBindedMeshes().filter((e) => !isLine(e)).length > 0;
|
|
287
274
|
if (needClone) {
|
|
288
|
-
|
|
275
|
+
// Clone only the material; keep the MTL texture objects shared.
|
|
276
|
+
const sourceMaterial = mat;
|
|
277
|
+
const { ambientTexture, diffuseTexture, specularTexture, bumpTexture, opacityTexture } = sourceMaterial;
|
|
278
|
+
const lineMaterial = scene._executeWithBlockedEntityCollection(!!this._assetContainer, () => {
|
|
279
|
+
sourceMaterial.ambientTexture = null;
|
|
280
|
+
sourceMaterial.diffuseTexture = null;
|
|
281
|
+
sourceMaterial.specularTexture = null;
|
|
282
|
+
sourceMaterial.bumpTexture = null;
|
|
283
|
+
sourceMaterial.opacityTexture = null;
|
|
284
|
+
try {
|
|
285
|
+
const result = sourceMaterial.clone(sourceMaterial.name + "_line");
|
|
286
|
+
result._parentContainer = this._assetContainer;
|
|
287
|
+
this._assetContainer?.materials.push(result);
|
|
288
|
+
return result;
|
|
289
|
+
}
|
|
290
|
+
finally {
|
|
291
|
+
sourceMaterial.ambientTexture = ambientTexture;
|
|
292
|
+
sourceMaterial.diffuseTexture = diffuseTexture;
|
|
293
|
+
sourceMaterial.specularTexture = specularTexture;
|
|
294
|
+
sourceMaterial.bumpTexture = bumpTexture;
|
|
295
|
+
sourceMaterial.opacityTexture = opacityTexture;
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
lineMaterial.ambientTexture = ambientTexture;
|
|
299
|
+
lineMaterial.diffuseTexture = diffuseTexture;
|
|
300
|
+
lineMaterial.specularTexture = specularTexture;
|
|
301
|
+
lineMaterial.bumpTexture = bumpTexture;
|
|
302
|
+
lineMaterial.opacityTexture = opacityTexture;
|
|
303
|
+
mat = lineMaterial;
|
|
289
304
|
}
|
|
290
305
|
mat.wireframe = true;
|
|
291
306
|
mesh.material = mat;
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
babylonMeshesArray.forEach((mesh) => {
|
|
310
|
+
if (mesh._internalMetadata) {
|
|
311
|
+
mesh._internalMetadata["_isLine"] = undefined;
|
|
295
312
|
}
|
|
296
313
|
});
|
|
297
314
|
return babylonMeshesArray;
|
|
@@ -310,6 +327,11 @@ OBJFileLoader.OPTIMIZE_WITH_UV = true;
|
|
|
310
327
|
* Invert model on y-axis (does a model scaling inversion)
|
|
311
328
|
*/
|
|
312
329
|
OBJFileLoader.INVERT_Y = false;
|
|
330
|
+
/**
|
|
331
|
+
* Wait for referenced textures to finish loading before completing the OBJ load.
|
|
332
|
+
* Defaults to false for backwards compatibility.
|
|
333
|
+
*/
|
|
334
|
+
OBJFileLoader.WAIT_FOR_TEXTURES = false;
|
|
313
335
|
/**
|
|
314
336
|
* Include in meshes the vertex colors available in some OBJ files. This is not part of OBJ standard.
|
|
315
337
|
*/
|