简体   繁体   中英

Kotlin- Sceneform - Load .sfb models from server direct. Not working

Iam and AR android app. I can load my .sfb files from asset. i want to load from direct server in order to secure my assets. Its loading from asset folder. not from direct server. iam using below code pls help me to solve this.

package com.example.a320_ar

import android.net.Uri
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import android.widget.Button
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AlertDialog
import com.google.ar.core.Anchor
import com.google.ar.core.Plane
import com.google.ar.sceneform.AnchorNode
import com.google.ar.sceneform.HitTestResult
import com.google.ar.sceneform.SkeletonNode
import com.google.ar.sceneform.animation.ModelAnimator
import com.google.ar.sceneform.rendering.ModelRenderable
import com.google.ar.sceneform.ux.ArFragment
import com.google.ar.sceneform.ux.TransformableNode
import kotlinx.android.synthetic.main.activity_main.*
import java.io.File

class MainActivity : AppCompatActivity() {
    lateinit var arFragment: ArFragment
    private  lateinit var model: Uri
    private var rendarable: ModelRenderable?=null
    private var animator: ModelAnimator? = null
    //private var modellink:String = "A320_Anim.sfb"
    private var modellink:String = "http://10.0.0.193:90/fbx/A320_Anim.sfb"

    @RequiresApi(Build.VERSION_CODES.N)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        arFragment = sceneform_fragment as ArFragment

        arFragment.setOnTapArPlaneListener { hitResult, plane, motionEvent ->
            if (plane.type != Plane.Type.HORIZONTAL_UPWARD_FACING) {
                return@setOnTapArPlaneListener
            }

            var anchor = hitResult.createAnchor()
            btnStart.setOnClickListener {
                placeObject(
                    arFragment,
                    anchor,
                    Uri.parse(modellink)
                )
            }

        }
    }

    @RequiresApi(Build.VERSION_CODES.N)
    private fun animateModel(name: String) {
        animator?.let { it->
            if(it.isRunning){
                it.end()
            }
        }
        rendarable?.let { modelRenderable ->
            val data = modelRenderable.getAnimationData(name)
            animator = ModelAnimator(data,modelRenderable)
            animator?.start()
        }
    }

    @RequiresApi(Build.VERSION_CODES.N)
    private fun placeObject(arFragment: ArFragment, anchor: Anchor?, model: Uri?) {

        ModelRenderable.builder()
            .setSource(arFragment.context,model)
            .build()
            .thenAccept{
                rendarable = it
                addtoScene(arFragment, anchor, it)
            }
            .exceptionally {
                val builder = AlertDialog.Builder(this)
                builder.setMessage( it.message).setTitle("Error")
                val dialog = builder.create()
                dialog.show()
                return@exceptionally null
            }
    }

    private fun addtoScene(arFragment: ArFragment, anchor: Anchor?, it: ModelRenderable?) {

        val anchorNode = AnchorNode(anchor)
        val skeletonNode = SkeletonNode()
        skeletonNode.renderable = rendarable
        Toast.makeText(this,"inside add scene",Toast.LENGTH_SHORT).show()
        val node = TransformableNode(arFragment.transformationSystem)
        node.addChild(skeletonNode)
        node.setParent(anchorNode)

        node.setOnTapListener { v: HitTestResult?, event: MotionEvent? ->
            //msgText.text = "Tapped me...$anchorNode  ---  $anchor --- $skeletonNode"
           // var bt = findViewById<Button>(R.id.btnDel)
            //bt.visibility = View.VISIBLE
            //removeAnchorNode(anchorNode)
            //bt.setOnClickListener { removeAnchorNode(anchorNode) }
        }

        arFragment.arSceneView.scene.addChild(anchorNode)
    }

}

its working fine no errors. but its not showing my object on fragment.

 private var modellink:String = "http://10.0.0.193:90/fbx/A320_Anim.sfb" (not loading .sfb)

private var modellink:String = "A320_Anim.sfb" (Loading the .sfb- woring fine)

please help me to load the model directly from server. i used all the permissions correctly.

<uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <uses-permission android:name="android.permission.CAMERA"/>

Thanks in advance, Syed Abdul Rahim

Are you still using the old 1.6 version of Sceneform? You could try the new maintained version and also discard the sfb format and switch to glTF. The maintained version is up to date related to android dependencies and ARCore/Filament.

Well to your second question, if you want to secure your assets you have to serve it from a password protected API-Endpoint, but you have to host your own server, maybe some simpler solutions exists. Strings or text files can be directly secured with on board libraries ( https://developer.android.com/guide/topics/security/cryptography )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM