3D model renders local but not on AWS - reactjs

I'm currently having an issue with AWS. I have a simple react-three-fiber build, that renders a car model from a .gltf file. The model and build run fine locally but not on AWS. The error I get is
Could not load /tesla_model_3/scene.gltf: Unexpected token < in JSON at position 0
I can't figure out why AWS won't load the JSON object of the model and instead is passing in an HTML. here is the site deployed: https://master.d258lkzp17ij6b.amplifyapp.com/
It could be a pathing issue, but it runs fine on a local server.
the file scene.gltf is the /public folder
and here are the code blocks for the model and the call to the component.
also here is the Github for the files if needed: https://github.com/SBrandon0432/tesla-car-shop/tree/Master/src
import React, {lazy, Suspense} from 'react';
import { useLoader } from '#react-three/fiber';
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
const Model = props =>{
const model = useLoader(
GLTFLoader, props.path
)
return (
<Suspense>
<primitive object={model.scene} scale={'.50'} position={[0,0,0]}/>
</Suspense>
)
}
export default Model
import React, {useRef, useEffect, Suspense, lazy} from "react";
import { ReactThreeFiber, Canvas, useFrame, extend, useThree, useLoader } from 'react-three-fiber';
import * as THREE from 'three';
import Box from './Box';
import Background from "./Background";
import Bulb from "./Bulb";
import Controls from "./Controls";
import Floor from "./Floor";
const Model = lazy(() => import("./Model"));
const ThreeD = () => {
return (
<Canvas className="ThreeD"
shadows
camera={{position:[200,200,200]}}
>
<ambientLight intensity={1.5}/>
<Bulb position={[0, 3, 0]}/>
<Suspense fallback={null}>
<Model
path={'/tesla_model_3/scene.gltf'}
/>
</Suspense>
<Controls/>
<axesHelper args={[5]}/>
<Suspense fallback={null}>
<Box position={[4,2,0]}/>
</Suspense>
<Suspense fallback={null}>
<Background/>
</Suspense>
<Floor position={[0,-.5,0]}/>
</Canvas>
)
}
export default ThreeD;

Related

React Three Fiber, Three.js and Drei: lazy import models using components gets re-rendered to infinity

I'm trying to lazy import JSX models in React Three Fiber.
I have a couple of JSX models which incorporate useGLTF() from drei, to load the actual .gltf/.glb model, as nodes and materials, like in the R3F tutorial.
What I'm trying to do now, is to lazy import those JSX model components on demand, through my ModelsLoader component.
The problem is that even when I use memo() or useMemo() from React, the component gets re-rendered constantly...
I don't know what I'm doing wrong, or even if what I'm trying to do is even possible, but hey, there are a lot of smart people here, some maybe you'll be able to help me ;)
example of my JSX model component, which I'm trying to lazy import in ModelsLoader component:
import React, { useRef } from 'react';
import { useGLTF } from '#react-three/drei';
export default function OCF155(props) {
const { nodes } = useGLTF('models/EXAMPLE_MODEL.glb');
const ref = useRef();
return (
<group {...props} ref={ref} dispose={null} type='TopParent'>
<mesh
name='EXAMPLE_MODEL'
castShadow
receiveShadow
geometry={nodes.EXAMPLE_MODEL.geometry}
material={nodes.EXAMPLE_MODEL.material}
rotation={[Math.PI / 2, 0, 0]}
scale={1}
/>
</group>
);
}
And here is my ModelsLoader component as it's stands for now, using .memo():
import React, { memo, lazy } from 'react';
import Selection from './helpers/Selection';
const ModelsLoader = memo(function ModelsLoader({ models }) {
return (
<>
{models &&
models.length > 0 &&
models.map((model, index) => {
const ModelComponent = lazy(() => import(`./models/${model.name}`));
return (
<Selection key={index}>
<ModelComponent
position={model.position}
rotation={model.rotation}
/>
</Selection>
);
})}
</>
);
});
export default ModelsLoader;
I was trying to do it without .memo(), but the result was the same. I was thinking, that if I use .memo(), hence the models list is not changing throughout the render of the page, it will get rendered once and then passed on...

Is my react getting loaded before showing up?

This is my App.js and earlier I was using Suspense but it does not seem to be working as it is not able to load the image and the font after the loader.
import React, { Suspense } from 'react';
import './App.css';
import SyncLoader from "react-spinners/SyncLoader";
const Newhome = React.lazy(() => import('./COMPONENTS/Newhome'));
function App() {
return (
<>
{
window.onload = <Newhome/>
}
{/* <Suspense className='App' fallback={
<SyncLoader size={'20px'} color='#FF5757' className='loader App'/>
}>
<Newhome />
</Suspense> */}
</>
);
}
export default App;
I have commented the Suspense tag part for now.
What can do so that the image, jsx, fonts, and everything loads and then the page is shown?

OBJ Model not loading in react three fiber

I'm trying to add an OBJ Model (armchair.obj) but it's not being loaded. I'm using React three fiber library.
Here's my codesandbox: CodeSandbox
There's no problem with the model because I tried to load it using some other website and it is being loaded.
Anyway, I tried uploading another model (spongebob.obj) but it's not being really visible
However, in the other website, it's visible:
So, here's my codesandbox link
But, if you prefer the code here:
My App.js component:
import React, { Suspense } from "react";
import { Canvas } from "#react-three/fiber";
import { OrbitControls } from "#react-three/drei";
import LoadModel from "./components/LoadModel";
import Loader from "./components/Loader";
const App = () => {
return (
<main className="main-area">
<div id="canvas-container">
<Canvas pixelratio={[1, 2]} camera={{ position: [15, 15, 15], fov: 50, scale: [2,2,2] }}>
<ambientLight intensity={1} />
<Suspense fallback={<Loader />}>
<LoadModel url="./spongebob.obj" />
</Suspense>
<OrbitControls />
</Canvas>
</div>
</main>
);
};
export default App;
My LoadModel.js component:
import React, { useMemo, useState } from "react";
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
const LoadModel = ({ url }) => {
const [obj, set] = useState();
// useMemo(() => new OBJLoader().load(url, set), [url])
useMemo(() => new OBJLoader().load(url, set), [url]);
//useMemo(() => new GLTFLoader().load(url, set), [url])
return obj ? <primitive object={obj} dispose={null} /> : null;
};
export default LoadModel;
You can improve the rendering of the SpongeBob model by adding a directional light to your scene. A single ambient light is not sufficient for proper illumination. Try adding the following line to your codesandbox:
<directionalLight />
The chair model has unfortunately some design issues. It has an extreme scale and is highly translated. I suggest you scale the model down and then center it after the loading process. However, it would be better to fix the model in a DCC tool like Blender and model the chair according to real world units.

I have a static image in a component, depending on the component where it is invoked, the image can be broken

I have this component called SearchBarScreen :
import React, { useEffect } from "react";
import "./index.scss";
export const SearchBarScreen = (props) => {
return (
<>
<img src="./assets/img/logo.png" className="nav_logo" alt="logo mercadolibre" />
</>
);
};
and my project has this structure:
depending on where I call this component, the image can be broken.
for example in the previous image it can be seen under the folder src/components/items/components, where it is called SearchBarScreen. For example, the image is shown broken on ItemDetailScreen but not on ItemScreen.
I always call it the same way in both components:
return (
<>
<SearchBarScreen props={props} />
</>
);
In ItemDetailScreen
In ItemDetailScreen
If you want the image loading to consistently work, you'll need to import the Image as if it was a component instead of the style you generally use with standard HTML.
Like so:
import React, { useEffect } from "react";
import Logo from '../path/to/image';
import "./index.scss";
export const SearchBarScreen = (props) => {
return (
<>
<img src={Logo} className="nav_logo" alt="logomercadolibre" />
</>
);
};
Edit:
If you absolutely have to use the public folder, which I don't recommend, here's how you do it: https://create-react-app.dev/docs/using-the-public-folder/
You'd basically make the path absolute instead of relative.
References:
https://create-react-app.dev/docs/adding-images-fonts-and-files/
cannot import image with create-react-app

Fetching data in other components with react hook

Im new to react hooks and are experimenting a bit. I can display my values that are generated in Provider.js in App.js through Comptest.js. My problem is that the structure of my project with css etc makes it inconvenient to have a structure in the App.js like this:
<Provider>
<Comptest />
</Provider>
is it possible to fetch the data without displaying the components in that way in the app? just passing it between the components.
Here is a compact version of my application:
App.js
import React, { useContext } from "react";
import Provider from "./Provider";
import Comptest from "./Comptest";
import DataContext from "./Context";
function App() {
return (
<div className="App">
<h2>My array!</h2>
<Provider>
<Comptest />
</Provider>
</div>
);
}
export default App;
Provider.js
import React, { useState } from "react";
import DataContext from "./Context";
const Provider = props => {
const data = ["item1", "item2"];
return (
<DataContext.Provider value={data}>{props.children}</DataContext.Provider>
);
};
export default Provider;
Comptest.js
import React from "react";
import DataContext from "./Context";
const Comptest = () => {
const content = React.useContext(DataContext);
console.log(content);
return <div>{(content)}</div>;
};
export default Comptest;
Context.js
import React from "react";
const DataContext = React.createContext([]);
export default DataContext;

Resources