door_models 5.3.2 → 5.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.js CHANGED
@@ -7,6 +7,7 @@ var jsxRuntime = require('react/jsx-runtime');
7
7
  var csg = require('@react-three/csg');
8
8
  var three = require('@react-spring/three');
9
9
  var THREE = require('three');
10
+ var drei = require('@react-three/drei');
10
11
 
11
12
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
12
13
 
@@ -803,20 +804,19 @@ new THREE__namespace.MeshStandardMaterial({
803
804
  roughness: 0.8
804
805
  });
805
806
 
806
- const textureLoader = new THREE__namespace.TextureLoader();
807
- textureLoader.setCrossOrigin("anonymous");
808
- const textureCache = {};
807
+ // Type definition for a material prop (string or object with opacity)
808
+
809
+ // Helper function to check for hex color codes
809
810
  const isHexColor = str => /^#([0-9A-F]{3}){1,2}$/i.test(str);
810
- const isUrl = str => str.startsWith("http") || str.startsWith("/");
811
- const getFirstValidValue = values => {
812
- for (const val of values) {
813
- if (val) {
814
- return val;
815
- }
816
- }
817
- return undefined;
818
- };
819
- const createDynamicMaterial = prop => {
811
+
812
+ /**
813
+ * A simple "builder" that creates a THREE.MeshStandardMaterial from a prop and an
814
+ * optional map of pre-loaded textures. It does NOT load textures itself.
815
+ * @param prop - The material definition (string or object).
816
+ * @param textures - A map of URL -> THREE.Texture, provided by useTexture.
817
+ * @returns A THREE.MeshStandardMaterial instance.
818
+ */
819
+ const buildMaterial = (prop, textures) => {
820
820
  if (!prop) {
821
821
  return new THREE__namespace.MeshStandardMaterial({
822
822
  color: "#cccccc",
@@ -830,12 +830,13 @@ const createDynamicMaterial = prop => {
830
830
  };
831
831
  if (isHexColor(sourceValue)) {
832
832
  params.color = sourceValue;
833
- } else if (isUrl(sourceValue)) {
834
- if (!textureCache[sourceValue]) {
835
- textureCache[sourceValue] = textureLoader.load(sourceValue);
836
- }
837
- params.map = textureCache[sourceValue];
838
- } else {
833
+ }
834
+ // Check if it's a URL and if it exists in the pre-loaded texture map
835
+ else if (textures && textures[sourceValue]) {
836
+ params.map = textures[sourceValue];
837
+ }
838
+ // Fallback for invalid values
839
+ else {
839
840
  params.color = "#cccccc";
840
841
  }
841
842
  if (opacity !== undefined && opacity < 1) {
@@ -845,45 +846,71 @@ const createDynamicMaterial = prop => {
845
846
  return new THREE__namespace.MeshStandardMaterial(params);
846
847
  };
847
848
 
848
- /**
849
- * A custom hook to generate memoized materials for the door model.
850
- * @param materialsProp - The materials object passed as props.
851
- * @returns An object containing all the necessary THREE.Material instances.
852
- */
849
+ // getFirstValidValue remains useful for fallbacks, so we keep it.
850
+ const getFirstValidValue = values => {
851
+ for (const val of values) {
852
+ if (val) {
853
+ return val;
854
+ }
855
+ }
856
+ return undefined;
857
+ };
858
+
859
+ // Re-export the type for easy access in other components
860
+
853
861
  const useDoorMaterials = function () {
854
862
  let materialsProp = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
855
- // --- Material Logic ---
863
+ // 1. Collect all unique texture URLs from the props.
864
+ const textureUrls = React.useMemo(() => {
865
+ const urls = new Set();
866
+ // Iterate over all passed material props
867
+ Object.values(materialsProp).forEach(prop => {
868
+ // Get the value, whether it's a string or inside an object
869
+ const value = typeof prop === "string" ? prop : prop === null || prop === void 0 ? void 0 : prop.value;
870
+ // If it's a valid URL, add it to our set to avoid duplicates
871
+ if (value && (value.startsWith("http") || value.startsWith("/"))) {
872
+ urls.add(value);
873
+ }
874
+ });
875
+ return Array.from(urls);
876
+ }, [materialsProp]);
856
877
 
857
- const doorMaterial = React.useMemo(() => createDynamicMaterial(materialsProp.Body), [materialsProp.Body]);
858
- const frameMaterial = React.useMemo(() => createDynamicMaterial(getFirstValidValue([materialsProp.D_PRF_COLOR, materialsProp.D_FR_SRF_DECOR, materialsProp.D_FR_SRF_DECOR_S2])), [materialsProp.D_PRF_COLOR, materialsProp.D_FR_SRF_DECOR, materialsProp.D_FR_SRF_DECOR_S2]);
859
- const gasketMaterial = React.useMemo(() => createDynamicMaterial(materialsProp.D_GASKET), [materialsProp.D_GASKET]);
860
- const doorStopMaterial = React.useMemo(() => createDynamicMaterial(getFirstValidValue([materialsProp.D_PRF_COLOR, materialsProp.D_FR_SRF_DECOR, materialsProp.D_FR_SRF_DECOR_S2])), [materialsProp.D_PRF_COLOR, materialsProp.D_FR_SRF_DECOR, materialsProp.D_FR_SRF_DECOR_S2]);
861
- const interiorFanlightMaterial = React.useMemo(() => createDynamicMaterial(materialsProp.D_SRF_DECOR), [materialsProp.D_SRF_DECOR]);
862
- const exteriorFanlightMaterial = React.useMemo(() => createDynamicMaterial(materialsProp.D_SRF_DECOR), [materialsProp.D_SRF_DECOR]);
863
- const occulusInfillMaterial = React.useMemo(() => createDynamicMaterial(materialsProp.D_FR_COLOR), [materialsProp.D_FR_COLOR]);
864
- const glassInfillMaterial = React.useMemo(() => createDynamicMaterial(materialsProp.D_FR_COLOR), [materialsProp.D_FR_COLOR]);
865
- const frontCoverPanelMaterial = React.useMemo(() => createDynamicMaterial(getFirstValidValue([materialsProp.D_PRF_COLOR, materialsProp.D_FR_SRF_DECOR, materialsProp.D_FR_SRF_DECOR_S2])), [materialsProp.D_PRF_COLOR, materialsProp.D_FR_SRF_DECOR, materialsProp.D_FR_SRF_DECOR_S2]);
866
- const backCoverPanelMaterial = React.useMemo(() => createDynamicMaterial(getFirstValidValue([materialsProp.D_PRF_COLOR, materialsProp.D_FR_SRF_DECOR, materialsProp.D_FR_SRF_DECOR_S2])), [materialsProp.D_PRF_COLOR, materialsProp.D_FR_SRF_DECOR, materialsProp.D_FR_SRF_DECOR_S2]);
867
- const frontDoorPlaneMaterial = React.useMemo(() => createDynamicMaterial(materialsProp.D_SRF_DECOR_2), [materialsProp.D_SRF_DECOR_2]);
868
- const backDoorPlaneMaterial = React.useMemo(() => createDynamicMaterial(materialsProp.D_SRF_DECOR), [materialsProp.D_SRF_DECOR]);
869
- const hingeBodyMaterial = React.useMemo(() => createDynamicMaterial(materialsProp.Hinge), [materialsProp.Hinge]);
870
- const hingeAccentMaterial = React.useMemo(() => createDynamicMaterial(materialsProp.HingeCuts), [materialsProp.HingeCuts]);
871
- return React.useMemo(() => ({
872
- doorMaterial,
873
- frameMaterial,
874
- gasketMaterial,
875
- doorStopMaterial,
876
- interiorFanlightMaterial,
877
- exteriorFanlightMaterial,
878
- occulusInfillMaterial,
879
- glassInfillMaterial,
880
- hingeBodyMaterial,
881
- frontCoverPanelMaterial,
882
- backCoverPanelMaterial,
883
- frontDoorPlaneMaterial,
884
- backDoorPlaneMaterial,
885
- hingeAccentMaterial
886
- }), [doorMaterial, frameMaterial, gasketMaterial, doorStopMaterial, interiorFanlightMaterial, exteriorFanlightMaterial, occulusInfillMaterial, glassInfillMaterial, hingeBodyMaterial, frontCoverPanelMaterial, backCoverPanelMaterial, frontDoorPlaneMaterial, backDoorPlaneMaterial, hingeAccentMaterial]);
878
+ // 2. Load all textures at once.
879
+ // !! THIS IS THE MAGIC !!
880
+ // `useTexture` will pause ("suspend") this component's rendering
881
+ // until all textures in the array are fully loaded.
882
+ const loadedTextures = drei.useTexture(textureUrls);
883
+
884
+ // 3. Create a map from URL back to the loaded THREE.Texture for easy lookup.
885
+ const textureMap = React.useMemo(() => {
886
+ const map = {};
887
+ textureUrls.forEach((url, index) => {
888
+ map[url] = loadedTextures[index];
889
+ });
890
+ return map;
891
+ }, [textureUrls, loadedTextures]);
892
+
893
+ // 4. Now that textures are guaranteed to be loaded, build all materials.
894
+ // This memo ensures the materials are only created when props or textures change.
895
+ return React.useMemo(() => {
896
+ const build = prop => buildMaterial(prop, textureMap);
897
+ return {
898
+ doorMaterial: build(materialsProp.Body),
899
+ frameMaterial: build(getFirstValidValue([materialsProp.D_PRF_COLOR, materialsProp.D_FR_SRF_DECOR, materialsProp.D_FR_SRF_DECOR_S2])),
900
+ gasketMaterial: build(materialsProp.D_GASKET),
901
+ doorStopMaterial: build(getFirstValidValue([materialsProp.D_PRF_COLOR, materialsProp.D_FR_SRF_DECOR, materialsProp.D_FR_SRF_DECOR_S2])),
902
+ interiorFanlightMaterial: build(materialsProp.D_SRF_DECOR),
903
+ exteriorFanlightMaterial: build(materialsProp.D_SRF_DECOR),
904
+ occulusInfillMaterial: build(materialsProp.D_FR_COLOR),
905
+ glassInfillMaterial: build(materialsProp.D_FR_COLOR),
906
+ frontCoverPanelMaterial: build(getFirstValidValue([materialsProp.D_PRF_COLOR, materialsProp.D_FR_SRF_DECOR, materialsProp.D_FR_SRF_DECOR_S2])),
907
+ backCoverPanelMaterial: build(getFirstValidValue([materialsProp.D_PRF_COLOR, materialsProp.D_FR_SRF_DECOR, materialsProp.D_FR_SRF_DECOR_S2])),
908
+ frontDoorPlaneMaterial: build(materialsProp.D_SRF_DECOR_2),
909
+ backDoorPlaneMaterial: build(materialsProp.D_SRF_DECOR),
910
+ hingeBodyMaterial: build(materialsProp.Hinge),
911
+ hingeAccentMaterial: build(materialsProp.HingeCuts)
912
+ };
913
+ }, [materialsProp, textureMap]);
887
914
  };
888
915
 
889
916
  function StandardHandle(_ref) {