door_models 5.3.1 → 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,19 +804,19 @@ new THREE__namespace.MeshStandardMaterial({
803
804
  roughness: 0.8
804
805
  });
805
806
 
806
- const textureLoader = new THREE__namespace.TextureLoader();
807
- const textureCache = {};
807
+ // Type definition for a material prop (string or object with opacity)
808
+
809
+ // Helper function to check for hex color codes
808
810
  const isHexColor = str => /^#([0-9A-F]{3}){1,2}$/i.test(str);
809
- const isUrl = str => str.startsWith("http") || str.startsWith("/");
810
- const getFirstValidValue = values => {
811
- for (const val of values) {
812
- if (val) {
813
- return val;
814
- }
815
- }
816
- return undefined;
817
- };
818
- 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) => {
819
820
  if (!prop) {
820
821
  return new THREE__namespace.MeshStandardMaterial({
821
822
  color: "#cccccc",
@@ -829,12 +830,13 @@ const createDynamicMaterial = prop => {
829
830
  };
830
831
  if (isHexColor(sourceValue)) {
831
832
  params.color = sourceValue;
832
- } else if (isUrl(sourceValue)) {
833
- if (!textureCache[sourceValue]) {
834
- textureCache[sourceValue] = textureLoader.load(sourceValue);
835
- }
836
- params.map = textureCache[sourceValue];
837
- } 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 {
838
840
  params.color = "#cccccc";
839
841
  }
840
842
  if (opacity !== undefined && opacity < 1) {
@@ -844,45 +846,71 @@ const createDynamicMaterial = prop => {
844
846
  return new THREE__namespace.MeshStandardMaterial(params);
845
847
  };
846
848
 
847
- /**
848
- * A custom hook to generate memoized materials for the door model.
849
- * @param materialsProp - The materials object passed as props.
850
- * @returns An object containing all the necessary THREE.Material instances.
851
- */
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
+
852
861
  const useDoorMaterials = function () {
853
862
  let materialsProp = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
854
- // --- 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]);
855
877
 
856
- const doorMaterial = React.useMemo(() => createDynamicMaterial(materialsProp.Body), [materialsProp.Body]);
857
- 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]);
858
- const gasketMaterial = React.useMemo(() => createDynamicMaterial(materialsProp.D_GASKET), [materialsProp.D_GASKET]);
859
- 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]);
860
- const interiorFanlightMaterial = React.useMemo(() => createDynamicMaterial(materialsProp.D_SRF_DECOR), [materialsProp.D_SRF_DECOR]);
861
- const exteriorFanlightMaterial = React.useMemo(() => createDynamicMaterial(materialsProp.D_SRF_DECOR), [materialsProp.D_SRF_DECOR]);
862
- const occulusInfillMaterial = React.useMemo(() => createDynamicMaterial(materialsProp.D_FR_COLOR), [materialsProp.D_FR_COLOR]);
863
- const glassInfillMaterial = React.useMemo(() => createDynamicMaterial(materialsProp.D_FR_COLOR), [materialsProp.D_FR_COLOR]);
864
- 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]);
865
- 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]);
866
- const frontDoorPlaneMaterial = React.useMemo(() => createDynamicMaterial(materialsProp.D_SRF_DECOR_2), [materialsProp.D_SRF_DECOR_2]);
867
- const backDoorPlaneMaterial = React.useMemo(() => createDynamicMaterial(materialsProp.D_SRF_DECOR), [materialsProp.D_SRF_DECOR]);
868
- const hingeBodyMaterial = React.useMemo(() => createDynamicMaterial(materialsProp.Hinge), [materialsProp.Hinge]);
869
- const hingeAccentMaterial = React.useMemo(() => createDynamicMaterial(materialsProp.HingeCuts), [materialsProp.HingeCuts]);
870
- return React.useMemo(() => ({
871
- doorMaterial,
872
- frameMaterial,
873
- gasketMaterial,
874
- doorStopMaterial,
875
- interiorFanlightMaterial,
876
- exteriorFanlightMaterial,
877
- occulusInfillMaterial,
878
- glassInfillMaterial,
879
- hingeBodyMaterial,
880
- frontCoverPanelMaterial,
881
- backCoverPanelMaterial,
882
- frontDoorPlaneMaterial,
883
- backDoorPlaneMaterial,
884
- hingeAccentMaterial
885
- }), [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]);
886
914
  };
887
915
 
888
916
  function StandardHandle(_ref) {