1- import React , { useMemo } from "react" ;
1+ import React from "react" ;
22import { Config } from "../config" ;
33import { HOVER_OBJECT_MODES , RenderOrder } from "../constants" ;
44import { Billboard , Plane , Sphere , useTexture } from "@react-three/drei" ;
5- import { Vector3 , Mesh , Group as GroupType , Color } from "three" ;
5+ import {
6+ Vector3 ,
7+ Mesh ,
8+ Group as GroupType ,
9+ Color ,
10+ WebGLProgramParametersWithUniforms ,
11+ } from "three" ;
612import {
713 getGardenPositionFunc ,
814 threeSpace ,
@@ -119,40 +125,33 @@ interface PlantPartProps extends CustomImageProps {
119125
120126const PlantPart = ( props : PlantPartProps ) => {
121127 const { config } = props ;
122- const boundsCenter = useMemo ( ( ) =>
123- new Vector3 (
124- 0 ,
125- 0 ,
126- - 10000 + zZero ( config ) ,
127- // eslint-disable-next-line react-hooks/exhaustive-deps
128- ) , [ ] ) ;
129- const halfSize = useMemo ( ( ) => new Vector3 (
130- config . bedLengthOuter / 2 - 300 ,
131- config . bedWidthOuter / 2 - config . bedWallThickness ,
132- 10000 ,
133- // eslint-disable-next-line react-hooks/exhaustive-deps
134- ) , [ ] ) ;
128+ // eslint-disable-next-line react-hooks/exhaustive-deps
129+ const boundsCenter = React . useMemo ( getBoundsCenter ( config ) , [ ] ) ;
130+ // eslint-disable-next-line react-hooks/exhaustive-deps
131+ const halfSize = React . useMemo ( getHalfSize ( config ) , [ ] ) ;
135132 const spreadRadii = getSpreadRadii ( {
136133 activeDragSpread : findCrop ( Path . getCropSlug ( ) ) . spread ,
137134 inactiveSpread : props . plant . spread ,
138135 radius : props . plant . size / 2 ,
139136 } ) ;
140- const worldPos = props . activePositionRef . current || { x : - 10000 , y : - 10000 } ;
141- const active = getGardenPositionFunc ( config ) ( worldPos ) ;
142- const overlap = getSpreadOverlap ( {
143- spreadRadii,
144- activeDragXY : {
145- x : round ( active . x + config . bedXOffset ) ,
146- y : round ( active . y + config . bedYOffset ) ,
147- z : 0 ,
148- } ,
149- plantXY : { x : round ( props . plant . x ) , y : round ( props . plant . y ) , z : 0 } ,
137+
138+ const rgb = React . useMemo ( ( ) => ( { value : [ 0 , 1 , 0 ] } ) , [ ] ) ;
139+ useFrame ( ( ) => {
140+ const worldPos = props . activePositionRef . current || { x : - 10000 , y : - 10000 } ;
141+ const active = getGardenPositionFunc ( config ) ( worldPos ) ;
142+ const overlap = getSpreadOverlap ( {
143+ spreadRadii,
144+ activeDragXY : {
145+ x : round ( active . x + config . bedXOffset ) ,
146+ y : round ( active . y + config . bedYOffset ) ,
147+ z : 0 ,
148+ } ,
149+ plantXY : { x : round ( props . plant . x ) , y : round ( props . plant . y ) , z : 0 } ,
150+ } ) ;
151+ const color = props . plant . id ? overlap . color . rgb : [ 1 , 1 , 1 ] ;
152+ rgb . value = getMode ( ) == Mode . clickToAdd ? color : [ 0 , 1 , 0 ] ;
150153 } ) ;
151- const rgb = useMemo ( ( ) => ( { value : [ 0 , 1 , 0 ] } ) , [ ] ) ;
152- const mode = getMode ( ) ;
153- React . useEffect ( ( ) => {
154- rgb . value = mode == Mode . clickToAdd ? overlap . color . rgb : [ 0 , 1 , 0 ] ;
155- } , [ rgb , overlap . color . rgb , mode ] ) ;
154+
156155 return < Group >
157156 < Image { ...props } />
158157 { props . spreadVisible &&
@@ -166,39 +165,57 @@ const PlantPart = (props: PlantPartProps) => {
166165 shader . uniforms . uHalfSize = { value : halfSize } ;
167166 shader . uniforms . uInside = rgb ;
168167 shader . uniforms . uOutside = { value : new Color ( "red" ) } ;
169- shader . vertexShader = shader . vertexShader . replace (
170- "#include <common>" ,
171- `#include <common>
172- varying vec3 vWorldPosition;` ,
173- ) . replace (
174- "#include <worldpos_vertex>" ,
175- `#include <worldpos_vertex>
176- vWorldPosition = worldPosition.xyz;` ) ;
177- shader . fragmentShader = shader . fragmentShader . replace (
178- "#include <common>" ,
179- `#include <common>
180- varying vec3 vWorldPosition;
181- uniform vec3 uBoundsCenter;
182- uniform vec3 uHalfSize;
183- uniform vec3 uInside;
184- uniform vec3 uOutside;` ,
185- ) . replace (
186- "#include <color_fragment>" ,
187- `#include <color_fragment>
188- vec3 p = vWorldPosition - uBoundsCenter;
189- bool inside =
190- p.x > -uHalfSize.x &&
191- abs(p.y) <= uHalfSize.y &&
192- abs(p.z) <= uHalfSize.z;
193- diffuseColor.rgb = mix(uOutside, uInside, float(inside));
194- ` ,
195- ) ;
168+ outOfBoundsShaderModification ( shader ) ;
196169 } }
197170 depthWrite = { false } />
198171 </ Sphere > }
199172 </ Group > ;
200173} ;
201174
175+ export const getBoundsCenter = ( config : Config ) => ( ) =>
176+ new Vector3 (
177+ 0 ,
178+ 0 ,
179+ - 10000 + zZero ( config ) ,
180+ ) ;
181+
182+ export const getHalfSize = ( config : Config ) => ( ) => new Vector3 (
183+ config . bedLengthOuter / 2 - 300 ,
184+ config . bedWidthOuter / 2 - config . bedWallThickness ,
185+ 10000 ,
186+ ) ;
187+
188+ export const outOfBoundsShaderModification =
189+ ( shader : WebGLProgramParametersWithUniforms ) => {
190+ shader . vertexShader = shader . vertexShader . replace (
191+ "#include <common>" ,
192+ `#include <common>
193+ varying vec3 vWorldPosition;` ,
194+ ) . replace (
195+ "#include <worldpos_vertex>" ,
196+ `#include <worldpos_vertex>
197+ vWorldPosition = worldPosition.xyz;` ) ;
198+ shader . fragmentShader = shader . fragmentShader . replace (
199+ "#include <common>" ,
200+ `#include <common>
201+ varying vec3 vWorldPosition;
202+ uniform vec3 uBoundsCenter;
203+ uniform vec3 uHalfSize;
204+ uniform vec3 uInside;
205+ uniform vec3 uOutside;` ,
206+ ) . replace (
207+ "#include <color_fragment>" ,
208+ `#include <color_fragment>
209+ vec3 p = vWorldPosition - uBoundsCenter;
210+ bool inside =
211+ p.x > -uHalfSize.x &&
212+ abs(p.y) <= uHalfSize.y &&
213+ abs(p.z) <= uHalfSize.z;
214+ diffuseColor.rgb = mix(uOutside, uInside, float(inside));
215+ ` ,
216+ ) ;
217+ } ;
218+
202219type MeshProps = ThreeElements [ "mesh" ] ;
203220interface CustomImageProps extends MeshProps {
204221 url : string ;
0 commit comments