pmndrs / gltfjsx

🎮 Turns GLTFs into JSX components
https://gltf.pmnd.rs
MIT License
4.41k stars 290 forks source link

TypeError: objectInfluences is undefined #238

Closed justindhillon closed 6 months ago

justindhillon commented 6 months ago

I am using nextjs with typescript, gltfjsx, and @react-three/fiber. And I am getting this error "TypeError: objectInfluences is undefined".

Here is what gltfjsx generates:

/*
Auto-generated by: https://github.com/pmndrs/gltfjsx
Command: npx gltfjsx@6.2.15 public/Justin.glb -t 
*/

import * as THREE from 'three'
import React, { useRef } from 'react'
import { useGLTF } from '@react-three/drei'
import { GLTF } from 'three-stdlib'

type GLTFResult = GLTF & {
  nodes: {
    Wolf3D_Hair: THREE.SkinnedMesh
    Wolf3D_Body: THREE.SkinnedMesh
    Wolf3D_Outfit_Bottom: THREE.SkinnedMesh
    Wolf3D_Outfit_Footwear: THREE.SkinnedMesh
    Wolf3D_Outfit_Top: THREE.SkinnedMesh
    EyeLeft: THREE.SkinnedMesh
    EyeRight: THREE.SkinnedMesh
    Wolf3D_Head: THREE.SkinnedMesh
    Wolf3D_Teeth: THREE.SkinnedMesh
    Hips: THREE.Bone
  }
  materials: {
    Wolf3D_Hair: THREE.MeshStandardMaterial
    Wolf3D_Body: THREE.MeshStandardMaterial
    Wolf3D_Outfit_Bottom: THREE.MeshStandardMaterial
    Wolf3D_Outfit_Footwear: THREE.MeshStandardMaterial
    Wolf3D_Outfit_Top: THREE.MeshStandardMaterial
    Wolf3D_Eye: THREE.MeshStandardMaterial
    Wolf3D_Skin: THREE.MeshStandardMaterial
    Wolf3D_Teeth: THREE.MeshStandardMaterial
  }
}

type ContextType = Record<string, React.ForwardRefExoticComponent<JSX.IntrinsicElements['skinnedMesh'] | JSX.IntrinsicElements['bone']>>

export default function Justin(props: JSX.IntrinsicElements['group']) {
  const { nodes, materials } = useGLTF('/Justin.glb') as GLTFResult
  return (
    <group {...props} dispose={null}>
      <primitive object={nodes.Hips} />
      <skinnedMesh geometry={nodes.Wolf3D_Hair.geometry} material={materials.Wolf3D_Hair} skeleton={nodes.Wolf3D_Hair.skeleton} />
      <skinnedMesh geometry={nodes.Wolf3D_Body.geometry} material={materials.Wolf3D_Body} skeleton={nodes.Wolf3D_Body.skeleton} />
      <skinnedMesh geometry={nodes.Wolf3D_Outfit_Bottom.geometry} material={materials.Wolf3D_Outfit_Bottom} skeleton={nodes.Wolf3D_Outfit_Bottom.skeleton} />
      <skinnedMesh geometry={nodes.Wolf3D_Outfit_Footwear.geometry} material={materials.Wolf3D_Outfit_Footwear} skeleton={nodes.Wolf3D_Outfit_Footwear.skeleton} />
      <skinnedMesh geometry={nodes.Wolf3D_Outfit_Top.geometry} material={materials.Wolf3D_Outfit_Top} skeleton={nodes.Wolf3D_Outfit_Top.skeleton} />
      <skinnedMesh geometry={nodes.EyeLeft.geometry} material={materials.Wolf3D_Eye} skeleton={nodes.EyeLeft.skeleton} />
      <skinnedMesh geometry={nodes.EyeRight.geometry} material={materials.Wolf3D_Eye} skeleton={nodes.EyeRight.skeleton} />
      <skinnedMesh geometry={nodes.Wolf3D_Head.geometry} material={materials.Wolf3D_Skin} skeleton={nodes.Wolf3D_Head.skeleton} />
      <skinnedMesh geometry={nodes.Wolf3D_Teeth.geometry} material={materials.Wolf3D_Teeth} skeleton={nodes.Wolf3D_Teeth.skeleton} />
    </group>
  )
}

useGLTF.preload('/Justin.glb')

Here is how I am using it:

"use client"
import { Suspense, useState } from "react";
import emailjs from '@emailjs/browser';
import { Canvas } from "@react-three/fiber";

import Justin from "./Justin";

export default function Contact() {
    const [form, setForm] = useState({ name: '', email: '', message: '' });
    const [isLoading, setIsLoading] = useState(false);

    const handleChange = (e: any) => {
        setForm({ ...form, [e.target.name]: e.target.value });
    }

    const handleSubmit = (e: any) => {
        e.preventDefault();
        setIsLoading(true);

        emailjs.send(
            process.env.EMAILJS_SERVICE_ID,
            process.env.EMAILJS_TEMPLATE_ID,
            {
                from_name: form.name,
                to_name: "Justin Dhillon",
                from_email: form.email,
                to_email: 'justin.singh.dhillon@gmail.com',
                message: form.message,
            },
            process.env.EMAILJS_PUBLIC_KEY,
        ).then(() => {
            setIsLoading(false);
            // TODO Alert
        }).catch((err: any) => {
            // TODO Alert
            console.log(err)
        })
    }

    return (
        <section className="flex lg:flex-row flex-col max-container bg-slate-50 p-8">
            <div className="flex-1 min-w-[50%] flex flex-col">
                <h1 className="text-4xl font-bold">Get in Touch</h1>
                <form className="w-full flex flex-col gap-4 mt-10" onSubmit={handleSubmit}>
                    <label className="text-xl text-black-500 font-medium" htmlFor="name">Name</label>
                    <input
                        type="text"
                        name="name"
                        id="name"
                        className="shadow appearance-none border rounded w-full p-2"
                        placeholder="Your Name"
                        required
                        value={form.name}
                        onChange={handleChange}
                        autoComplete="name"
                    />
                    <label className="text-xl text-black-500 font-medium" htmlFor="email">Email</label>
                    <input
                        type="email"
                        name="email"
                        id="email"
                        className="shadow appearance-none border rounded w-full p-2"
                        placeholder="example@gmail.com"
                        required
                        value={form.email}
                        onChange={handleChange}
                        autoComplete="email"
                    />
                    <label className="text-xl text-black-500 font-medium" htmlFor="message">Message</label>
                    <textarea
                        name="message"
                        id="message"
                        rows={4}
                        className="shadow appearance-none border rounded w-full p-2"
                        placeholder="What do you want me to know?"
                        required
                        value={form.message}
                        onChange={handleChange}
                    />
                    <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold p-2 rounded mt-10" type="submit">
                        {isLoading ? 'Sending...' : 'Send Message'}
                    </button>
                </form>
            </div>
            <div className="lg:w-1/2 w-full lg:h-auto md:h-[550px] h-[350px]">
                <Canvas camera={{
                    position: [0, 1, 2]
                }}>
                    <Suspense fallback={null}>
                        <Justin 
                            position={[0, -1, 0]}
                            rotation={[0, -0.6, 0]}
                        />
                        <directionalLight intensity={2.5} position={[0, 0, 1]} />
                    </Suspense>
                </Canvas>
            </div>
        </section>
    )
}
justindhillon commented 6 months ago

I solved the issue by turning props: JSX.IntrinsicElements['group'] into props: any

If we want total typescript support, we should document why this happens and how to solve it.

KhayKhun commented 3 months ago

Do you have any idea for js? I got the same error but I'm not using typescript.

justindhillon commented 3 months ago

Do you any idea for js? I got the same error but I'm not using typescript.

What does your code look like?

KhayKhun commented 3 months ago

Do you any idea for js? I got the same error but I'm not using typescript.

What does your code look like?

https://github.com/pmndrs/gltfjsx/issues/249

justindhillon commented 3 months ago

I created a quick demo to solve your issue here: https://github.com/pmndrs/gltfjsx/issues/249#issuecomment-1987747199