PHP实现WEB 3D应用

原创
2023/02/14 10:22
阅读数 43

这是另一篇关于如何使用 PHP加载 3D 模型的文章。 在这里,我使用 Laravel 作为后端及其存储。 我在前端使用 Three.Js 库来渲染和显示 3D 模型。 我将向您展示如何上传 3D 模型以及如何从 Laravel 存储加载 3D 模型。 请仔细完成以下步骤。 大家可以在评论区提出任何问题。 在这里,我展示了一条主要路径,然后你可以根据自己的喜好对其进行自定义。

在这里插入图片描述

推荐:使用 NSDT场景设计器 快速搭建 3D场景。

1、创建 Laravel 项目

创建一个新的 Laravel 项目并创建新的模型、视图和控制器。 然后使用下面的命令链接存储。

php artisan storage:link

2、上传 3D 模型

你可以使用 HTML 和 Javascript 创建一个简单的表单。 我使用 Laravel blade文件来构建前端。

<form action="{{ route('model.store') }}" method="POST" id="file-upload" enctype="multipart/form-data">
          @csrf
          <div class="form-group row">
              <label for="name" class="col-md-4 col-form-label text-md-right">Model Name</label>
              <div class="col-md-6">
              <div class="row">
                  <input id="name" type="name" class="form-control" name="name" required>
              </div>
              </div>
          </div>
        <div class="form-group row">
              <label for="file_type" class="col-md-4 col-form-label text-md-right">File Type</label>
              <div class="col-md-6">
              <div class="row">
                <select class="form-select" aria-label="Default select example" name="file_type" id="file_type">
                    <option value="gltf">GLTF</option>
                    <option value="obj">OBJ</option>
                    <option value="fbx">FBX</option>
                </select>
              </div>
              </div>
          </div>
          <div class="form-group row">
              <label for="file" class="col-md-4 col-form-label text-md-right">Upload Main File</label>
              <div class="col-md-6">
              <div class="row">
                  <input type="file" id="main"  class="form-control" name="main"  required>
              </div>
              </div>
          </div>
          <div class="form-group row">
              <label for="file" class="col-md-4 col-form-label text-md-right">Upload Other Files</label>
              <div class="col-md-6">
              <div class="row">
                  <input type="file" id="files"  class="form-control" name="files[]"  required multiple>
              </div>
              </div>
          </div>
          <div class="form-group row">
              <label for="preview" class="col-md-4 col-form-label text-md-right">Upload Preview Image</label>
              <div class="col-md-6">
              <div class="row">
                  <input type="file" id="preview"  class="form-control" name="preview"  required>
              </div>
              </div>
          </div>
          <div class="form-group row mb-0">
              <div class="col-md-6 offset-md-4">
                  <button type="button" class="btn btn-secondary" onclick="window.history.back()">Close</button>
                  <button type="submit" class="btn btn-primary" id="product_save_btn">
                      Upload Model
                  </button>
              </div>
          </div>
      </form>

使用 Ajax 调用提交表单:

$(document).ready(function() {
        $('#file-upload').submit(function(e) {
            e.preventDefault();
            let formData = new FormData(this);

            $.ajax({
                type:'POST',
                url: "{{ route('model.store') }}",
                data: formData,
                contentType: false,
                processData: false,
                success: (response) => {
                    console.log(response);
                    if (response.success) {
                        window.location.href = response.url;
                    }
                },
                error: function(response){
                    alert('Prescription has not been created successfully');
                }
          });
        });
    });

在后端,可以按如下方式实现 store() 方法:

  /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required',
            'files' => 'required',
            'file_type' => 'required',
            'main' => 'required',
            'preview' => 'required',
        ]);
        
        if ($validator->fails())
        {
            return response()->json(['errors'=>$validator->errors()->all()]);
        }

        $date = date('Y-m-d');
        $folder = $date.time();
        $files = $request->file('files');
        foreach ($files as $file) {
            $file_name = $file->getClientOriginalName();
            $fileName = pathinfo($file_name, PATHINFO_FILENAME);
         
            try {
                $path = Storage::disk('public')->PutFileAs($folder , $file, $file->getClientOriginalName());
            } catch (\Exception $e) {
                return false;
            }
        }

        if ($request->hasFile('preview')) {
            $file = $request->file('preview');
            $file_name = $file->getClientOriginalName();
            $imageName = time().'.'.$file->extension();  
            $preview_path = Storage::disk('public')->PutFileAs($folder, $file, $file->getClientOriginalName());
        
        }

        if ($request->hasFile('main')) {
            $file = $request->file('main');
            $file_name = $file->getClientOriginalName();
            $imageName = time().'.'.$file->extension();  
            $path = Storage::disk('public')->PutFileAs($folder,$file,$file->getClientOriginalName());
        
        }

        return response()->json(['success'=> true, 'msg'=>'Record is successfully added', 'url'=> '/home']);
    
    }

然后就可以在存储中看到上传的文件了。 它们被组织为单独的文件夹。 要显示 3D 模型,你需要路径 URL。 在这里插入图片描述

3、加载 3D 模型

在下面的示例中,我向你展示如何从 laravel 存储加载 fbx 模型。 同样,你可以轻松加载其他文件类型。 请理解并尝试首先针对一种文件类型实施它。

 if(myData['file_type'] == 'fbx'){
          init1();
        }else if(myData['file_type'] == 'obj'){
          init2();
        }
      
      
      function init1() {
            scene = new THREE.Scene();
            scene.background = new THREE.Color(0xdddddd);

            camera = new THREE.PerspectiveCamera(5, window.innerWidth/window.innerHeight, 1, 5000);
            camera.position.z = 1000;

            light = new THREE.HemisphereLight(0xffffff, 0x444444, 1.0);
            light.position.set(0, 1, 0);
            scene.add(light);

            light = new THREE.DirectionalLight(0xffffff, 1.0);
            light.position.set(0, 1, 0);
            scene.add(light);

            renderer = new THREE.WebGLRenderer({antialias:true});
            renderer.setSize(window.innerWidth, window.innerHeight);

            container = document.getElementById( 'canvas' );
            renderer.setSize(container.offsetWidth, 400);
            
            container.appendChild( renderer.domElement );

            controls = new THREE.OrbitControls(camera,  renderer.domElement);
            controls.addEventListener('change', renderer);
            const fbxLoader = new THREE.FBXLoader();
                let text1 = "storage/";
                let result = text1.concat(myData['url']);
                console.log(result);
                fbxLoader.load('{{ asset('storage/') }}'+'/'+myData['url']+'.fbx', (object) => {
                scene.add(object);
                animate();
            });
        }
        function animate(){
            renderer.render(scene,camera);
            requestAnimationFrame(animate);
        }

这里的方法根据3D模型文件类型而改变。


原文链接:PHP加载3D模型 — BimAnt

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部