我的问题是如何在expo three.js中使用.mtl和.obj文件,但是我不想使用AR,我只想使用旋转对象的简单画布/视图。 这段代码是我想要的,但是要使用我的obj文件,而不是创建多维数据集。
import { View as GraphicsView } from 'expo-graphics';
import ExpoTHREE, { THREE } from 'expo-three';
import React from 'react';
import Assets from './Assets.js';
import ThreeStage from './ThreeStage.js';
export default class App extends React.Component {
componentWillMount() {
THREE.suppressExpoWarnings();
}
render() {
return (
<GraphicsView
onContextCreate={this.onContextCreate}
onRender={this.onRender}
/>
);
}
async setupModels() {
await super.setupModels();
const model = Assets.models.obj.ninja;
const SCALE = 2.436143; // from original model
const BIAS = -0.428408; // from original model
const object = await ExpoTHREE.loadObjAsync({
asset: require('ninja.obj'),
});
const materialStandard = new THREE.MeshStandardMaterial({
color: 0xffffff,
metalness: 0.5,
roughness: 0.6,
displacementScale: SCALE,
displacementBias: BIAS,
normalScale: new THREE.Vector2(1, -1),
//flatShading: true,
side: THREE.DoubleSide,
});
const geometry = object.children[0].geometry;
geometry.attributes.uv2 = geometry.attributes.uv;
geometry.center();
const mesh = new THREE.Mesh(geometry, materialStandard);
mesh.scale.multiplyScalar(0.25);
ExpoTHREE.utils.scaleLongestSideToSize(mesh, 1);
ExpoTHREE.utils.alignMesh(mesh, { y: 1 });
this.scene.add(mesh);
this.mesh = mesh;
}
onRender(delta) {
super.onRender(delta);
this.mesh.rotation.y += 0.5 * delta;
}
}
我的assets.js文件,其中包含.obj中我的3D模态的路径
export default {
obj: {
"museu.obj": require('../Conteudos_AV/museu1.obj'),
}
};
还有我的threeStage.js文件,其中包含3DModal.js的导入
import ExpoTHREE, { THREE } from 'expo-three';
class ThreeStage {
constructor() {
this.onRender = this.onRender.bind(this);
this.setupControls = this.setupControls.bind(this);
this.onResize = this.onResize.bind(this);
this.setupCamera = this.setupCamera.bind(this);
this.setupScene = this.setupScene.bind(this);
}
onContextCreate = async ({
gl,
canvas,
width,
height,
scale: pixelRatio,
}) => {
this.gl = gl;
this.canvas = canvas;
this.width = width;
this.height = height;
this.pixelRatio = pixelRatio;
await this.setupAsync();
};
setupAsync = async () => {
const { gl, canvas, width, height, pixelRatio } = this;
await this.setupRenderer({ gl, canvas, width, height, pixelRatio });
await this.setupScene();
await this.setupCamera({ width, height });
await this.setupLights();
await this.setupModels();
await this.setupControls();
};
setupControls() {
new THREE.OrbitControls(this.camera);
}
setupRenderer = props => {
this.renderer = new ExpoTHREE.Renderer(props);
this.renderer.capabilities.maxVertexUniforms = 52502;
};
setupCamera({ width, height }) {
this.camera = new THREE.PerspectiveCamera(50, width / height, 0.1, 10000);
this.camera.position.set(0, 6, 12);
this.camera.lookAt(0, 0, 0);
}
setupScene() {
this.scene = new THREE.Scene();
this.scene.background = new THREE.Color(0x999999);
this.scene.fog = new THREE.FogExp2(0xcccccc, 0.002);
this.scene.add(new THREE.GridHelper(50, 50, 0xffffff, 0x555555));
}
setupLights = () => {
const directionalLightA = new THREE.DirectionalLight(0xffffff);
directionalLightA.position.set(1, 1, 1);
this.scene.add(directionalLightA);
const directionalLightB = new THREE.DirectionalLight(0xffeedd);
directionalLightB.position.set(-1, -1, -1);
this.scene.add(directionalLightB);
const ambientLight = new THREE.AmbientLight(0x222222);
this.scene.add(ambientLight);
};
async setupModels() {}
onResize({ width, height, scale }) {
this.camera.aspect = width / height;
this.camera.updateProjectionMatrix();
this.renderer.setPixelRatio(scale);
this.renderer.setSize(width, height);
this.width = width;
this.height = height;
this.pixelRatio = scale;
}
onRender(delta) {
this.renderer.render(this.scene, this.camera);
}
}
export default ThreeStage;
答案 0 :(得分:1)
所提供的代码似乎创建了一个ThreeStage类,该类已导入,但从未被包含Expo GraphicsView的类使用。
回购中为第3个博览会提供的示例使用了一些深奥的结构,因为它们分别是通过具有集中式资产库和抽象组件的react-navigation应用程序提供的。对于仅尝试在屏幕上显示模型的简单应用程序来说,这是很多额外的功能。
import React from 'react';
import ExpoTHREE, { THREE } from 'expo-three';
import { GraphicsView } from 'expo-graphics';
export default class App extends React.Component {
componentDidMount() {
THREE.suppressExpoWarnings();
}
render() {
return (
<GraphicsView
onContextCreate={this.onContextCreate}
onRender={this.onRender}
onResize={this.onResize}
/>
);
}
// When our context is built we can start coding 3D things.
onContextCreate = async ({ gl, pixelRatio, width, height }) => {
// Create a 3D renderer
this.renderer = new ExpoTHREE.Renderer({
gl,
pixelRatio,
width,
height,
});
// We will add all of our meshes to this scene.
this.scene = new THREE.Scene();
this.scene.background = new THREE.Color(0xbebebe)
this.camera = new THREE.PerspectiveCamera(45, width/height, 1, 1000)
this.camera.position.set(3, 3, 3);
this.camera.lookAt(0, 0, 0);
this.scene.add(new THREE.AmbientLight(0xffffff));
await this.loadModel();
};
loadModel = async () => {
const obj = {
"museu.obj": require('../Conteudos_AV/museu1.obj')
}
const model = await ExpoTHREE.loadAsync(
obj['museu.obj'],
null,
obj
);
// this ensures the model will be small enough to be viewed properly
ExpoTHREE.utils.scaleLongestSideToSize(model, 1);
this.scene.add(model)
};
// When the phone rotates, or the view changes size, this method will be called.
onResize = ({ x, y, scale, width, height }) => {
// Let's stop the function if we haven't setup our scene yet
if (!this.renderer) {
return;
}
this.camera.aspect = width / height;
this.camera.updateProjectionMatrix();
this.renderer.setPixelRatio(scale);
this.renderer.setSize(width, height);
};
// Called every frame.
onRender = delta => {
// Finally render the scene with the Camera
this.renderer.render(this.scene, this.camera);
};
}
我从Evan的一个博览会小吃示例中改编了此代码,由于它们没有占用整个示例应用程序的大量开销,因此易于遵循。您可以在他的博览会小吃页面上找到更多信息:https://expo.io/snacks/@bacon。
此代码应呈现您的目标文件,但是如果您的.obj依赖于其他材质或纹理文件,则可能会遇到问题。在这种情况下,您需要像这样将它们添加到loadModel函数中:
const obj = {
"museu.obj": require('../Conteudos_AV/museu1.obj'),
"museu.mtl": require('../Conteudos_AV/museu1.mtl'),
"museu.png": require('../Conteudos_AV/museu1.png'),
}
const model = await ExpoTHREE.loadAsync(
[obj['museu.obj'], obj['museu.mtl']],
null,
obj
);
我建议您在入门时先看一下使用expo-3而不是示例应用程序的expo快餐,因为处理示例中的所有复杂内容可能有点儿困惑。 / p>
我目前没有用于测试的设备,但是如果您对上述代码有任何疑问,请告诉我,当我回到手机和笔记本电脑旁边时,我可以进行故障排除。