Jump to content

TylerH

Members
  • Posts

    525
  • Joined

  • Last visited

Posts posted by TylerH

  1. Sorry, it was meant to be taken lightly. ;)

     

    Really hard to commit emotion and tone via the Internet and Text, so I should have added a B) or :P smiley.

     

    I'm not aware how different the new system is, so I was assuming the change-over was either minuscule or 1:1, if it is difficult I will see if I can do it myself so others can test.

  2. The material file was a straight up copy from the last version of the SDK that had shot1.mat or whatever. I think 2.25.

     

    Here is the material file:

     

    texture0="abstract::shot1.dds"
    shader="abstract::mesh_diffuse.vert","abstract::mesh_diffuse_alphatest.frag"
    
    alphatest=1
    blend=mod2x
    depthmask=0
    //normalmask=0
    overlay=1
    clamp0=1,1
    castshadows=0
    

  3. I am not switching to the single-state 2.3 until I am comfortable with and fix all current bugs with the entities I have created in multi-state.

     

    I don't want to switch to single-state with pre-existing bugs in my code at present, because then any bugs from single-state will be hard to differentiate from the existing ones.

     

    Over the next 2-3 days I will upgrade, but in the mean time can you just bear with me here? Don't act like you are incapable of making it compatible if you need it that way.

  4. I have been trying to adapt the code Josh used in road_node.lua to create the roads aligned to terrains, in order to work on a per-entity individual basis for terrain-aligned decals.

     

    I stripped it down to how I think it should work, and made a few modifications, but nothing is visible. I was hoping someone (preferably Josh or anyone who knows how this may work), to take a look and see if they can either get it working, or tell me what in practice I am doing wrong.

     

    Here is the decal.lua script:

    dofile("Scripts/base.lua")
    dofile("Scripts/Math.lua")
    dofile("Scripts/Primitives/Patch.lua")
    dofile("Scripts/Math/Plane.lua")
    dofile("Scripts/linkedlist.lua")
    
    --Properties interface
    function InitDialog(grid)
    base_InitDialog(grid)	
    end
    
    --Helper function to retrieve the scene terrain, if it exists
    function GetTerrain()
    for terrain in iterate(CurrentWorld().terrains) do
    	return terrain
    end
    end
    
    function Spawn(model)
    local entity=base_Spawn(model)	
    
    --Default settings
    entity.model:SetKey("width","5")
    entity.model:SetKey("border","0.25")
    entity.model:SetKey("tessellation","1.0")
    entity.model:SetKey("offset","0.05")
    entity.model:SetKey("material","road.mat")
    entity.model:SetKey("linkoncreate","1")
    entity.model:SetKey("reloadafterscript","0")
    
    entity.roadmesh=CreateMesh(nil)
    material=LoadMaterial("abstract::"..entity.model:GetKey("material"))
    entity.roadmesh:Paint(material,0)
    
    local surf=entity.roadmesh:AddSurface(material)
    entity.roadsurface=surf
    entity.roadsurface:Paint(material,0)
    
    entity.roadmesh:SetParent(entity.model,1)
    entity.roadmesh:SetShadowMode(0)
    
    function entity:BuildSegment()
    
    	--Create a temporary mesh and add a surface
    	local temp=CreateMesh()
    
    	local x0,x1,z0,z1,cx,cz,w,d
    	local terrain=GetTerrain()
    	local meterspertile=2.0
    	if terrain~=nil then meterspertile=terrain.scale.x end
    
    	cx=1.0
    	cz=1.0
    	w=2.0
    	d=2.0
    
    	--Now create a patch; this is a segmented plane that will match the terrain tiles			
    	patch=CreatePatch(w,d)
    	local patchsurf=patch:GetSurface(1)
    	patchsurf:Scale(Vec3(meterspertile*w,1.0,meterspertile*d))
    	patchsurf:Translate(Vec3(cx-w/meterspertile,0,cz-d/meterspertile))
    
    	--Make y coordinates of patch match terrain
    	if terrain~=nil then
    		for v=0,patchsurf:CountVertices()-1 do
    			local t=patchsurf:GetVertexPosition(v)
    			local px,pz
    			px = t.x/meterspertile+terrain.resolution/meterspertile
    			pz = t.z/meterspertile+terrain.resolution/meterspertile
    			t.y = terrain:GetHeight(px,pz)*terrain.scale.y+0.005
    			patchsurf:SetVertexPosition(v,t)
    		end
    	end
    
    	patch:SetParent(self.model,1)
    
    	local a,b,c,p,d
    	local src=patch:GetSurface(1)
    	local dst=temp:AddSurface()
    
    	--UV map the finished surface. This was hard!!!
    	a=patchsurf:GetVertexPosition(0)
    	b=patchsurf:GetVertexPosition(1)
    	c=patchsurf:GetVertexPosition(2)		
    	d=patchsurf:GetVertexPosition(3)
    
    	local texcoord = Vec2()
    	local u = Vec3()
    	local v = Vec3()
    	local p0=Vec2()
    	local p1=Vec2()
    	local result0=0
    	local result1=0
    	local a00
    	local a01
    	local a10
    	local a11
    	local texcoord=Vec2(0)
    
    	--Calculate the intersection of the top and bottom edges		
    	result0,p0.x,p0.y=linesintersect(a.x,a.z,b.x,b.z,c.x,c.z,d.x,d.z)
    	if result0==1 then
    		a00=math.atan2(a.z-p0.y,a.x-p0.x)
    		a01=math.atan2(c.z-p0.y,c.x-p0.x)
    		a00=WrapAngle(math.deg(a00))
    		a01=WrapAngle(math.deg(a01))
    		da0=angledifference(a00,a01)
    	end
    
    	--Calculate the intersection of the left and right edges
    	result1,p1.x,p1.y=linesintersect(a.x,a.z,c.x,c.z,b.x,b.z,d.x,d.z)
    	if result1==1 then
    		a10=math.atan2(a.z-p1.y,a.x-p1.x)
    		a11=math.atan2(b.z-p1.y,b.x-p1.x)
    		a10=WrapAngle(math.deg(a10))
    		a11=WrapAngle(math.deg(a11))
    		da1=angledifference(a10,a11)
    	end
    
    	--Now calculate texcoords and add normals
    	for n=0,dst:CountVertices()-1 do
    		t=dst:GetVertexPosition(n)
    		local yfactor=0
    		if result0==1 then
    			angle=math.deg(math.atan2(t.z-p0.y,t.x-p0.x))
    			yfactor = angledifference(angle,a00)/da0
    			--yfactor = math.mod(angledifference(angle,a00)/da0,1.0)
    			--yfactor=1.0+yfactor
    			--texcoord.y = (i+yfactor) / self.countsegments*1.0
    			texcoord.y=yfactor
    else
    			u=Vec3()
    			u.x = c.x-a.x
    			u.y = c.y-a.y
    			u.z = c.z-a.z
    			u=planefrompointnormal(a,Normalize(u))
    			dist=PointDistance(a,c)
    			u.nx=u.nx/dist
    			u.ny=u.ny/dist
    			u.nz=u.nz/dist
    			u.d=u.d/dist
    			texcoord.y=((u.nx*t.x+u.ny*t.y+u.nz*t.z+u.d))
    			--texcoord.y=1.0+texcoord.y
    			--texcoord.y = (i+texcoord.y) / self.countsegments*1.0
    			--if texcoord.y<0.0 then texcoord.y=1.0+texcoord.y end
    			--texcoord.y = texcoord.y + i
    		end
    		if result1==1 then
    			angle=math.deg(math.atan2(t.z-p1.y,t.x-p1.x))
    			texcoord.x = 1.0+angledifference(angle,a10)/da1
    		else
    			u=Vec3()
    			u.x = b.x-a.x
    			u.y = b.y-a.y
    			u.z = b.z-a.z
    			u=planefrompointnormal(a,Normalize(u))
    			dist=PointDistance(a,B)
    			u.nx=u.nx/dist
    			u.ny=u.ny/dist
    			u.nz=u.nz/dist
    			u.d=u.d/dist
    			texcoord.x=u.nx*t.x+u.ny*t.y+u.nz*t.z+u.d		
    		end
    		dst:SetVertexTexCoords(n,texcoord,0)
    		if terrain~=nil then
    			dst:SetVertexNormal(n,terrain:CalcNormal(t.x,t.z))
    		else
    			dst:SetVertexNormal(n,Vec3(0,1,0))			
    		end			
    	end
    
    	--Add the temporary surface to the real road surface
    	dst:Add(entity.roadsurface)
    
    	--Discard the temporary meshes
    	patch:Free()
    	temp:Free()
    end
    
    return entity
    end
    
    function SetKey(model,key,value)
    local entity=entitytable[model]
    if entity==nil then return 1 end
    if key=="material" then
    	if entity.roadmesh then
    		material=LoadMaterial("abstract::"..value)
    		entity.roadmesh:Paint(material,0)
    	end	
    end
    return 1
    end
    
    function GetKey(model,key,value)
    local entity=entitytable[model]
    if entity==nil then return value end
    if key=="material" then
    	return value
    else
    	return base_GetKey(model,key,value)
    end
    end
    
    function Kill(model)
    local entity=entitytable[model]
    base_Kill(model)
    end
    
    function UpdateMatrix(model)
    local entity=entitytable[model]
    if (entity ~= nil) then
    	entity:BuildSegment()
    	entity.roadsurface:UpdateTangentsAndBinormals()
    
    	entity.roadmesh:UpdateLocalAABB()
    	entity.roadmesh:UpdateAABB()
    end	
    end
    

     

    Thanks,

    Tyler

  5. Is it possible the LinePick doesn't work with the terrain because it is setup via the vertex shader?

     

    I mean, it is basically a high-resolution ish plane with a displacement map (height map).

  6. str is just a typedef for char* isn't it? So a bit redundant to explicitly cast to char*, besides, what if you have dangling pointer and non-mutable access to that particular string?

     

    You should use const_cast<char*>(s.c_str()) to be 100% safe, though what Masterxilo stated about the memory problems still apply.

  7. Yes, I do have decals working.

     

    Here is my code to create a decal:

     

    if (pick.surface~=nil) then
    			SetWorld(fw.transparency.world)
    			decal = CreateDecal(pick.surface,TFormPoint(pick.position,nil,pick.entity),1.0/16.0,64)
    			SetWorld(fw.main.world)				
    			if (decal~=nil) then
    				decal:SetParent(pick.entity,0)
    				--decal:Paint(LoadMaterial("abstract::bullethole.mat"))
    				decal:Paint(GetImpactDecal(GetMeshModel(pick.entity)))
    
    				decal:SetColorf(1.0,1.0,1.0,bullet.damage/bullet.initialdamage)
    			end
    		end
    

     

    You can ignore the SetColorf and GetImpactDecal stuff, those are things for Weaponwerks for the dynamic impact system, and to set the alpha of the decal based on how much damage the bullet has inflicted relative how much it could in perfect conditions.

     

    For CreateDecal from a pick, you need to pass the surface, the transformed pick position from world to entity space, the radius (1/16.0 is what Josh used by default and makes a nice, though slightly too big bullet hole), and 64 is the max tris (the higher this is, the better the decal can align to the surface).

     

    The transparency world and decal:SetParent calls are key in order to make sure it is visible and sticks to the surface.

  8. Depends on what you actually call a "draw calls".

     

    As in a call to glDrawArryas or glDrawElements, that is done once per Vertex Buffer Object (VBO) or once per Vertex Buffer Array (VBA [collection of VBOs]) depending on your setup.

     

    Last I heard I thought Leadwerks Engine used VBOs per-mesh, and just translated, rotated, scaled Object Space and then made a call to glDrawElements of the same VBO, on a per-instance basis.

     

    Anyways, I am not the one to have the answer.

×
×
  • Create New...