+ Reply to Thread
Page 1 of 6 123 ... LastLast
Results 1 to 10 of 59

Thread: [E2] TraceHull

  1. #1
    Wirererer bobthe2lol's Avatar
    Join Date
    Aug 2007
    Location
    US,NY
    Posts
    309

    Talking [E2] TraceHull

    I looked at the ranger code, and, as with the holo code, i got scared. Hence why i wont do it myself. Anyway, on to the sugestion. This arises from a e2-train i was making, using rangers (thanks Omi ) and the problem, is it is messed up by any tiny crack in the track, because traces are infinitly small. TraceHull, on the other hand, is a trace, with a size. I think of it as something like this:

    traceHull(entity()os(),entity():toWorld(vec(0,0,-100)),vec(10,10,0),-vec(10,10,0))
    would make a tracehull from startpos, vector1, to endpos, vector2, with tracedata.mins as the 3rd vector
    and tracedata.maxs as the 4th one

    I think someone out there can handle this, and please. Do it fast. It is needed.
    Thank you, and have a nice day.

  2. #2
    Wirererer Jake's Avatar
    Join Date
    Feb 2010
    Location
    owner():pos()
    Posts
    116

    Default Re: [E2] TraceHull

    This would be usefull.

  3. #3
    No u Divran's Avatar
    Join Date
    Jul 2008
    Location
    Sweden
    Posts
    4,582

    Default Re: [E2] TraceHull

    This has already been suggested, but I didn't know there was a tracehull function! ( util.TraceHull - GMod Wiki )
    I'm going to make this right away.
    SVN Tutorial
    My SVN:
    Code:
    http://divranspack.googlecode.com/svn/trunk/%20divranspack/
    Get dropbox and get 250 MB extra space: Dropbox

  4. #4
    Wire Sofaking feha's Avatar
    Join Date
    Sep 2009
    Location
    Here
    Posts
    1,154

    Default Re: [E2] TraceHull

    Is this liek a ranger where ou specify width? If so, I have thought this would simplyfy and improve lots of my stuff alot!

    If there is a lua function for it, it should not be to hard to add it :P. Run divtag, run!

  5. #5
    Wirererer Jake's Avatar
    Join Date
    Feb 2010
    Location
    owner():pos()
    Posts
    116

    Default Re: [E2] TraceHull

    Hurry up, Divran! I hope this will go in the SVN if it works !
    Last edited by Jake; 02-27-2010 at 06:58 PM.

  6. #6
    Wire Sofaking N00bDud3's Avatar
    Join Date
    Jul 2009
    Location
    Error: Unknown Location
    Posts
    1,252

    Default Re: [E2] TraceHull

    This would be very useful. With it, I won't have to use a bunch of different traces to check a hallway for people, I can just use a wide scanning trace.



  7. #7
    Wirererer Jake's Avatar
    Join Date
    Feb 2010
    Location
    owner():pos()
    Posts
    116

    Default Re: [E2] TraceHull

    I did the same thing before as you, N00bdud3.
    This would be very useful. With it, I won't have to use a bunch of different traces to check a hallway for people, I can just use a wide scanning trace.

  8. #8
    No u Divran's Avatar
    Join Date
    Jul 2008
    Location
    Sweden
    Posts
    4,582

    Default Re: [E2] TraceHull

    DONE!

    Here's the code for those who want it (Replace everything in wire/lua/entities/gmod_wire_expression2/core/ranger.lua with this)
    Code:
    /******************************************************************************\
      Expression 2 built-in ranger/tracing extension
    \******************************************************************************/
    
    E2Lib.RegisterExtension("ranger", true)
    
    -------------------
    -- Main function --
    -------------------
    
    local function ResetRanger(self)
    	local data = self.data
    	data.rangerdefaultzero = false
    	data.rangerignoreworld = false
    	data.rangerwater = false
    	data.rangerentities = true
    	data.rangerfilter = {}
    end
    
    local function ranger(self, rangertype, range, p1, p2, hullbool, size)
    	local data = self.data
    	local chip = self.entity
    	
    	local defaultzero = data.rangerdefaultzero
    	local ignoreworld = data.rangerignoreworld
    	local water = data.rangerwater
    	local entities = data.rangerentities
    	local filter = data.rangerfilter
    
    	if not data.rangerpersist then
    		ResetRanger(self)
    	end
    	
    	-- begin building tracedata structure
    	table.insert(filter, chip)
    	local tracedata = { filter = filter }
    	if water then
    		if entities then
    			--(i)we
    			tracedata.mask = -1
    		elseif ignoreworld then
    			--iw
    			tracedata.mask = MASK_WATER
    			ignoreworld = false
    		else
    			--w
    			tracedata.mask = MASK_WATER | CONTENTS_SOLID
    		end
    	elseif not entities then
    		if ignoreworld then
    			--i
    			tracedata.mask = 0
    			ignoreworld = false
    		else
    			--no flags
    			tracedata.mask = MASK_NPCWORLDSTATIC
    		end
    	--else
    		--(i)e
    	end
    	
    	-- calculate startpos and endpos
    	if rangertype == 2 then
    		tracedata.start = Vector( p1[1], p1[2], p1[3] )
    		tracedata.endpos = Vector( p2[1], p2[2], p2[3] )
    	elseif rangertype == 3 then
    		tracedata.start = Vector( p1[1], p1[2], p1[3] )
    		tracedata.endpos = tracedata.start + Vector( p2[1], p2[2], p2[3] ):Normalize()*range
    	else
    		tracedata.start = chip:GetPos()
    		
    		if rangertype == 1 && (p1!=0 || p2!=0) then
    			p1 = math.rad(p1)
    			p2 = math.rad(p2+270)
    			local zoff = -math.cos(p1)*range
    			local yoff = math.sin(p1)*range
    			local xoff = math.cos(p2)*zoff
    			zoff = math.sin(p2)*zoff
    			tracedata.endpos = chip:LocalToWorld(Vector(xoff,yoff,zoff))
    		elseif rangertype == 0 && (p1!=0 || p2!=0) then
    			local skew = Vector(p2, -p1, 1)
    			tracedata.endpos = chip:LocalToWorld(skew:Normalize()*range)
    		else
    			tracedata.endpos = tracedata.start + chip:GetUp()*range
    		end
    	end
    	
    	--------------------------------------------------------------------------------------- I ADDED THIS BIT!
    	local trace = util.TraceLine( tracedata )
    	if (hullbool and hullbool == true) then
    		local s = Vector(size[1], size[2], size[3])
    		tracedata.mins = s/2*-1
    		tracedata.maxs = s/2
    		trace = util.TraceHull( tracedata )
    	end
    	---------------------------------------------------------------------------------------
    	
    	-- handle some ranger settings
    	if ignoreworld and trace.HitWorld then
    		trace.HitPos = defaultzero and tracedata.start or tracedata.endpos
    		trace.Hit = false
    	elseif defaultzero and not trace.Hit then
    		trace.HitPos = tracedata.start
    	end
    	
    	return trace
    end
    
    /******************************************************************************/
    
    registerType("ranger", "xrd", nil,
    	nil,
    	nil,
    	function(retval)
    		if retval == nil then return end
    		if type(retval) ~= "table" then error("Return value is neither nil nor a table, but a "..type(retval).."!",0) end
    	end,
    	function(v)
    		return type(v) ~= "table" or not v.HitPos
    	end
    )
    
    /******************************************************************************/
    
    __e2setcost(1) -- temporary
    
    --- RD = RD
    e2function ranger operator=(ranger lhs, ranger rhs)
    	self.vars[lhs] = rhs
    	self.vclk[lhs] = true
    	return rhs
    end
    
    e2function number operator_is(ranger walker)
    	if walker then return 1 else return 0 end
    end
    
    /******************************************************************************/
    
    __e2setcost(1) -- temporary
    
    --- Passing 0 (the default) resets all ranger flags and filters every execution and after calling ranger/rangerOffset. Passing anything else will make the flags and filters persist until they're changed again.
    e2function void rangerPersist(persist)
    	self.data.rangerpersist = persist ~= 0
    end
    
    --- Resets all ranger flags and filters.
    e2function void rangerReset()
    	ResetRanger(self)
    end
    
    local flaglookup = {
    	i = "rangerignoreworld",
    	w = "rangerwater",
    	e = "rangerentities",
    	z = "rangerdefaultzero",
    }
    
    --- Returns the ranger flags as a string.
    e2function string rangerFlags()
    	local ret = ""
    	for char,field in pairs(flaglookup) do
    		if self.data[field] then ret = ret .. char end
    	end
    	return ret
    end
    
    --- Sets the ranger flags. <flags> can be any combination of I=ignore world, W=hit water, E=hit entities and Z=default to zero.
    e2function void rangerFlags(string flags)
    	flags = flags:lower()
    	for char,field in pairs(flaglookup) do
    		self.data[field] = flags:find(char) and true or false
    	end
    end
    
    --- Default is 0, if any other value is given it will hit water
    e2function void rangerHitWater(hitwater)
    	self.data.rangerwater = hitwater ~= 0
    end
    
    --- Default is 1, if any other value is given it will hit entities
    e2function void rangerHitEntities(hitentities)
    	self.data.rangerentities = hitentities ~= 0
    end
    
    --- Default is 0, if any other value is given it will ignore world
    e2function void rangerIgnoreWorld(ignoreworld)
    	self.data.rangerignoreworld = ignoreworld ~= 0
    end
    
    --- If given any value other than 0 it will default the distance data to zero when nothing is hit
    e2function void rangerDefaultZero(defaultzero)
    	self.data.rangerdefaultzero = defaultzero ~= 0
    end
    
    --- Feed entities you don't want the trace to hit
    e2function void rangerFilter(entity ent)
    	if validEntity(ent) then
    		table.insert(self.data.rangerfilter,ent)
    	end
    end
    
    __e2setcost(5)
    
    --- Feed an array of entities you don't want the trace to hit
    e2function void rangerFilter(array filter)
    	local rangerfilter = self.data.rangerfilter
    	for _,ent in ipairs(filter) do
    		if validEntity(ent) then
    			table.insert(rangerfilter,ent)
    		end
    	end
    end
    
    /******************************************************************************/
    
    e2function ranger noranger()
    	return nil
    end
    
    __e2setcost(20) -- temporary
    
    --- You input max range, it returns ranger data
    e2function ranger ranger(distance)
    	return ranger(self, 0, distance, 0, 0) -- type 0, no skew
    end
    
    --- Same as above with added inputs for X and Y skew
    e2function ranger ranger(distance, xskew, yskew)
    	return ranger(self, 0, distance, xskew, yskew) -- type 0, with skew
    end
    
    --- You input the distance, x-angle and y-angle (both in degrees) it returns ranger data
    e2function ranger rangerAngle(distance, xangle, yangle)
    	return ranger(self, 1, distance, xangle, yangle) -- type 1, with angles
    end
    
    --- You input two vector points, it returns ranger data
    e2function ranger rangerOffset(vector from, vector to)
    	return ranger(self, 2, 0, from, to) -- type 2, from one point to another
    end
    
    --- You input the range, a position vector, and a direction vector and it returns ranger data
    e2function ranger rangerOffset(distance, vector from, vector direction)
    	return ranger(self, 3, distance, from, direction) -- type 3, from one position into a specific direction, in a specific range
    end
    
    /******************************************************************************/
    
    __e2setcost(2) -- temporary
    
    --- Returns the distance from the rangerdata input, else depends on rangerDefault
    e2function number ranger:distance()
    	if not this then return 0 end
    	if this.StartSolid then return this.StartPos:Distance(this.HitPos)*(1/(1-this.FractionLeftSolid)-1) end
    	return this.StartPos:Distance(this.HitPos)
    end
    
    --- Returns the position of the input ranger data trace IF it hit anything, else returns vec(0,0,0)
    e2function vector ranger:position()
    	if not this then return { 0, 0, 0 } end
    	if this.StartSolid then return this.StartPos end
    	return this.HitPos
    end
    
    --- Returns the entity of the input ranger data trace IF it hit an entity, else returns nil
    e2function entity ranger:entity()
    	if not this then return nil end
    	return this.Entity
    end
    
    --- Returns the bone of the input ranger data trace IF it hit an entity, else returns nil
    e2function bone ranger:bone()
    	if not this then return nil end
    	
    	local ent = this.Entity
    	if not validEntity(ent) then return nil end
    	return getBone(ent, this.PhysicsBone)
    end
    
    --- Returns 1 if the input ranger data hit anything and 0 if it didn't
    e2function number ranger:hit()
    	if not this then return 0 end
    	if this.Hit then return 1 else return 0 end
    end
    
    --- Outputs a normalized vector perpendicular to the surface the ranger is pointed at.
    e2function vector ranger:hitNormal()
    	if not this then return { 0, 0, 0 } end
    	return this.HitNormal
    end
    
    /******************************************************************************/
    
    e2function ranger rangerOffsetHull( vector startpos, vector endpos, vector size )
    	return ranger( self, 2, 0, startpos, endpos, true, size )
    end
    
    e2function ranger rangerOffsetHull( number distance, vector startpos, vector direction, vector size )
    	return ranger( self, 3, distance, startpos, direction, true, size )
    end
    
    /******************************************************************************/
    
    registerCallback("construct", function(self)
    	self.data.rangerpersist = false
    end)
    
    registerCallback("preexecute", function(self)
    	if not self.data.rangerpersist then
    		ResetRanger(self)
    	end
    end)
    
    __e2setcost(nil) -- temporary
    And I've attached a patch for TomyLobo.

    EDIT: I've recorded a short video of it in action. Uploading at the moment.

    EDIT2: I know someone who will be VERY happy. Techni will LOVE this for his pathfinder. It will most likely increase efficiency by OVER 9000 %!

    EDIT3: The two functions in E2 are:
    Ranger = rangerOffsetHull( (vector) StartPos, (vector) EndPos, (vector) Size )
    and
    Ranger= rangerOffsetHull( (number) Distance, (vector) StartPos, (vector) Direction, (vector) Size )

    EDIT4: Video!
    http://www.xfire.com/video/233792/
    Last edited by Divran; 02-27-2010 at 07:16 PM.
    SVN Tutorial
    My SVN:
    Code:
    http://divranspack.googlecode.com/svn/trunk/%20divranspack/
    Get dropbox and get 250 MB extra space: Dropbox

  9. #9
    Wirererer Jake's Avatar
    Join Date
    Feb 2010
    Location
    owner():pos()
    Posts
    116

    Talking Re: [E2] TraceHull

    Hooray! That was fast !

    Edit:
    It will most likely increase efficiency by OVER 9000 %!


    Edit 2: These function things look easy enough to remember.

    Edit 3: The video made it look great! This is definitly worthy of the SVN maybe with some additions/modifications. Also, you ninja'd me (kinda) 3 times with the edits !
    Last edited by Jake; 02-27-2010 at 07:31 PM.

  10. #10
    No u Divran's Avatar
    Join Date
    Jul 2008
    Location
    Sweden
    Posts
    4,582

    Default Re: [E2] TraceHull

    TomyLobo, or any other admin reading this, remember that I didn't mean that to be directly commited. You should look it over and stuff first. And also maybe add some more functions, like "rangerOffsetHull( StartPos, EndPos, MinSize, MaxSize )" instead of just "Size" like I have at the moment.
    In case anyone else is wondering: The way I have it at the moment with only "Size", you can only create a "box" in the middle of the ranger beam. With two variables like MinSize and MaxSize, you could create a box to one side of the ranger beam, or even offsetted from it.
    SVN Tutorial
    My SVN:
    Code:
    http://divranspack.googlecode.com/svn/trunk/%20divranspack/
    Get dropbox and get 250 MB extra space: Dropbox

+ Reply to Thread
Page 1 of 6 123 ... LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
proceed-collector
proceed-collector
proceed-collector
proceed-collector
linguistic-parrots
linguistic-parrots
linguistic-parrots
linguistic-parrots