diff --git a/core/stickernode.gd b/core/stickernode.gd index 34ba61f..583915e 100644 --- a/core/stickernode.gd +++ b/core/stickernode.gd @@ -38,6 +38,8 @@ var detected_solids:Array var detected_zones:Array var Grabbed:bool = false +## Emitted when the sticker overlap a blocking body, preventing to be spawned as an asset in the level. Usually received by the cursor to change his sprite +signal spawn_mode_changed(can_spawn:bool) #region Functions func _get_configuration_warnings(): if (get_parent() == get_tree().get_edited_scene_root()): @@ -75,17 +77,19 @@ func _ready(): area_exited.connect(_on_area_exited) body_entered.connect(_on_body_entered) body_exited.connect(_on_body_exited) + # TODO : Solids and interactive zone detection area should not be the same as the sticker area. # IDEA: Need to export a child Area2D func _on_body_entered(body:Node2D): print("body entered",body) detected_solids.append(body) + spawn_mode_changed.emit(false) func _on_body_exited(body:Node2D): print("body exited",body) detected_solids.erase(body) - if(Sticker_mode and Grabbed and detected_solids.size() == 0): - print("Can be released in object mode") + if(Sticker_mode and Grabbed and detected_solids.size() == 0 ): + spawn_mode_changed.emit(true) func _on_area_entered(area:Area2D): print("area entered",area) #TODO:Filter by type diff --git a/shaders/pageflip.gdshader b/shaders/pageflip.gdshader new file mode 100644 index 0000000..d0bf928 --- /dev/null +++ b/shaders/pageflip.gdshader @@ -0,0 +1,142 @@ +shader_type canvas_item; +uniform vec2 scale = vec2(1,1); +uniform vec2 flip_pos = vec2(-1.,-1.); + +vec2 Line2point(vec2 linePoint,vec2 lineDire,vec2 point) { + lineDire = normalize(lineDire); + vec2 line2Ori = - linePoint - dot(-linePoint,lineDire)*lineDire; + vec2 p2Ori = - point - dot(-point,lineDire)*lineDire; + return line2Ori-p2Ori; + } +vec4 ColorWithA(vec4 oldCol,vec4 newCol){ + vec4 finalCol; + if((newCol.a + oldCol.a)>=1.) + { + finalCol.rgb = newCol.rgb ; + finalCol.a =1.0; + } + else{ + finalCol.rgb = newCol.a/(newCol.a + oldCol.a)*newCol.rgb + oldCol.a/(newCol.a + oldCol.a)*oldCol.rgb; + finalCol.a = oldCol.a +newCol.a; + } + return finalCol; + } + +void fragment() { + vec2 uv = UV; +// vec2 mouse_uv = flip_pos ; + vec4 finalColor = vec4(0.0); // Initialize with transparent color + //拉伸变形校正 + float scale_min = scale.x/scale.y; + vec2 uv_max = vec2(scale_min,1.); + float trueScale; + if(scale.y-0.0001) + { + vec2 left_bottom = vec2(0.,uv_max.y/TEXTURE_PIXEL_SIZE.y * trueScale); + vec2 midpoint = (flip_pos - left_bottom)/2. + left_bottom; +// vec2 midDirect = vec2(-1.,-1.)/1.414; + vec2 midDirect = normalize(vec2(-(flip_pos-left_bottom).y,(flip_pos-left_bottom).x)); + //bg + + //pageback + vec2 sharpPoint = vec2(0.,midpoint.y - midDirect.y/midDirect.x * midpoint.x); + vec2 flipEdgeDire = normalize(sharpPoint - flip_pos); + //pagebackBottom + vec2 sharpPointB = vec2(midpoint.x-midDirect.x/midDirect.y * (midpoint-left_bottom).y,left_bottom.y); + vec2 flipEdgeDireB = normalize(sharpPointB - flip_pos); + + //圆柱 + float cyOriOff = length(flip_pos-left_bottom); + if (cyOriOff>100.) cyOriOff = 100.;//圆柱向里面缩进 + float cyR = cyOriOff*2./PI; + float pageHDire = PI/6.; + vec2 midlineToP = Line2point(midpoint,midDirect,pPos); + vec2 sideEdgeToP = Line2point(flip_pos,flipEdgeDire,pPos); + vec2 BottomEdgeToP = Line2point(flip_pos,flipEdgeDireB,pPos); + + vec2 cyOriToP = midlineToP - normalize(flip_pos- left_bottom)*cyOriOff; + vec2 cyEdgeToP = midlineToP - normalize(flip_pos- left_bottom)*(cyOriOff-cyR); + + bool atBG = (cyOriToP).x<=-0.01; + bool atPageBack = !atBG&&(sideEdgeToP.y>0.)&&(BottomEdgeToP.x<=0.); +// bool atCy = (cyOriToP).x<=0.; + bool atCy = cyEdgeToP.x >=0. && (cyOriToP).x<=0.; + bool atCyPage = false; + vec2 uvCy ; + vec2 uvCyB ; + + + float shadow = 1.; + if (atCy){ + vec2 cyOri = pPos-cyOriToP; + vec2 trueDis = cyR* asin(length(cyOriToP)/cyR)*normalize(cyOriToP); + vec2 truePos = cyOri+trueDis; + + vec2 sideEdgeToTP = Line2point(flip_pos,flipEdgeDire,truePos); + vec2 BottomEdgeToTP = Line2point(flip_pos,flipEdgeDireB,truePos); + uvCyB = truePos * TEXTURE_PIXEL_SIZE /trueScale; + shadow *= 1.-pow(length(trueDis)/(cyR*PI/2.),3.); + + if ((BottomEdgeToTP.x<0.)&& (sideEdgeToTP.y>0.)) + { + atCyPage = true; + uvCy = vec2(length(sideEdgeToTP),left_bottom.y-length(BottomEdgeToTP))*TEXTURE_PIXEL_SIZE /trueScale; + } + + if ((uvCyB.x > uv_max.x)||(uvCyB.y > uv_max.y)||(uvCyB.x <= 0.)|| (uvCyB.y <= 0.)) + atCy =false; + } + + + //色彩 + COLOR = vec4(0.); + // Page + if (!atBG && !atCy) { + vec4 color = texture(TEXTURE, uv); + finalColor = color; + } + + // cyBottom + if (atCy) { + vec4 cyColor = texture(TEXTURE, uvCyB); + finalColor = cyColor; + } + + if (atCyPage) { + vec4 cyPageColor = texture(TEXTURE, uvCy); + cyPageColor.xyz *= 0.8; + // Blend based on the alpha value of cyPageColor + finalColor = mix(finalColor, cyPageColor, cyPageColor.a); + } else if (atPageBack) { + uv = vec2(length(sideEdgeToP), left_bottom.y - length(BottomEdgeToP)) * TEXTURE_PIXEL_SIZE / trueScale; + vec4 pageBackColor = texture(TEXTURE, uv); + pageBackColor.xyz *= 0.8; + // Blend based on the alpha value of pageBackColor + finalColor = mix(finalColor, pageBackColor, pageBackColor.a); + } + + COLOR = finalColor; +} + + // Place fragment code here. + +// FRAGCOORD.xy; +} \ No newline at end of file