Three.js + Cordova - 如何在不使用 server/http 的情况下加载纹理?
Three.js + Cordova - How to load textures without the use of a server/http?
我正在尝试使用 Three.js 制作一个可以玩的 Cordova 游戏离线,但似乎 Three.js
非常热衷于制作必须通过 http
提供纹理文件。有没有解决的办法?如果可能的话,我极力避免在我的游戏中使用 Node.js 服务器
在您提到无法完成之前,Google Play/App 商店中有很多 3D 游戏并且可以离线工作,例如 Temple 运行、Match 3D、等。这些是如何工作的?
由于尝试加载 GLB/GLTF
模型,必须在我的 index.js
文件中使用 import {GLTF}
方法,而我的 index.html
文件需要 index.js
声明为 module
,它又被 CORS
击中
我尝试将我的 .glb 文件转换为 .json 并使用 Three.js 的内置 ObjectLoader
,但我收到错误 THREE.ObjectLoader: Can't load resources/models/test.json
index.html
<html>
<head>
<title>Test</title>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy" content="default-src * self blob: data: gap:; style-src * self 'unsafe-inline' blob: data: gap:; script-src * 'self' 'unsafe-eval' 'unsafe-inline' blob: data: gap:; object-src * 'self' blob: data: gap:; img-src * self 'unsafe-inline' blob: data: gap:; connect-src self * 'unsafe-inline' blob: data: gap:; frame-src * self blob: data: gap:;">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="initial-scale=1, width=device-width, viewport-fit=cover">
<meta name="color-scheme" content="light dark">
<link rel="stylesheet" href="css/styles.css">
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/three.min.js"></script>
<script type="text/javascript" src="js/jquery-3.5.1.min.js"> </script>
<script type="text/javascript" src="js/OrbitControls.js"></script>
<script type="module" src="loaders/GLTFLoader.js"></script>
<script type="module" src="js/index.js"></script>
</head>
<body>
<div id="screen-gameplay" class="primary-screen"></div>
</body>
</html>
index.js
//When I remove this `import`, and change the `type = "module"` to
//`type="text/javascript" from `<script type="module" src="js/index.js"></script>`,
//it works fine
import { GLTFLoader } from '../loaders/GLTFLoader.js';
const loader = new THREE.ObjectLoader();
function loadModel(path){
loader.load(
// resource URL
path,
// onLoad callback
// Here the loaded data is assumed to be an object
function ( obj ) {
// Add the loaded object to the scene
scene.add( obj );
},
// onProgress callback
function ( xhr ) {
console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
},
// onError callback
function ( err ) {
console.error( 'An error happened' );
}
);
}
loadModel('resources/models/test.json');
config.xml
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.example.test" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>Test</name>
<description>
Test
</description>
<author email="dev@cordova.apache.org" href="http://cordova.io">
Test
</author>
<content src="index.html" />
<access origin="*" />
<allow-navigation href="*"/>
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<preference name="AndroidXEnabled" value="true" />
<preference name="android-minSdkVersion" value="22" />
<preference name="AndroidInsecureFileModeEnabled" value="true" />
<platform name="android">
<preference name="AndroidBlacklistSecureSocketProtocols" value="SSLv3,TLSv1" />
<resource-file src="www/audio/zombie.wav" target="app/src/main/res/raw/zombie.wav" />
<allow-intent href="market:*" />
<preference name="Orientation" value="landscape" />
<preference name="Fullscreen" value="true" />
<preference name="AndroidXEnabled" value="true" />
<preference name="StatusBarOverlaysWebView" value="false" />
<preference name="AndroidInsecureFileModeEnabled" value="true" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
<platform name="browser">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
</widget>
插件列表
cordova-custom-config 5.1.0 "cordova-custom-config"
cordova-plugin-androidx-adapter 1.1.3 "cordova-plugin-androidx-adapter"
cordova-plugin-badge 0.8.8 "Badge"
cordova-plugin-cors 1.3.0 "CORS"
cordova-plugin-device-motion 2.0.1 "Device Motion"
cordova-plugin-device-orientation 2.0.1 "Device Orientation"
cordova-plugin-device 2.0.3 "Device"
cordova-plugin-fullscreen 1.3.0 "cordova-plugin-fullscreen"
cordova-plugin-local-notification 0.9.3 "LocalNotification"
cordova-plugin-screen-orientation 3.0.2 "Screen Orientation"
cordova-plugin-vibration 3.1.1 "Vibration"
cordova-plugin-whitelist 1.3.5 "Whitelist"
cordova-plugin-wkwebview-engine 1.2.2 "Cordova WKWebView Engine"
cordova-plugin-wkwebviewxhrfix 0.1.0 "WKWebView XHR Fix"
es6-promise-plugin 4.2.2 "Promise"
文件夹和文件结构 (省略最不相关的文件)
www
|_ audio
|_ build
|___ three.js
|___ three.module.js
|___ three.min.js
|_ css
|___ styles.css
|_ img
|_ js
|___ index.js
|___ jquery.js
|___ three.js
|___ orbitControls.js
|_ loaders
|___ GLTFLoader.js
|_ resources
|___ skybox
|___ models
|_____ test.json
|_____ test.glb
|_ index.html
Android工作室Logcat(调试)
2021-12-12 18:29:20.264 10578-10578/? I/om.example.enz: Late-enabling -Xcheck:jni
2021-12-12 18:29:20.264 10578-10578/? I/om.example.enz: Late-enabling -Xcheck:jni
2021-12-12 18:29:20.279 10578-10578/? E/USNET: USNET: appName: com.example.enzy
2021-12-12 18:29:20.276 1360-2387/? W/System.err: at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:30)
2021-12-12 18:29:20.264 10578-10578/? I/om.example.enz: Late-enabling -Xcheck:jni
2021-12-12 18:29:20.280 10578-10578/? D/ProcessState: Binder ioctl to enable oneway spam detection failed: Invalid argument
2021-12-12 18:29:20.279 10578-10578/? E/USNET: USNET: appName: com.example.enzy
2021-12-12 18:29:20.282 10578-10578/? D/ActivityThread: setConscryptValidator
2021-12-12 18:29:20.282 10578-10578/? D/ActivityThread: setConscryptValidator - put
2021-12-12 18:29:20.280 10578-10578/? D/ProcessState: Binder ioctl to enable oneway spam detection failed: Invalid argument
2021-12-12 18:29:20.282 10578-10578/? D/ActivityThread: setConscryptValidator
2021-12-12 18:29:20.282 10578-10578/? D/ActivityThread: setConscryptValidator - put
2021-12-12 18:29:20.279 10578-10578/? E/USNET: USNET: appName: com.example.enzy
2021-12-12 18:29:20.280 10578-10578/? D/ProcessState: Binder ioctl to enable oneway spam detection failed: Invalid argument
2021-12-12 18:29:20.282 10578-10578/? D/ActivityThread: setConscryptValidator
2021-12-12 18:29:20.282 10578-10578/? D/ActivityThread: setConscryptValidator - put
2021-12-12 18:29:20.293 10578-10578/com.example.enzy D/ActivityThread: handleBindApplication()++ app=com.example.enzy
2021-12-12 18:29:20.293 10578-10578/com.example.enzy D/CompatibilityChangeReporter: Compat change id reported: 171979766; UID 10413; state: DISABLED
2021-12-12 18:29:20.298 10578-10578/com.example.enzy D/ApplicationLoaders: Returning zygote-cached class loader: /system/framework/android.test.base.jar
2021-12-12 18:29:20.330 10578-10578/com.example.enzy D/LoadedApk: LoadedApk::makeApplication() appContext.mOpPackageName=com.example.enzy appContext.mBasePackageName=com.example.enzy
2021-12-12 18:29:20.330 10578-10578/com.example.enzy D/NetworkSecurityConfig: No Network Security Config specified, using platform default
2021-12-12 18:29:20.338 10578-10578/com.example.enzy D/NetworkSecurityConfig: No Network Security Config specified, using platform default
2021-12-12 18:29:20.343 10578-10578/com.example.enzy D/ActivityThread: handleBindApplication() --
2021-12-12 18:29:20.347 10578-10602/com.example.enzy I/AdrenoGLES-0: QUALCOMM build : b25f720, I2fb6e682e6
Build Date : 09/14/21
OpenGL ES Shader Compiler Version: EV031.35.01.09
Local Branch : CLDebug0914
Remote Branch :
Remote Branch :
Reconstruct Branch :
2021-12-12 18:29:20.347 10578-10602/com.example.enzy I/AdrenoGLES-0: Build Config : S P 10.0.7 AArch64
2021-12-12 18:29:20.347 10578-10602/com.example.enzy I/AdrenoGLES-0: Driver Path : /vendor/lib64/egl/libGLESv2_adreno.so
2021-12-12 18:29:20.349 10578-10602/com.example.enzy I/AdrenoGLES-0: PFP: 0x016dc094, ME: 0x00000000
2021-12-12 18:29:20.367 10578-10578/com.example.enzy I/CordovaLog: Changing log level to DEBUG(3)
2021-12-12 18:29:20.367 10578-10578/com.example.enzy I/CordovaActivity: Apache Cordova native platform version 10.1.1 is starting
2021-12-12 18:29:20.367 10578-10578/com.example.enzy D/CordovaActivity: CordovaActivity.onCreate()
2021-12-12 18:29:20.372 10578-10578/com.example.enzy I/DecorView: [INFO] isPopOver=false, config=true
2021-12-12 18:29:20.372 10578-10578/com.example.enzy I/DecorView: updateCaptionType >> DecorView@554fcad[], isFloating=false, isApplication=true, hasWindowControllerCallback=true, hasWindowDecorCaption=false
2021-12-12 18:29:20.372 10578-10578/com.example.enzy D/DecorView: setCaptionType = 0, this = DecorView@554fcad[]
2021-12-12 18:29:20.387 10578-10578/com.example.enzy I/WebViewFactory: Loading com.google.android.webview version 96.0.4664.92 (code 466409234)
2021-12-12 18:29:20.397 10578-10578/com.example.enzy W/om.example.enz: Accessing hidden method Landroid/os/Trace;->isTagEnabled(J)Z (unsupported, reflection, allowed)
2021-12-12 18:29:20.397 10578-10578/com.example.enzy W/om.example.enz: Accessing hidden method Landroid/os/Trace;->traceBegin(JLjava/lang/String;)V (unsupported, reflection, allowed)
2021-12-12 18:29:20.397 10578-10578/com.example.enzy W/om.example.enz: Accessing hidden method Landroid/os/Trace;->traceEnd(J)V (unsupported, reflection, allowed)
2021-12-12 18:29:20.397 10578-10578/com.example.enzy W/om.example.enz: Accessing hidden method Landroid/os/Trace;->asyncTraceBegin(JLjava/lang/String;I)V (unsupported, reflection, allowed)
2021-12-12 18:29:20.397 10578-10578/com.example.enzy W/om.example.enz: Accessing hidden method Landroid/os/Trace;->asyncTraceEnd(JLjava/lang/String;I)V (unsupported, reflection, allowed)
2021-12-12 18:29:20.398 10578-10578/com.example.enzy I/cr_WVCFactoryProvider: Loaded version=96.0.4664.92 minSdkVersion=29 isBundle=true multiprocess=true packageId=2
2021-12-12 18:29:20.409 10578-10578/com.example.enzy I/cr_LibraryLoader: Successfully loaded native library
2021-12-12 18:29:20.409 10578-10578/com.example.enzy I/cr_CachingUmaRecorder: Flushed 8 samples from 8 histograms.
2021-12-12 18:29:20.414 10578-10611/com.example.enzy E/SchedPolicy: Failed to find cgroup for tid 10578
2021-12-12 18:29:20.429 10578-10615/com.example.enzy W/chromium: [WARNING:dns_config_service_android.cc(153)] Failed to read DnsConfig.
2021-12-12 18:29:20.439 10578-10578/com.example.enzy D/CompatibilityChangeReporter: Compat change id reported: 171228096; UID 10413; state: ENABLED
2021-12-12 18:29:20.458 10578-10578/com.example.enzy W/om.example.enz: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (unsupported, reflection, allowed)
2021-12-12 18:29:20.458 10578-10578/com.example.enzy W/om.example.enz: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (unsupported, reflection, allowed)
2021-12-12 18:29:20.462 10578-10578/com.example.enzy D/SystemWebViewEngine: CordovaWebView is running on device made by: samsung
2021-12-12 18:29:20.462 10578-10578/com.example.enzy D/SystemWebViewEngine: Enabled insecure file access
2021-12-12 18:29:20.463 10578-10578/com.example.enzy D/PluginManager: init()
2021-12-12 18:29:20.465 10578-10578/com.example.enzy D/PluginManager: getPlugin - put: CordovaAllowListPlugin
2021-12-12 18:29:20.465 10578-10578/com.example.enzy D/PluginManager: startupPlugins: put - Badge
2021-12-12 18:29:20.465 10578-10578/com.example.enzy D/PluginManager: startupPlugins: put - Device
2021-12-12 18:29:20.465 10578-10578/com.example.enzy D/PluginManager: startupPlugins: put - Accelerometer
2021-12-12 18:29:20.465 10578-10578/com.example.enzy D/PluginManager: startupPlugins: put - Compass
2021-12-12 18:29:20.465 10578-10578/com.example.enzy D/PluginManager: startupPlugins: put - AndroidFullScreen
2021-12-12 18:29:20.465 10578-10578/com.example.enzy D/PluginManager: startupPlugins: put - LocalNotification
2021-12-12 18:29:20.465 10578-10578/com.example.enzy D/PluginManager: startupPlugins: put - CDVOrientation
2021-12-12 18:29:20.465 10578-10578/com.example.enzy D/PluginManager: startupPlugins: put - CoreAndroid
2021-12-12 18:29:20.465 10578-10578/com.example.enzy D/CordovaWebViewImpl: >>> loadUrl(file:///android_asset/www/index.html)
2021-12-12 18:29:20.467 10578-10621/com.example.enzy W/om.example.enz: Accessing hidden method Landroid/media/AudioManager;->getOutputLatency(I)I (unsupported, reflection, allowed)
2021-12-12 18:29:20.472 10578-10621/com.example.enzy W/cr_media: Requires BLUETOOTH permission
2021-12-12 18:29:20.472 10578-10578/com.example.enzy D/CordovaActivity: Started the activity.
2021-12-12 18:29:20.475 10578-10578/com.example.enzy D/CordovaActivity: Resumed the activity.
2021-12-12 18:29:20.476 10578-10578/com.example.enzy I/MSHandlerLifeCycle: isMultiSplitHandlerRequested: ignored. pkg=com.example.enzy parent=null callers=com.android.internal.policy.DecorView.setVisibility:4216 android.app.ActivityThread.handleResumeActivity:5285 android.app.servertransaction.ResumeActivityItem.execute:54 android.app.servertransaction.ActivityTransactionItem.execute:45 android.app.servertransaction.TransactionExecutor.executeLifecycleState:176
2021-12-12 18:29:20.476 10578-10578/com.example.enzy I/MSHandlerLifeCycle: removeMultiSplitHandler: no exist. decor=DecorView@554fcad[]
2021-12-12 18:29:20.479 10578-10602/com.example.enzy D/NativeCustomFrequencyManager: [NativeCFMS] BpCustomFrequencyManager::BpCustomFrequencyManager()
2021-12-12 18:29:20.480 10578-10578/com.example.enzy D/InsetsSourceConsumer: setRequestedVisible: visible=false, type=21, host=com.example.enzy/com.example.enzy.MainActivity, from=android.view.InsetsSourceConsumer.hide:242 android.view.InsetsController.collectSourceControls:1214 android.view.InsetsController.controlAnimationUnchecked:1076 android.view.InsetsController.applyAnimation:1455 android.view.InsetsController.applyAnimation:1436 android.view.InsetsController.hide:1005 android.view.InsetsController.hide:980 android.view.ViewRootImpl.controlInsetsForCompatibility:3037 android.view.ViewRootImpl.setView:1504 android.view.WindowManagerGlobal.addView:488
2021-12-12 18:29:20.481 10578-10578/com.example.enzy D/InsetsSourceConsumer: setRequestedVisible: visible=false, type=20, host=com.example.enzy/com.example.enzy.MainActivity, from=android.view.InsetsSourceConsumer.hide:242 android.view.InsetsController.collectSourceControls:1214 android.view.InsetsController.controlAnimationUnchecked:1076 android.view.InsetsController.applyAnimation:1455 android.view.InsetsController.applyAnimation:1436 android.view.InsetsController.hide:1005 android.view.InsetsController.hide:980 android.view.ViewRootImpl.controlInsetsForCompatibility:3037 android.view.ViewRootImpl.setView:1504 android.view.WindowManagerGlobal.addView:488
2021-12-12 18:29:20.481 10578-10578/com.example.enzy D/InsetsSourceConsumer: setRequestedVisible: visible=false, type=1, host=com.example.enzy/com.example.enzy.MainActivity, from=android.view.InsetsSourceConsumer.hide:242 android.view.InsetsController.collectSourceControls:1214 android.view.InsetsController.controlAnimationUnchecked:1076 android.view.InsetsController.applyAnimation:1455 android.view.InsetsController.applyAnimation:1436 android.view.InsetsController.hide:1005 android.view.InsetsController.hide:980 android.view.ViewRootImpl.controlInsetsForCompatibility:3037 android.view.ViewRootImpl.setView:1504 android.view.WindowManagerGlobal.addView:488
2021-12-12 18:29:20.481 10578-10578/com.example.enzy D/InsetsSourceConsumer: setRequestedVisible: visible=false, type=0, host=com.example.enzy/com.example.enzy.MainActivity, from=android.view.InsetsSourceConsumer.hide:242 android.view.InsetsController.collectSourceControls:1214 android.view.InsetsController.controlAnimationUnchecked:1076 android.view.InsetsController.applyAnimation:1455 android.view.InsetsController.applyAnimation:1436 android.view.InsetsController.hide:1005 android.view.InsetsController.hide:980 android.view.ViewRootImpl.controlInsetsForCompatibility:3037 android.view.ViewRootImpl.setView:1504 android.view.WindowManagerGlobal.addView:488
2021-12-12 18:29:20.484 10578-10578/com.example.enzy I/ViewRootImpl@3068e7c[MainActivity]: setView = com.android.internal.policy.DecorView@554fcad TM=true
2021-12-12 18:29:20.484 10578-10578/com.example.enzy I/MSHandlerLifeCycle: isMultiSplitHandlerRequested: windowingMode=1 isFullscreen=true isPopOver=false isHidden=false skipActivityType=false isHandlerType=true this: DecorView@554fcad[MainActivity]
2021-12-12 18:29:20.484 10578-10578/com.example.enzy I/MSHandlerLifeCycle: removeMultiSplitHandler: no exist. decor=DecorView@554fcad[MainActivity]
2021-12-12 18:29:20.509 10578-10578/com.example.enzy I/ViewRootImpl@3068e7c[MainActivity]: Relayout returned: old=(0,0,3200,1440) new=(100,0,3200,1440) req=(3200,1440)0 dur=6 res=0x7 s={true 508994645632} ch=true fn=-1
2021-12-12 18:29:20.512 10578-10602/com.example.enzy D/hw-ProcessState: Binder ioctl to enable oneway spam detection failed: Invalid argument
2021-12-12 18:29:20.537 10578-10602/com.example.enzy I/BufferQueueProducer: [ViewRootImpl@3068e7c[MainActivity]#0(BLAST Consumer)0](id:295200000000,api:1,p:10578,c:10578) queueBuffer: queued for the first time.
2021-12-12 18:29:20.539 10578-10602/com.example.enzy D/OpenGLRenderer: GPIS:: SetUp Pid : 10578 Tid : 10602
2021-12-12 18:29:20.558 10578-10578/com.example.enzy I/View: draw TL bounds[ Rect(0, 0 - 101, 101) ] color[ ff000000 ] this - DecorView@554fcad[MainActivity]
2021-12-12 18:29:20.558 10578-10578/com.example.enzy I/View: draw BL bounds[ Rect(0, 1339 - 101, 1440) ] color[ ff000000 ] this - DecorView@554fcad[MainActivity]
2021-12-12 18:29:20.558 10578-10578/com.example.enzy D/CordovaWebViewImpl: onPageDidNavigate(file:///android_asset/www/index.html)
2021-12-12 18:29:20.558 10578-10578/com.example.enzy D/PluginManager: postMessage: onPageStarted
2021-12-12 18:29:20.558 10578-10578/com.example.enzy I/ViewRootImpl@3068e7c[MainActivity]: MSG_WINDOW_FOCUS_CHANGED 1 1
2021-12-12 18:29:20.559 10578-10578/com.example.enzy D/InputMethodManager: startInputInner - Id : 0
2021-12-12 18:29:20.559 10578-10578/com.example.enzy I/InputMethodManager: startInputInner - mService.startInputOrWindowGainedFocus
2021-12-12 18:29:20.563 10578-10578/com.example.enzy D/InputMethodManager: startInputInner - Id : 0
2021-12-12 18:29:20.583 10578-10578/com.example.enzy D/JsMessageQueue: Set native->JS mode to EvalBridgeMode
2021-12-12 18:29:20.674 10578-10685/com.example.enzy D/PluginManager: getPlugin - put: CoreAndroid
2021-12-12 18:29:20.675 10578-10578/com.example.enzy D/PluginManager: postMessage: spinner
2021-12-12 18:29:20.681 10578-10685/com.example.enzy I/ShortcutBadger: Checking if platform supports badge counters, attempt 1/3.
2021-12-12 18:29:20.686 10578-10685/com.example.enzy I/ShortcutBadger: Badge counter is supported in this platform.
2021-12-12 18:29:20.692 10578-10685/com.example.enzy D/PluginManager: getPlugin - put: Badge
2021-12-12 18:29:20.695 10578-10685/com.example.enzy D/PluginManager: getPlugin - put: Device
2021-12-12 18:29:20.698 10578-10685/com.example.enzy D/PluginManager: getPlugin - put: LocalNotification
2021-12-12 18:29:20.703 10578-10578/com.example.enzy D/CordovaWebViewImpl: onPageFinished(file:///android_asset/www/index.html)
2021-12-12 18:29:20.703 10578-10578/com.example.enzy D/PluginManager: postMessage: onPageFinished
它只是通过 XMLHttpRequest 执行 XHR 请求,因此加载本地文件应该没有任何问题,这完全取决于您的设置方式。
如果您使用的是 cordova-android 10,您可以尝试在 config.xml
中进行设置
<preference name="AndroidInsecureFileModeEnabled" value="true" />
对于 iOS,请尝试使用 cordova-plugin-ios-xhr 并将您的首选项设置为
<preference name="allowFileAccessFromFileURLs" value="true" />
<preference name="allowUniversalAccessFromFileURLs" value="true" />
我正在尝试使用 Three.js 制作一个可以玩的 Cordova 游戏离线,但似乎 Three.js
非常热衷于制作必须通过 http
提供纹理文件。有没有解决的办法?如果可能的话,我极力避免在我的游戏中使用 Node.js 服务器
在您提到无法完成之前,Google Play/App 商店中有很多 3D 游戏并且可以离线工作,例如 Temple 运行、Match 3D、等。这些是如何工作的?
由于尝试加载 GLB/GLTF
模型,必须在我的 index.js
文件中使用 import {GLTF}
方法,而我的 index.html
文件需要 index.js
声明为 module
,它又被 CORS
我尝试将我的 .glb 文件转换为 .json 并使用 Three.js 的内置 ObjectLoader
,但我收到错误 THREE.ObjectLoader: Can't load resources/models/test.json
index.html
<html>
<head>
<title>Test</title>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy" content="default-src * self blob: data: gap:; style-src * self 'unsafe-inline' blob: data: gap:; script-src * 'self' 'unsafe-eval' 'unsafe-inline' blob: data: gap:; object-src * 'self' blob: data: gap:; img-src * self 'unsafe-inline' blob: data: gap:; connect-src self * 'unsafe-inline' blob: data: gap:; frame-src * self blob: data: gap:;">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="initial-scale=1, width=device-width, viewport-fit=cover">
<meta name="color-scheme" content="light dark">
<link rel="stylesheet" href="css/styles.css">
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/three.min.js"></script>
<script type="text/javascript" src="js/jquery-3.5.1.min.js"> </script>
<script type="text/javascript" src="js/OrbitControls.js"></script>
<script type="module" src="loaders/GLTFLoader.js"></script>
<script type="module" src="js/index.js"></script>
</head>
<body>
<div id="screen-gameplay" class="primary-screen"></div>
</body>
</html>
index.js
//When I remove this `import`, and change the `type = "module"` to
//`type="text/javascript" from `<script type="module" src="js/index.js"></script>`,
//it works fine
import { GLTFLoader } from '../loaders/GLTFLoader.js';
const loader = new THREE.ObjectLoader();
function loadModel(path){
loader.load(
// resource URL
path,
// onLoad callback
// Here the loaded data is assumed to be an object
function ( obj ) {
// Add the loaded object to the scene
scene.add( obj );
},
// onProgress callback
function ( xhr ) {
console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
},
// onError callback
function ( err ) {
console.error( 'An error happened' );
}
);
}
loadModel('resources/models/test.json');
config.xml
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.example.test" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>Test</name>
<description>
Test
</description>
<author email="dev@cordova.apache.org" href="http://cordova.io">
Test
</author>
<content src="index.html" />
<access origin="*" />
<allow-navigation href="*"/>
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<preference name="AndroidXEnabled" value="true" />
<preference name="android-minSdkVersion" value="22" />
<preference name="AndroidInsecureFileModeEnabled" value="true" />
<platform name="android">
<preference name="AndroidBlacklistSecureSocketProtocols" value="SSLv3,TLSv1" />
<resource-file src="www/audio/zombie.wav" target="app/src/main/res/raw/zombie.wav" />
<allow-intent href="market:*" />
<preference name="Orientation" value="landscape" />
<preference name="Fullscreen" value="true" />
<preference name="AndroidXEnabled" value="true" />
<preference name="StatusBarOverlaysWebView" value="false" />
<preference name="AndroidInsecureFileModeEnabled" value="true" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
<platform name="browser">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
</widget>
插件列表
cordova-custom-config 5.1.0 "cordova-custom-config"
cordova-plugin-androidx-adapter 1.1.3 "cordova-plugin-androidx-adapter"
cordova-plugin-badge 0.8.8 "Badge"
cordova-plugin-cors 1.3.0 "CORS"
cordova-plugin-device-motion 2.0.1 "Device Motion"
cordova-plugin-device-orientation 2.0.1 "Device Orientation"
cordova-plugin-device 2.0.3 "Device"
cordova-plugin-fullscreen 1.3.0 "cordova-plugin-fullscreen"
cordova-plugin-local-notification 0.9.3 "LocalNotification"
cordova-plugin-screen-orientation 3.0.2 "Screen Orientation"
cordova-plugin-vibration 3.1.1 "Vibration"
cordova-plugin-whitelist 1.3.5 "Whitelist"
cordova-plugin-wkwebview-engine 1.2.2 "Cordova WKWebView Engine"
cordova-plugin-wkwebviewxhrfix 0.1.0 "WKWebView XHR Fix"
es6-promise-plugin 4.2.2 "Promise"
文件夹和文件结构 (省略最不相关的文件)
www
|_ audio
|_ build
|___ three.js
|___ three.module.js
|___ three.min.js
|_ css
|___ styles.css
|_ img
|_ js
|___ index.js
|___ jquery.js
|___ three.js
|___ orbitControls.js
|_ loaders
|___ GLTFLoader.js
|_ resources
|___ skybox
|___ models
|_____ test.json
|_____ test.glb
|_ index.html
Android工作室Logcat(调试)
2021-12-12 18:29:20.264 10578-10578/? I/om.example.enz: Late-enabling -Xcheck:jni
2021-12-12 18:29:20.264 10578-10578/? I/om.example.enz: Late-enabling -Xcheck:jni
2021-12-12 18:29:20.279 10578-10578/? E/USNET: USNET: appName: com.example.enzy
2021-12-12 18:29:20.276 1360-2387/? W/System.err: at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:30)
2021-12-12 18:29:20.264 10578-10578/? I/om.example.enz: Late-enabling -Xcheck:jni
2021-12-12 18:29:20.280 10578-10578/? D/ProcessState: Binder ioctl to enable oneway spam detection failed: Invalid argument
2021-12-12 18:29:20.279 10578-10578/? E/USNET: USNET: appName: com.example.enzy
2021-12-12 18:29:20.282 10578-10578/? D/ActivityThread: setConscryptValidator
2021-12-12 18:29:20.282 10578-10578/? D/ActivityThread: setConscryptValidator - put
2021-12-12 18:29:20.280 10578-10578/? D/ProcessState: Binder ioctl to enable oneway spam detection failed: Invalid argument
2021-12-12 18:29:20.282 10578-10578/? D/ActivityThread: setConscryptValidator
2021-12-12 18:29:20.282 10578-10578/? D/ActivityThread: setConscryptValidator - put
2021-12-12 18:29:20.279 10578-10578/? E/USNET: USNET: appName: com.example.enzy
2021-12-12 18:29:20.280 10578-10578/? D/ProcessState: Binder ioctl to enable oneway spam detection failed: Invalid argument
2021-12-12 18:29:20.282 10578-10578/? D/ActivityThread: setConscryptValidator
2021-12-12 18:29:20.282 10578-10578/? D/ActivityThread: setConscryptValidator - put
2021-12-12 18:29:20.293 10578-10578/com.example.enzy D/ActivityThread: handleBindApplication()++ app=com.example.enzy
2021-12-12 18:29:20.293 10578-10578/com.example.enzy D/CompatibilityChangeReporter: Compat change id reported: 171979766; UID 10413; state: DISABLED
2021-12-12 18:29:20.298 10578-10578/com.example.enzy D/ApplicationLoaders: Returning zygote-cached class loader: /system/framework/android.test.base.jar
2021-12-12 18:29:20.330 10578-10578/com.example.enzy D/LoadedApk: LoadedApk::makeApplication() appContext.mOpPackageName=com.example.enzy appContext.mBasePackageName=com.example.enzy
2021-12-12 18:29:20.330 10578-10578/com.example.enzy D/NetworkSecurityConfig: No Network Security Config specified, using platform default
2021-12-12 18:29:20.338 10578-10578/com.example.enzy D/NetworkSecurityConfig: No Network Security Config specified, using platform default
2021-12-12 18:29:20.343 10578-10578/com.example.enzy D/ActivityThread: handleBindApplication() --
2021-12-12 18:29:20.347 10578-10602/com.example.enzy I/AdrenoGLES-0: QUALCOMM build : b25f720, I2fb6e682e6
Build Date : 09/14/21
OpenGL ES Shader Compiler Version: EV031.35.01.09
Local Branch : CLDebug0914
Remote Branch :
Remote Branch :
Reconstruct Branch :
2021-12-12 18:29:20.347 10578-10602/com.example.enzy I/AdrenoGLES-0: Build Config : S P 10.0.7 AArch64
2021-12-12 18:29:20.347 10578-10602/com.example.enzy I/AdrenoGLES-0: Driver Path : /vendor/lib64/egl/libGLESv2_adreno.so
2021-12-12 18:29:20.349 10578-10602/com.example.enzy I/AdrenoGLES-0: PFP: 0x016dc094, ME: 0x00000000
2021-12-12 18:29:20.367 10578-10578/com.example.enzy I/CordovaLog: Changing log level to DEBUG(3)
2021-12-12 18:29:20.367 10578-10578/com.example.enzy I/CordovaActivity: Apache Cordova native platform version 10.1.1 is starting
2021-12-12 18:29:20.367 10578-10578/com.example.enzy D/CordovaActivity: CordovaActivity.onCreate()
2021-12-12 18:29:20.372 10578-10578/com.example.enzy I/DecorView: [INFO] isPopOver=false, config=true
2021-12-12 18:29:20.372 10578-10578/com.example.enzy I/DecorView: updateCaptionType >> DecorView@554fcad[], isFloating=false, isApplication=true, hasWindowControllerCallback=true, hasWindowDecorCaption=false
2021-12-12 18:29:20.372 10578-10578/com.example.enzy D/DecorView: setCaptionType = 0, this = DecorView@554fcad[]
2021-12-12 18:29:20.387 10578-10578/com.example.enzy I/WebViewFactory: Loading com.google.android.webview version 96.0.4664.92 (code 466409234)
2021-12-12 18:29:20.397 10578-10578/com.example.enzy W/om.example.enz: Accessing hidden method Landroid/os/Trace;->isTagEnabled(J)Z (unsupported, reflection, allowed)
2021-12-12 18:29:20.397 10578-10578/com.example.enzy W/om.example.enz: Accessing hidden method Landroid/os/Trace;->traceBegin(JLjava/lang/String;)V (unsupported, reflection, allowed)
2021-12-12 18:29:20.397 10578-10578/com.example.enzy W/om.example.enz: Accessing hidden method Landroid/os/Trace;->traceEnd(J)V (unsupported, reflection, allowed)
2021-12-12 18:29:20.397 10578-10578/com.example.enzy W/om.example.enz: Accessing hidden method Landroid/os/Trace;->asyncTraceBegin(JLjava/lang/String;I)V (unsupported, reflection, allowed)
2021-12-12 18:29:20.397 10578-10578/com.example.enzy W/om.example.enz: Accessing hidden method Landroid/os/Trace;->asyncTraceEnd(JLjava/lang/String;I)V (unsupported, reflection, allowed)
2021-12-12 18:29:20.398 10578-10578/com.example.enzy I/cr_WVCFactoryProvider: Loaded version=96.0.4664.92 minSdkVersion=29 isBundle=true multiprocess=true packageId=2
2021-12-12 18:29:20.409 10578-10578/com.example.enzy I/cr_LibraryLoader: Successfully loaded native library
2021-12-12 18:29:20.409 10578-10578/com.example.enzy I/cr_CachingUmaRecorder: Flushed 8 samples from 8 histograms.
2021-12-12 18:29:20.414 10578-10611/com.example.enzy E/SchedPolicy: Failed to find cgroup for tid 10578
2021-12-12 18:29:20.429 10578-10615/com.example.enzy W/chromium: [WARNING:dns_config_service_android.cc(153)] Failed to read DnsConfig.
2021-12-12 18:29:20.439 10578-10578/com.example.enzy D/CompatibilityChangeReporter: Compat change id reported: 171228096; UID 10413; state: ENABLED
2021-12-12 18:29:20.458 10578-10578/com.example.enzy W/om.example.enz: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (unsupported, reflection, allowed)
2021-12-12 18:29:20.458 10578-10578/com.example.enzy W/om.example.enz: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (unsupported, reflection, allowed)
2021-12-12 18:29:20.462 10578-10578/com.example.enzy D/SystemWebViewEngine: CordovaWebView is running on device made by: samsung
2021-12-12 18:29:20.462 10578-10578/com.example.enzy D/SystemWebViewEngine: Enabled insecure file access
2021-12-12 18:29:20.463 10578-10578/com.example.enzy D/PluginManager: init()
2021-12-12 18:29:20.465 10578-10578/com.example.enzy D/PluginManager: getPlugin - put: CordovaAllowListPlugin
2021-12-12 18:29:20.465 10578-10578/com.example.enzy D/PluginManager: startupPlugins: put - Badge
2021-12-12 18:29:20.465 10578-10578/com.example.enzy D/PluginManager: startupPlugins: put - Device
2021-12-12 18:29:20.465 10578-10578/com.example.enzy D/PluginManager: startupPlugins: put - Accelerometer
2021-12-12 18:29:20.465 10578-10578/com.example.enzy D/PluginManager: startupPlugins: put - Compass
2021-12-12 18:29:20.465 10578-10578/com.example.enzy D/PluginManager: startupPlugins: put - AndroidFullScreen
2021-12-12 18:29:20.465 10578-10578/com.example.enzy D/PluginManager: startupPlugins: put - LocalNotification
2021-12-12 18:29:20.465 10578-10578/com.example.enzy D/PluginManager: startupPlugins: put - CDVOrientation
2021-12-12 18:29:20.465 10578-10578/com.example.enzy D/PluginManager: startupPlugins: put - CoreAndroid
2021-12-12 18:29:20.465 10578-10578/com.example.enzy D/CordovaWebViewImpl: >>> loadUrl(file:///android_asset/www/index.html)
2021-12-12 18:29:20.467 10578-10621/com.example.enzy W/om.example.enz: Accessing hidden method Landroid/media/AudioManager;->getOutputLatency(I)I (unsupported, reflection, allowed)
2021-12-12 18:29:20.472 10578-10621/com.example.enzy W/cr_media: Requires BLUETOOTH permission
2021-12-12 18:29:20.472 10578-10578/com.example.enzy D/CordovaActivity: Started the activity.
2021-12-12 18:29:20.475 10578-10578/com.example.enzy D/CordovaActivity: Resumed the activity.
2021-12-12 18:29:20.476 10578-10578/com.example.enzy I/MSHandlerLifeCycle: isMultiSplitHandlerRequested: ignored. pkg=com.example.enzy parent=null callers=com.android.internal.policy.DecorView.setVisibility:4216 android.app.ActivityThread.handleResumeActivity:5285 android.app.servertransaction.ResumeActivityItem.execute:54 android.app.servertransaction.ActivityTransactionItem.execute:45 android.app.servertransaction.TransactionExecutor.executeLifecycleState:176
2021-12-12 18:29:20.476 10578-10578/com.example.enzy I/MSHandlerLifeCycle: removeMultiSplitHandler: no exist. decor=DecorView@554fcad[]
2021-12-12 18:29:20.479 10578-10602/com.example.enzy D/NativeCustomFrequencyManager: [NativeCFMS] BpCustomFrequencyManager::BpCustomFrequencyManager()
2021-12-12 18:29:20.480 10578-10578/com.example.enzy D/InsetsSourceConsumer: setRequestedVisible: visible=false, type=21, host=com.example.enzy/com.example.enzy.MainActivity, from=android.view.InsetsSourceConsumer.hide:242 android.view.InsetsController.collectSourceControls:1214 android.view.InsetsController.controlAnimationUnchecked:1076 android.view.InsetsController.applyAnimation:1455 android.view.InsetsController.applyAnimation:1436 android.view.InsetsController.hide:1005 android.view.InsetsController.hide:980 android.view.ViewRootImpl.controlInsetsForCompatibility:3037 android.view.ViewRootImpl.setView:1504 android.view.WindowManagerGlobal.addView:488
2021-12-12 18:29:20.481 10578-10578/com.example.enzy D/InsetsSourceConsumer: setRequestedVisible: visible=false, type=20, host=com.example.enzy/com.example.enzy.MainActivity, from=android.view.InsetsSourceConsumer.hide:242 android.view.InsetsController.collectSourceControls:1214 android.view.InsetsController.controlAnimationUnchecked:1076 android.view.InsetsController.applyAnimation:1455 android.view.InsetsController.applyAnimation:1436 android.view.InsetsController.hide:1005 android.view.InsetsController.hide:980 android.view.ViewRootImpl.controlInsetsForCompatibility:3037 android.view.ViewRootImpl.setView:1504 android.view.WindowManagerGlobal.addView:488
2021-12-12 18:29:20.481 10578-10578/com.example.enzy D/InsetsSourceConsumer: setRequestedVisible: visible=false, type=1, host=com.example.enzy/com.example.enzy.MainActivity, from=android.view.InsetsSourceConsumer.hide:242 android.view.InsetsController.collectSourceControls:1214 android.view.InsetsController.controlAnimationUnchecked:1076 android.view.InsetsController.applyAnimation:1455 android.view.InsetsController.applyAnimation:1436 android.view.InsetsController.hide:1005 android.view.InsetsController.hide:980 android.view.ViewRootImpl.controlInsetsForCompatibility:3037 android.view.ViewRootImpl.setView:1504 android.view.WindowManagerGlobal.addView:488
2021-12-12 18:29:20.481 10578-10578/com.example.enzy D/InsetsSourceConsumer: setRequestedVisible: visible=false, type=0, host=com.example.enzy/com.example.enzy.MainActivity, from=android.view.InsetsSourceConsumer.hide:242 android.view.InsetsController.collectSourceControls:1214 android.view.InsetsController.controlAnimationUnchecked:1076 android.view.InsetsController.applyAnimation:1455 android.view.InsetsController.applyAnimation:1436 android.view.InsetsController.hide:1005 android.view.InsetsController.hide:980 android.view.ViewRootImpl.controlInsetsForCompatibility:3037 android.view.ViewRootImpl.setView:1504 android.view.WindowManagerGlobal.addView:488
2021-12-12 18:29:20.484 10578-10578/com.example.enzy I/ViewRootImpl@3068e7c[MainActivity]: setView = com.android.internal.policy.DecorView@554fcad TM=true
2021-12-12 18:29:20.484 10578-10578/com.example.enzy I/MSHandlerLifeCycle: isMultiSplitHandlerRequested: windowingMode=1 isFullscreen=true isPopOver=false isHidden=false skipActivityType=false isHandlerType=true this: DecorView@554fcad[MainActivity]
2021-12-12 18:29:20.484 10578-10578/com.example.enzy I/MSHandlerLifeCycle: removeMultiSplitHandler: no exist. decor=DecorView@554fcad[MainActivity]
2021-12-12 18:29:20.509 10578-10578/com.example.enzy I/ViewRootImpl@3068e7c[MainActivity]: Relayout returned: old=(0,0,3200,1440) new=(100,0,3200,1440) req=(3200,1440)0 dur=6 res=0x7 s={true 508994645632} ch=true fn=-1
2021-12-12 18:29:20.512 10578-10602/com.example.enzy D/hw-ProcessState: Binder ioctl to enable oneway spam detection failed: Invalid argument
2021-12-12 18:29:20.537 10578-10602/com.example.enzy I/BufferQueueProducer: [ViewRootImpl@3068e7c[MainActivity]#0(BLAST Consumer)0](id:295200000000,api:1,p:10578,c:10578) queueBuffer: queued for the first time.
2021-12-12 18:29:20.539 10578-10602/com.example.enzy D/OpenGLRenderer: GPIS:: SetUp Pid : 10578 Tid : 10602
2021-12-12 18:29:20.558 10578-10578/com.example.enzy I/View: draw TL bounds[ Rect(0, 0 - 101, 101) ] color[ ff000000 ] this - DecorView@554fcad[MainActivity]
2021-12-12 18:29:20.558 10578-10578/com.example.enzy I/View: draw BL bounds[ Rect(0, 1339 - 101, 1440) ] color[ ff000000 ] this - DecorView@554fcad[MainActivity]
2021-12-12 18:29:20.558 10578-10578/com.example.enzy D/CordovaWebViewImpl: onPageDidNavigate(file:///android_asset/www/index.html)
2021-12-12 18:29:20.558 10578-10578/com.example.enzy D/PluginManager: postMessage: onPageStarted
2021-12-12 18:29:20.558 10578-10578/com.example.enzy I/ViewRootImpl@3068e7c[MainActivity]: MSG_WINDOW_FOCUS_CHANGED 1 1
2021-12-12 18:29:20.559 10578-10578/com.example.enzy D/InputMethodManager: startInputInner - Id : 0
2021-12-12 18:29:20.559 10578-10578/com.example.enzy I/InputMethodManager: startInputInner - mService.startInputOrWindowGainedFocus
2021-12-12 18:29:20.563 10578-10578/com.example.enzy D/InputMethodManager: startInputInner - Id : 0
2021-12-12 18:29:20.583 10578-10578/com.example.enzy D/JsMessageQueue: Set native->JS mode to EvalBridgeMode
2021-12-12 18:29:20.674 10578-10685/com.example.enzy D/PluginManager: getPlugin - put: CoreAndroid
2021-12-12 18:29:20.675 10578-10578/com.example.enzy D/PluginManager: postMessage: spinner
2021-12-12 18:29:20.681 10578-10685/com.example.enzy I/ShortcutBadger: Checking if platform supports badge counters, attempt 1/3.
2021-12-12 18:29:20.686 10578-10685/com.example.enzy I/ShortcutBadger: Badge counter is supported in this platform.
2021-12-12 18:29:20.692 10578-10685/com.example.enzy D/PluginManager: getPlugin - put: Badge
2021-12-12 18:29:20.695 10578-10685/com.example.enzy D/PluginManager: getPlugin - put: Device
2021-12-12 18:29:20.698 10578-10685/com.example.enzy D/PluginManager: getPlugin - put: LocalNotification
2021-12-12 18:29:20.703 10578-10578/com.example.enzy D/CordovaWebViewImpl: onPageFinished(file:///android_asset/www/index.html)
2021-12-12 18:29:20.703 10578-10578/com.example.enzy D/PluginManager: postMessage: onPageFinished
它只是通过 XMLHttpRequest 执行 XHR 请求,因此加载本地文件应该没有任何问题,这完全取决于您的设置方式。 如果您使用的是 cordova-android 10,您可以尝试在 config.xml
中进行设置 <preference name="AndroidInsecureFileModeEnabled" value="true" />
对于 iOS,请尝试使用 cordova-plugin-ios-xhr 并将您的首选项设置为
<preference name="allowFileAccessFromFileURLs" value="true" />
<preference name="allowUniversalAccessFromFileURLs" value="true" />