本地语言替换未完成

时间:2018-08-13 08:45:52

标签: autodesk-forge

我是Forge的新手,我想用服务器构建一个离线3d查看器,但是语言选项不能完全正常工作,如下面的屏幕截图所示:

Problem screenshot

仅多维数据集中的语言与浏览器配置相同(图片中为中文),其他均为默认英语单词。

所有.js / .css文件都存储在服务器上,如果我在Autodesk.Viewing.Initializer({language: '***someLanguage***'})中设置了该选项。它仅适用于多维数据集,其他语言仍为英语。

但是,如果我将下面的主要js文件源更改为AutoDesk的CDN(其他js文件仍在本地服务器上)https://developer.api.autodesk.com/derivativeservice/v2/viewers/viewer3D.min.js?v=v3.3(离线和在线版本均相同),则该语言将完全替换为选项并正确运行。

要重现该问题,可以从https://extract.autodesk.io/导出模型,然后在本地http服务器上运行下载文件。

在中国,我们与海外服务器的连接不好,所以我更希望使用本地存储来获得更好的UE,是否应该在本地处理一些获取/发布请求,而我错过了?

1 个答案:

答案 0 :(得分:0)

我尝试过/** * This is an example activity that uses the Sceneform UX package to make common AR tasks easier. */ public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getSimpleName(); private static final double MIN_OPENGL_VERSION = 3.1; Session mSession; private ArFragment arFragment; private ArSceneView arSceneView; private ModelRenderable andyRenderable; private boolean shouldConfigureSession = false; private boolean modelAdded = false; private ObjectAnimator objectAnimation; private TransformableNode andy; private AnchorNode endNode; private GestureDetector trackableGestureDetector; /** * Returns false and displays an error message if Sceneform can not run, true if Sceneform can run * on this device. * <p> * <p>Sceneform requires Android N on the device as well as OpenGL 3.1 capabilities. * <p> * <p>Finishes the activity if Sceneform can not run */ public static boolean checkIsSupportedDeviceOrFinish(final Activity activity) { if (Build.VERSION.SDK_INT < VERSION_CODES.N) { Log.e(TAG, "Sceneform requires Android N or later"); Toast.makeText(activity, "Sceneform requires Android N or later", Toast.LENGTH_LONG).show(); activity.finish(); return false; } String openGlVersionString = ((ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE)) .getDeviceConfigurationInfo() .getGlEsVersion(); if (Double.parseDouble(openGlVersionString) < MIN_OPENGL_VERSION) { Log.e(TAG, "Sceneform requires OpenGL ES 3.1 later"); Toast.makeText(activity, "Sceneform requires OpenGL ES 3.1 or later", Toast.LENGTH_LONG) .show(); activity.finish(); return false; } return true; } @Override @SuppressWarnings({"AndroidApiChecker", "FutureReturnValueIgnored"}) // CompletableFuture requires api level 24 // FutureReturnValueIgnored is not valid protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (!checkIsSupportedDeviceOrFinish(this)) { return; } setContentView(R.layout.activity_main); ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 105); arFragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.ux_fragment); if (arFragment != null) { arFragment.getPlaneDiscoveryController().hide(); arFragment.getPlaneDiscoveryController().setInstructionView(null); } arSceneView = arFragment.getArSceneView(); arSceneView.getScene().addOnUpdateListener((this::onUpdateFrame)); arFragment.getArSceneView().getScene().addOnPeekTouchListener(this::handleOnTouch); this.trackableGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() { public boolean onSingleTapUp(MotionEvent e) { onSingleTap(e); return true; } public boolean onDown(MotionEvent e) { return true; } }); // When you build a Renderable, Sceneform loads its resources in the background while returning // a CompletableFuture. Call thenAccept(), handle(), or check isDone() before calling get(). File file = new File(Environment.getExternalStorageDirectory(), "model.sfb"); Uri photoURI = Uri.fromFile(file); Callable callable = () -> (InputStream) new FileInputStream(file); FutureTask task = new FutureTask<>(callable); new Thread(task).start(); ModelRenderable.builder() .setSource(this, R.raw.model) //.setSource(this, callable) .build() .thenAccept(renderable -> andyRenderable = renderable) .exceptionally( throwable -> { Toast toast = Toast.makeText(this, "Unable to load andy renderable", Toast.LENGTH_LONG); toast.setGravity(Gravity.CENTER, 0, 0); toast.show(); return null; }); arFragment.setOnTapArPlaneListener( (HitResult hitResult, Plane plane, MotionEvent motionEvent) -> { if (andyRenderable == null) { return; } if (modelAdded) { endNode = new AnchorNode(hitResult.createAnchor()); endNode.setParent(arFragment.getArSceneView().getScene()); startWalking(); } }); } private void handleOnTouch(HitTestResult hitTestResult, MotionEvent motionEvent) { // First call ArFragment's listener to handle TransformableNodes. arFragment.onPeekTouch(hitTestResult, motionEvent); // Check for touching a Sceneform node if (hitTestResult.getNode() != null) { return; } // Otherwise call gesture detector. trackableGestureDetector.onTouchEvent(motionEvent); } private void onSingleTap(MotionEvent motionEvent) { Frame frame = arFragment.getArSceneView().getArFrame(); if (frame != null && motionEvent != null && frame.getCamera().getTrackingState() == TrackingState.TRACKING) { for (HitResult hit : frame.hitTest(motionEvent)) { Trackable trackable = hit.getTrackable(); if (trackable instanceof Plane && ((Plane) trackable).isPoseInPolygon(hit.getHitPose())) { Plane plane = (Plane) trackable; endNode = new AnchorNode(plane.createAnchor(plane.getCenterPose())); endNode.setParent(arFragment.getArSceneView().getScene()); startWalking(); // Handle plane hits. break; } else if (trackable instanceof Point) { // Handle point hits Point point = (Point) trackable; endNode = new AnchorNode(point.createAnchor(hit.getHitPose())); endNode.setParent(arFragment.getArSceneView().getScene()); startWalking(); } else if (trackable instanceof AugmentedImage) { // Handle image hits. AugmentedImage image = (AugmentedImage) trackable; endNode = new AnchorNode(image.createAnchor(image.getCenterPose())); endNode.setParent(arFragment.getArSceneView().getScene()); startWalking(); } } } } private void startWalking() { objectAnimation = new ObjectAnimator(); objectAnimation.setAutoCancel(true); objectAnimation.setTarget(andy); // All the positions should be world positions // The first position is the start, and the second is the end. objectAnimation.setObjectValues(andy.getWorldPosition(), endNode.getWorldPosition()); // Use setWorldPosition to position andy. objectAnimation.setPropertyName("worldPosition"); // The Vector3Evaluator is used to evaluator 2 vector3 and return the next // vector3. The default is to use lerp. objectAnimation.setEvaluator(new Vector3Evaluator()); // This makes the animation linear (smooth and uniform). objectAnimation.setInterpolator(new LinearInterpolator()); // Duration in ms of the animation. objectAnimation.setDuration(500); objectAnimation.start(); } private void configureSession() { Config config = new Config(mSession); if (!setupAugmentedImageDb(config)) { Toast.makeText(this, "Could not setup augmented", Toast.LENGTH_SHORT).show(); } config.setUpdateMode(Config.UpdateMode.LATEST_CAMERA_IMAGE); mSession.configure(config); } @Override public void onPause() { super.onPause(); if (mSession != null) { // Note that the order matters - GLSurfaceView is paused first so that it does not try // to query the session. If Session is paused before GLSurfaceView, GLSurfaceView may // still call session.update() and get a SessionPausedException. arSceneView.pause(); mSession.pause(); } } @Override protected void onResume() { super.onResume(); if (mSession == null) { String message = null; Exception exception = null; try { mSession = new Session(this); } catch (UnavailableArcoreNotInstalledException e) { message = "Please install ARCore"; exception = e; } catch (UnavailableApkTooOldException e) { message = "Please update ARCore"; exception = e; } catch (UnavailableSdkTooOldException e) { message = "Please update this app"; exception = e; } catch (Exception e) { message = "This device does not support AR"; exception = e; } if (message != null) { Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); Log.e(TAG, "Exception creating session", exception); return; } shouldConfigureSession = true; } if (shouldConfigureSession) { configureSession(); shouldConfigureSession = false; arSceneView.setupSession(mSession); } } private void onUpdateFrame(FrameTime frameTime) { Frame frame = arSceneView.getArFrame(); Collection<AugmentedImage> updatedAugmentedImages = frame.getUpdatedTrackables(AugmentedImage.class); Log.d("size----", String.valueOf(updatedAugmentedImages.size())); for (AugmentedImage augmentedImage : updatedAugmentedImages) { if (augmentedImage.getTrackingState() == TrackingState.TRACKING) { // Check camera image matches our reference image if (augmentedImage.getName().contains("car")) { if (!modelAdded) { modelAdded = true; Anchor anchor = augmentedImage.createAnchor(augmentedImage.getCenterPose()); AnchorNode anchorNode = new AnchorNode(anchor); anchorNode.setParent(arFragment.getArSceneView().getScene()); // Create the transformable andy and add it to the anchor. andy = new TransformableNode(arFragment.getTransformationSystem()); andy.setParent(anchorNode); andy.setRenderable(andyRenderable); andy.select(); } } } } } private boolean setupAugmentedImageDb(Config config) { AugmentedImageDatabase augmentedImageDatabase; Bitmap augmentedImageBitmap = loadAugmentedImage(); if (augmentedImageBitmap == null) { return false; } augmentedImageDatabase = new AugmentedImageDatabase(mSession); augmentedImageDatabase.addImage("car", augmentedImageBitmap); config.setAugmentedImageDatabase(augmentedImageDatabase); return true; } private Bitmap loadAugmentedImage() { try (InputStream is = getAssets().open("car.jpeg")) { return BitmapFactory.decodeStream(is); } catch (IOException e) { Log.e(TAG, "IO exception loading augmented image bitmap.", e); } return null; } } 并且工作正常,也尝试过中文(似乎还不错)。使用 Viewer v6 。根据许可证,您应该使用Autodesk托管URL(即CDN)中的.js文件:

  

Autodesk Forge查看器只能用于查看由Autodesk Forge服务生成的文件。必须从Autodesk托管URL交付Autodesk Forge Viewer JavaScript。

enter image description here