#flythrough.rb
#Auther :TAK2HATA
#version1.3
#Update Feb 28,2014.
#site: http://sketchup-onigiri.jimdo.com/
###日本語
#General disclaimer
#I MAKES NO GUARANTEE OF VALIDITY about this script.
#Please use this script at your own risk.
##免責事項
##このスクリプトによって如何なる損害が発生しても製作者は責任を負いません。各人の責任においてご使用ください。
#
require "sketchup.rb"
class TAK_FlyThrough
	class TAK_view_animation
		@@psec = 0.to_f
		def initialize( flylength,shift,keypress,tarmvec,psec = false)
			@flylength1 = flylength
			@flylength1 = @flylength1 * 3 if shift == true
			@upkey1 = keypress["UP"]
			@downkey1 = keypress["DOWN"]
			@rightkey1 = keypress["RIGHT"]
			@leftkey1 =keypress["LEFT"]
			@homekey1 =keypress["HOME"]
			@endkey1 =keypress["END"]
			@tar_mvec = tarmvec
			@@psec = 0.to_f if psec == true
		end
		def nextFrame(view)
			camera = view.camera
			cdir = camera.direction.normalize
			up = camera.up.normalize
			mvec = Geom::Vector3d.new(0,0,0)
			csec = Time.now.to_f
			@@psec = csec - 0.1 if @@psec == 0.to_f
			flylength1 = @flylength1 * ( csec - @@psec ) * 10
			cdir.length = flylength1 
			zvec = Geom::Vector3d.new(0,0,1)
			zvec.length = flylength1 / 2.0
			sidevec = cdir.cross( up )
			sidevec.length = flylength1 if sidevec != Geom::Vector3d.new(0,0,0)
			if @upkey1 == true
				mvec = mvec + cdir
			end
			if @downkey1 == true
				mvec = mvec + cdir.reverse
			end
			if @leftkey1 == true
				mvec = mvec + sidevec.reverse
			end
			if @rightkey1 == true
				mvec = mvec + sidevec
			end
			if @homekey1 == true
				mvec = mvec + zvec
			end
			if @endkey1 == true
				mvec = mvec + zvec.reverse
			end
			return if mvec == Geom::Vector3d.new(0,0,0) and @tar_mvec == Geom::Vector3d.new(0,0,0)
			#mvec.length = @flylength1 if mvec != Geom::Vector3d.new(0,0,0)
			eye = view.camera.eye + mvec
			tvec = eye.vector_to( view.camera.target )
			tvec2 = tvec + mvec + @tar_mvec
			tvec2.length = tvec.length
			target = eye + tvec2
			up = Geom::Vector3d.new(0,0,1).cross( tvec ).cross( tvec ).reverse
			view.camera.set( eye, target , up )
			view.show_frame
			@tar_mvec = Geom::Vector3d.new( 0,0,0 )
			@eye_mvec = Geom::Vector3d.new( 0,0,0 )
			@@psec = Time.now.to_f
		end
	end
	
	def draw(view)
		Sketchup.set_status_text( "[ARROW] to MOVE,[L-Drag] to Look Around,[SHIFT] to RUN,[R-Click] to change SPEED" )
	end
	def initialize
		@flylength = 0.2.m
		a = Sketchup.read_default("TAK2_FLYTHROUGH","FLYLENGTH",@flylength.to_s)
		@flylength = a.to_l if a
		#@flylength = 0.2.m
		@lbtndn = false
		@cxy = [ 0,0 ]
		reset
	end
	def reset
		@keypress = Hash.new
		@keypress["UP"] = false
		@keypress["DOWN"] = false
		@keypress["LEFT"] = false
		@keypress["RIGHT"] = false
		@keypress["HOME"] = false
		@keypress["END"] = false
		@shift = false
		#@lbtndn = false
		@tar_mvec = Geom::Vector3d.new(0,0,0)
		#@cxy = [ 0,0 ]
		Sketchup.active_model.active_view.animation = nil
	end
	def activate
		Sketchup.set_status_text( "[ARROW] to MOVE,[L-Drag] to Look Around,[SHIFT] to RUN,[R-Click] to change SPEED" )
	end
	def deactivate(view)
	end
	
	def onCancel(flag, view)
		reset
		Sketchup.active_model.select_tool nil
	end

	def send_animation(psec = false)
		if @keypress.values.index( true ) or @tar_mvec != Geom::Vector3d.new(0,0,0)
			Sketchup.active_model.active_view.animation = TAK_view_animation.new( @flylength , @shift , @keypress , @tar_mvec , psec )
		else
			reset
		end
	end
	def getMenu(menu)
		menu.add_item("Change SPEED Value") {
			 res = UI.inputbox ["FLY SPEED"],[@flylength.to_s],"CHANGE FLYING SPEED"
			 if res
				if res[0].to_l != 0.0
					@flylength = res[0].to_l
					#p @flylength
					Sketchup.write_default("TAK2_FLYTHROUGH","FLYLENGTH", @flylength.to_s )
				end
			 end
		} 
	end
	def onKeyDown(key, repeat, flags, view)
		#case key
		if key == VK_UP
			@keypress["UP"] = true
		elsif key == VK_DOWN
			@keypress["DOWN"] = true
		elsif key == VK_RIGHT
			@keypress["RIGHT"] = true
		elsif key == VK_LEFT
			@keypress["LEFT"] = true
		elsif key == 36 or key == 91
			@keypress["HOME"] = true
		elsif key == 35 or key == 93
			@keypress["END"] = true
		elsif key == VK_SHIFT
			@shift = true
		end
		send_animation(true)
	end
	def onKeyUp(key, repeat, flags, view)
		#case key
		if key == VK_UP
			@keypress["UP"] = false
		elsif key == VK_DOWN
			@keypress["DOWN"] = false
		elsif key == VK_RIGHT
			@keypress["RIGHT"] = false
		elsif key == VK_LEFT
			@keypress["LEFT"] = false
		elsif key == 36 or key == 91
			@keypress["HOME"] = false
		elsif key == 35 or key == 93
			@keypress["END"] = false
		elsif key == VK_SHIFT
			@shift = false
		else
			reset
		end
		send_animation()
	end
	def onMouseMove(flags, x, y, view)
		if @lbtndn == true
			px , py = @cxy
			model = Sketchup.active_model
			camera = view.camera
			cdir = camera.direction.normalize
			fov = camera.fov
			up = camera.up
			eye = camera.eye
			target = camera.target
			plane = [ target , cdir ]
			ray1 = view.pickray( px , py )
			ray2 = view.pickray( x , y )
			opt = Geom.intersect_line_plane( ray1 , plane )
			npt = Geom.intersect_line_plane( ray2 , plane )
			@tar_mvec = opt.vector_to(npt)
			if @tar_mvec.length > 0.0
				@tar_mvec.length = @tar_mvec.length * 1.2
			end
			#target = @tar_mvec
			
			#up = Geom::Vector3d.new(0,0,1).cross( eye.vector_to(target) ).cross( eye.vector_to(target) ).reverse
			#view.camera.set( eye, target , up )
			@cxy = [ x,y ]
			send_animation()
			@tar_mvec = Geom::Vector3d.new(0,0,0)
		end
	end
	def onMouseLeave(view)
		#@lbtndn = false
		@tar_mvec = Geom::Vector3d.new(0,0,0)
		send_animation()
	end
	def onLButtonUp(flags, x, y, view)
		#@lbtndn = false
		@tar_mvec = Geom::Vector3d.new(0,0,0)
		send_animation()
	end
	def onLButtonDown(flags, x, y, view)
		@lbtndn = ( @lbtndn == false )
		@rbtndn = false
		@cxy = [ x,y ]
	end
end

unless( file_loaded?( "flythrough.rb" ) )
	UI.menu("Plugins").add_item( "FlyThrough Mode"){
		Sketchup.active_model.select_tool TAK_FlyThrough.new
	}
end
file_loaded("flythrough.rb")