• Login
sketchucation logo sketchucation
  • Login
🤑 SketchPlus 1.3 | 44 Tools for $15 until June 20th Buy Now

Help: Plug in bug

Scheduled Pinned Locked Moved Developers' Forum
1 Posts 1 Posters 439 Views
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    genma saotome
    last edited by 12 Jul 2009, 17:57

    I'm not a programmer and I need some help fixing a ruby plug-in. The author wrote it largely as an educational exercise (it seemed to work as he now has a job with a cad company) and he is no longer available to deal with this problem. It's a simple export to game format plug-in with one flaw: it doesn't export the correct position of a manually moved texture when the poly displaying that texture is in a component. If the poly is not in a component, any adjustment to the textures position exports properly.

    I'd would be very grateful if someone here was willing to take a look at the code and see if the problem jumps out / is easilly corrected.

    WRT copyright: Any suggested fix will be returned to the author (on the chance he wants it). I'll edit my own copy for my own use.

    ###======================================================
    # Copyright © 2006-2008. All rights reserved.
    # version 1.0 24th June 2006.
    # version 1.3 29/2/2008 - adjusted for polymaster
    
    ###======================================================
    # THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
    # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
    # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    #-----------------------------------------------------------------------------
    
    require "3dmath.rb"
    
    
    #####################################################
    # Single class instance
    class SFile
     attr_accessor ;name, ;fileName, ;newFolder, ;fh , ;specular, ;message
    
    	# scan the model groups for geometry
    	def scanModel1(startEnt,parentSeg,dlevel,trans,lay)
    		
    		showFaces=true
    		
    		# if component instance, set grp to be the definition
    		grp=startEnt
    		if(grp.kind_of? Sketchup;;ComponentInstance) then
    			# matrix id
    			id=parentSeg
    			trans=Geom;;Transformation.new() if not trans
    			trans =  trans * grp.transformation
    			# get component definition
    			grp = grp.definition
    		else
    			# grp could be a group or a model
    			#
    			# @lastMatrixid is nil for first LOD, 0+ for later passes
    			if @lastMatrixid then
    				id=@lastMatrixid
    				oMatrix=@matrices[id]
    				@lastMatrixid+=1
    			else
    				oMatrix=Matrix.new()
    				oMatrix.polys=0
    		
    				if(grp.kind_of? Sketchup;;Model) then
    					oMatrix.name = "main"
    				else
    					oMatrix.name=grp.name.tr(" ","_")
    				end
    				
    				oMatrix.name="default" if oMatrix.name.length==0
    				
    				oMatrix.name = "x" + oMatrix.name if oMatrix.name =~ /^\d/
    				if parentSeg>=0 then
    					# get the transform matrix
    					oMatrix.setFromSU startEnt.transformation.to_a
    				end
    				
    				# count faces
    				
    				id=@matrices.length
    				
    				@matrices.push oMatrix
    			end
    			# if group lod
    			if id>0 then
    				showFaces=(dlevel==0 or grp.lod==0 or grp.lod >= lay)
    			end
    			@distance_levels[dlevel].hierarchy.push parentSeg
    		end
    		
    		# scan faces
    		if showFaces then
    			for ent in grp.entities
    				if(ent.kind_of? Sketchup;;Face) then
    					if dlevel==0 or ent.lod==0 or ent.lod >= lay then
    						scanVerts ent,id,startEnt,dlevel,trans
    					end
    				end
    			end
    		end
    		
    		# recursive call to sub groups
    		for ent in grp.entities
    		
    			# scan sub groups
    			if(ent.kind_of? Sketchup;;Group)
    				scanModel1 ent, id,dlevel,trans,lay
    				
    			# don't show instances if group is disabled
    			elsif( ent.kind_of? Sketchup;;ComponentInstance and showFaces )
    				# ignore component if it'd LOD is not visible
    				if dlevel==0 or ent.lod==0 or ent.lod >= lay then
    					scanModel1 ent, id,dlevel,trans,lay
    				end
    				
    			elsif( ent.kind_of? Sketchup;;ComponentDefinition )
    				scanModel1 ent, id,dlevel,trans,lay
    				
     			end
    		end
    	end
    	
    	# save the vertices for a face
    	def scanVerts(o,id,ent,dlevel,trans)
    		# o is a face
    		# ent - original entity
    		
    		mf=o.material
    		mb=o.back_material
    		scaleu,scalev,shade1,shade2=nil,nil,nil,nil
    		polys=0
    		
    		# get the instance material if definition material is nil
    		if not mf 
    			mf=ent.material if ent.kind_of? Sketchup;;ComponentInstance
    			if mf and mf.texture then
    				scaleu=mf.texture.width.inch
    				scalev=mf.texture.height.inch
    			end
    		end
    		
    		mat,matb=nil,nil
    		uvhelp=o.get_UVHelper(true, true, @tw)
    		
    		subobj1=@distance_levels[dlevel].sub_objects.at(0)
    		subobj2=subobj1
    
    		mesh = o.mesh 7
    		p1,p2,p3 = 0
    		pr2,fNormal2,shade2,pstat2,vst2,lmc2,vset2,nx2=nil,nil,nil,nil,nil,nil,nil,nil
    		pr1,fNormal1,shade1,pstat1,vst1,lmc1,vset1,nx1=nil,nil,nil,nil,nil,nil,nil,nil
    		
    		if mf or not mb
    			fNormal1=findItem(o.normal,@normals)
    			# use front face material		
    			mat = findTexture(mf)
    			
    			shade1=findShader(mf)
    			lmc1=findLightCnf(shade1)
    			vst1=findVState(mf,id,lmc1)
    			
    			# calc prim_state
    			ps=SPState.new()
    			ps.shader=shade1
    			ps.lightCfg=lmc1
    			ps.vState=vst1
    			ps.tex_idxs.push mat if mat
    			# gloss
    			if @light_model_cfgs.at(lmc1)==2 then
    				img=@images.index("env_map.ace")
    				# compare image properties
    				ps.tex_idxs.push @textures.index(img)
    			end
    
    
    			# no material alpha is for solid/transparent
    			# alpha of 99% is for alpha but no sub-object
    			# 98% and lower will create a sub-object for alpha sorting
    			
    			if mf
    				# set alphatest to 1 for transparent, 0 for solid or alpha
    				if mf.texture
    					stex =  mf.texture.filename.upcase
    					if stex.index(".TGA") then
    						ps.alphatestmode=1
    					end
    				end
    				if mf.alpha < 1.0
    					ps.alphatestmode=0
    					ps.priority=mf.alpha*100
    					if ps.priority<99
    						subobj1=setSubObj(dlevel)
    					end
    				end
    			end
    	
    	
    	
    			pstat1=findItem(ps,@prim_states)
    			
    			findItem shade1,subobj1.shaders
    			findItem lmc1,subobj1.lightcfgs
    			
    			vset=SVtxset.new(vst1)
    			vset1=findItem(vset,subobj1.vtx_sets)
    			
    			node= SGeomnode.new(id)
    			nx1=findItem node,subobj1.geometry_nodes
    			findItem pstat1,subobj1.geometry_nodes[nx1].pStates
    			
    			pr1=getPrim(subobj1,vset1,pstat1)
    		end
    		
    		if mb
    			fNormal2=findItem(o.normal.reverse,@normals)
    			matb=findTexture(mb)
    			shade2=findShader(mb)
    			lmc2=findLightCnf(shade2)
    			vst2=findVState(mb,id,lmc2)
    
    			# calc prim_state
    			ps=SPState.new()
    			ps.shader=shade2
    			ps.lightCfg=lmc2
    			ps.vState=vst2
    			ps.tex_idxs.push matb if matb
    			
    			if @light_model_cfgs.at(lmc2)==2 then
    				img=@images.index("env_map.ace")
    				# compare image properties
    				ps.tex_idxs.push @textures.index(img)
    			end
    			
    			# set alphatest to 1 for transparent, 0 for solid or alpha
    			if mb.texture
    				stex =  mb.texture.filename.upcase
    				if stex.index(".TGA") then
    					ps.alphatestmode=1
    				end
    			end
    			
    			if mb.alpha < 1.0 
    				ps.alphatestmode=0
    				ps.priority=mb.alpha*100
    				if ps.priority<99
    					subobj2=setSubObj(dlevel)
    				end
    			end
    			pstat2=findItem(ps,@prim_states)
    		
    			findItem shade2,subobj2.shaders
    			findItem lmc2,subobj2.lightcfgs
    			vset=SVtxset.new(vst2)
    			vset2=findItem(vset,subobj2.vtx_sets)
    			
    			node= SGeomnode.new(id)
    			nx2=findItem node,subobj2.geometry_nodes
    			findItem pstat2,subobj2.geometry_nodes[nx2].pStates
    			
    			pr2=getPrim(subobj2,vset2,pstat2)
    		end
    		
    		1.upto(mesh.count_polygons) do |j|
    			p3,p2,p1 = mesh.polygon_at(j)
    			
    			p1 = p1.abs
    			pt1=mesh.point_at p1
    			p2 = p2.abs
    			pt2=mesh.point_at p2
    			p3 = p3.abs
    			pt3=mesh.point_at p3
    			if trans
    				pt1.transform! trans
    				pt2.transform! trans
    				pt3.transform! trans
    			end
    			
    			# make sure we have a triangle
    			if  not pt3.on_line? [pt1,pt2]
    			
    				if mf or not mb
    					@bb.add pt1
    					@bb.add pt2
    					@bb.add pt3
    					if mat
    						uv1=uvhelp.get_front_UVQ pt1
    						uv1.x/=scaleu if scaleu
    						uv1.y/=scalev if scalev
    					
    						uv2=uvhelp.get_front_UVQ pt2
    						uv2.x/=scaleu if scaleu
    						uv2.y/=scalev if scalev
    					
    						uv3=uvhelp.get_front_UVQ pt3
    						uv3.x/=scaleu if scaleu
    						uv3.y/=scalev if scalev
    					else
    						uv1,uv2,uv3=nil,nil,nil
    					end
    					pn=mesh.normal_at(p1)
    					pn.transform! trans if trans
    					pr1.vert_idxs.push storeVertex(subobj1,pt1,pn,uv1,vset1)
    					pn=mesh.normal_at(p2)
    					pn.transform! trans if trans
    					pr1.vert_idxs.push storeVertex(subobj1,pt2,pn,uv2,vset1)
    					pn=mesh.normal_at(p3)
    					pn.transform! trans if trans
    					pr1.vert_idxs.push storeVertex(subobj1,pt3,pn,uv3,vset1)
    					
    					subobj1.faceNormals +=1
    					polys+=1
    					pr1.normal_idxs.push fNormal1
    					subobj1.geometry_nodes[nx1].count+=1
    					
    					#print uv1.to_s + "\n" + uv2.to_s + "\n" + uv3.to_s + "\n"
    				end
    				if mb then
    					if matb
    						uv1=uvhelp.get_back_UVQ pt1
    						uv2=uvhelp.get_back_UVQ pt2
    						uv3=uvhelp.get_back_UVQ pt3
    					else
    						uv1,uv2,uv3=nil,nil,nil
    					end
    					
    					# adjust order if reflected odd number of times
    					if trans
    						if trans.to_a[0]*trans.to_a[5]*trans.to_a[10]<0
    							p3,p1=p1,p3
    							uv3,uv1=uv1,uv3
    							pt3,pt1=pt1,pt3
    						end
    					end
    					
    					# reverse order
    					pn=mesh.normal_at(p3).reverse
    					pn.transform! trans if trans
    					pr2.vert_idxs.push storeVertex(subobj2,pt3,pn,uv3,vset2)
    					pn=mesh.normal_at(p2).reverse
    					pn.transform! trans if trans
    					pr2.vert_idxs.push storeVertex(subobj2,pt2,pn,uv2,vset2)
    					pn=mesh.normal_at(p1).reverse
    					pn.transform! trans if trans
    					pr2.vert_idxs.push storeVertex(subobj2,pt1,pn,uv1,vset2)
    					
    					#print uv1.to_s + "\n" + uv2.to_s + "\n" + uv3.to_s + "\n"
    
    					subobj2.faceNormals +=1
    					polys+=1
    					pr2.normal_idxs.push fNormal2
    					subobj2.geometry_nodes[nx2].count+=1
    				end
    			end
    		end
    		@matrices[id].polys+=polys if dlevel==0
    	end
    	
    	def storeVertex(so,p,n,u,vset)
    		
    		ip=findItem(p,@points)
    		ix=findItem(n,@normals)
    		iu=findItem(u,@uv_points)
    		vert=SVertex.new
    		vert.pointIdx=ip
    		vert.normalIdx=ix
    		vert.vertex_uvs.push iu if u
    	
    		findItem(vert,so.vtx_sets[vset].vertices)
    	end
    	
    	def setSubObj(dl)
    		if @distance_levels[dl].sub_objects.length==1 then
    			so=SSObject.new()
    			@distance_levels[dl].sub_objects.push so
    			so.flags="00000500"
    			so.vol=0
    			return so
    		else
    			return @distance_levels[dl].sub_objects[1]
    		end
    	end
    
    	def getPrim(so,vs,ps)
    		prim=SPrimitive.new
    		prim.primstate=ps
    		x=so.vtx_sets[vs]
    		
    		# 2 primitive entries
    		prind=findItem prim,x.primitives
    		
    		if prind==(x.primitives.length-1) then
    			x.primitives.push SPrimitive.new()
    		end
    		
    		prind+=1
    		pr=x.primitives[prind]
    		while pr.normal_idxs.length>2700 and not pr.primstate do
    			# at very end - add new one
    			if prind==(x.primitives.length-1) then
    				x.primitives.push SPrimitive.new()
    			end
    			prind+=1
    			pr=x.primitives[prind]
    		end
    		if pr.primstate then
    			x.primitives[prind]=[SPrimitive.new(),pr]
    			x.primitives.flatten!
    		end
    		return x.primitives[prind]
    	end
    
    
    	def findTexture(m)
    		if m and m.texture 
    			img=findImage(m.texture)
    		end
    		if not(img) 
    			return nil
    		end
    		# compare image properties
    		0.upto(@textures.length-1) do |e|
    			if @textures.at(e).img==img
    				return e
    			end
    		end
    		
    		t=STex.new(img)
    		
    		n=m.name.upcase.index("/BIAS")
    		t.mipbias=m.name[n+5..n+7].to_i if n
    		
    		@textures.push t
    		return @textures.length-1
    		
    	end
    
    	# used for points, normals, UV points and other objects that support ==
    	def findItem(v,array)
    		if not v 
    			return nil
    		end
    		return array.addSearch(v)
    	end
    
    
    	# find vstate from material
    	def findVState(m,id,cnf)
    		vs=SVState.new(id)
    		vs.lightCfg=cnf
    		stex=""
    		if m
    			if m.name.upcase.index("HISHINE")
    				vs.lightMat=-6
    				@specular=true
    			elsif m.name.upcase.index("LOSHINE")
    				vs.lightMat=-7
    				@specular=true
    			elsif m.name.upcase.index("AMBIENT")
    				vs.lightMat=-9
    			elsif m.name.upcase.index("DARKSHADE")
    				vs.lightMat=-12
    			elsif m.name.upcase.index("HALFBRIGHT")
    				vs.lightMat=-11
    			end
    			
    			if m.texture then 
    				stex=m.texture.filename
    			end
    		end
    				#'''''' color of material
    		if m then
    			if stex.length==0 
    				col = m.color
    			end
    		else
    			col = Sketchup.active_model.rendering_options["FaceFrontColor"]
    		end
    		
    		# new colour and light material
    		if col then
    			if @colours.length==0
    				# add black & white
    				findItem(Sketchup;;Color.new(0,0,0),@colours)
    				findItem(Sketchup;;Color.new(255,255,255),@colours)
    			end
    			c1=findItem(col,@colours)
    			lm=c1.to_s + " " + c1.to_s + " 1 0 0"
    			vs.lightMat = findItem(lm,@light_materials)
    		end
    
    		return findItem(vs,@vtx_states)
    	end
    
    	# find shader from material
    	def findShader(m)
    		if m and m.texture
    			stex =  m.texture.filename.upcase
    			s="Tex"
    			s << "Diff" if not m.name.upcase.index("BRIGHT")
    			if stex.index(".TGA") then 
    				s="BlendA" + s
    			end
    			if m.name.upcase.index("GLOSS") then 
    				s="GlossMap"
    				img=@images.addSearch("env_map.ace")
    				# compare image properties
    				0.upto(@textures.length-1) do |e|
    					if @textures.at(e).img==img
    						return @shader_names.addSearch(s)
    					end
    				end		
    				t=STex.new(img)
    				t.mipbias=0
    				@textures.push t
    			end
    		else
    			s="Diffuse"
    		end
    		
    		return @shader_names.addSearch(s)
    	end
    
    	# given a shader index, find the light config
    	def findLightCnf(s)
    		cn=1
    		cn=2 if @shader_names.at(s)=="GlossMap"
    		cn=3 if @shader_names.at(s).index("Bumpmap")
    		cn=4 if @shader_names.at(s)=="Diffuse"
    		return @light_model_cfgs.addSearch(cn)
    	end
    
    	# find image ID
    	def findImage(t)
    		i=t.filename.rindex("\\")
    		i=-1 if not i
    		s=t.filename[i+1..t.filename.rindex(".")].upcase << "ACE"
    		return @images.addSearch(s)
    	end
    	
    
    
    	#'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    
    	# perform the actual file save
    	def saveS()
    		# unicode file
    		@fh.write "\377\376"
    		$\="\015\012"
    		@fh.uprintln "SIMISA@@@@@@@@@@JINX0s1t______"
    		@fh.uprintln ""
    		@fh.uprintln "shape ("
    		
    		
    		shape_header
    		volumes
    		shader_names
    		texture_filter_names
    		points
    		uv_points
    		normals
    		sort_vectors
    		colours
    		matrices
    		images
    		textures
    		light_materials
    		light_model_cfgs
    		vtx_states
    		prim_states
    		lod_controls
    		
    		animations if @anim_nodes.length>0
    		
    		@fh.uprint ")"
    		@fh.close
    	end
    
    	def	shape_header
    		@fh.uprintln "\tshape_header sketchup20 ( 00000000 00000000 )"
    	end
    	
    	def vector(v)
    		@fh.uprint "vector ( "
    		@fh.uprint v.x.to_m.fix.to_s + " "
    		@fh.uprint v.z.to_m.fix.to_s + " "
    		@fh.uprint v.y.to_m.fix
    		@fh.uprintln " )"
    	end
    
    	def normal(v)
    		@fh.uprint "vector ( "
    		@fh.uprint v.x.fix.to_s + " "
    		@fh.uprint v.z.fix.to_s + " "
    		@fh.uprint v.y.fix
    		@fh.uprintln " )"
    	end
    
    	def vol_sphere(v,r)
    		$\=nil
    		@fh.uprint "\t\tvol_sphere ( \015\012\t\t\t"
    		vector v
    		$\="\015\012"
    		@fh.uprintln " " + r.to_m.fix.to_s
    		@fh.uprintln "\t\t)"
    	end
    
    	def volumes
    		@fh.uprint "\tvolumes ( "
    		@fh.uprintln @volumes
    		vol_sphere @bb.center, @bb.diagonal/2.0
    		@fh.uprintln "\t)"
    	end
    	
    	def named_shader(s)
    		@fh.uprintln "\t\tnamed_shader ( " + s + " )"
    	end
    	
    	def shader_names
    		@fh.uprint "\tshader_names ( "
    		@fh.uprintln @shader_names.length
    		@shader_names.each { |s| named_shader s }
    		@fh.uprintln "\t)"				
    	end
    	
    	def	texture_filter_names
    		@fh.uprint "\ttexture_filter_names ( "
    		@fh.uprintln 1
    		@fh.uprintln "\t\tnamed_filter_mode ( MipLinear )"
    		@fh.uprintln "\t)"		
    	end
    	
    	def point(v)
    		@fh.uprint "\t\tpoint ( " + v.x.to_m.fix.to_s + " " + v.z.to_m.fix.to_s + " " + v.y.to_m.fix.to_s
    		@fh.uprintln " )"
    	end
    
    	def	points
    		@fh.uprint "\tpoints ( "
    		@fh.uprintln @points.length
    		@points.each { |e| point e }
    		@fh.uprintln "\t)"		
    	end
    	
    	def uv_point(v)
    		@fh.uprintln "\t\tuv_point ( " + v.x.fix.to_s + " " + (-v.y.fix).to_s + " )"
    	end
    
    	def	uv_points
    		@fh.uprint "\tuv_points ( "
    		@fh.uprintln @uv_points.length
    		@uv_points.each { |e| uv_point e }
    		@fh.uprintln "\t)"		
    	end
    	
    	def	normals
    		@fh.uprint "\tnormals ( "
    		@fh.uprintln @normals.length
    		@normals.each { |e| @fh.uprint "\t\t"; normal e }
    		@fh.uprintln "\t)"		
    	end
    	
    	def	sort_vectors	
    		@fh.uprintln "\tsort_vectors ( 0 )"
    	end
    	
    	def colour(v)
    		@fh.uprintln "\t\tcolour ( " + (v.alpha/255.0).to_s + " " + (v.red/255.0).to_s + " " + (v.green/255.0).to_s  + " " + (v.blue/255.0).to_s + " )"
    	end
    
    	def	colours
    		@fh.uprint "\tcolours ( "
    		@fh.uprintln @colours.length
    		@colours.each { |e| colour e }
    		@fh.uprintln "\t)"		
    	end
    	
    	def matrix(v)
    		
    		@fh.uprint "\t\tmatrix "
    		@fh.uprint v.name
    		@fh.uprint " ( "
    		@fh.uprint v.m[0].fix.to_s + " " + v.m[1].fix.to_s + " " + v.m[2].fix.to_s + " "
    		@fh.uprint v.m[4].fix.to_s + " " + v.m[5].fix.to_s + " " + v.m[6].fix.to_s + " "
    		@fh.uprint v.m[8].fix.to_s + " " + v.m[9].fix.to_s + " " + v.m[10].fix.to_s + " "
    		@fh.uprintln v.m[12].to_m.fix.to_s + " " + v.m[13].to_m.fix.to_s + " " + v.m[14].to_m.fix.to_s + " )"
    		
    		@message << v.name + " " + v.polys.to_s + " Polygons " + (v.polys>2700 ? "<< Primitives split\n" ; "\n")
    		
    	end
    	
    	def	matrices
    		@message="Groups ;\n"
    		@fh.uprint "\tmatrices ( "
    		@fh.uprintln @matrices.length
    		@matrices.each { |e| matrix e }
    		@fh.uprintln "\t)"
    	end
    	
    	def image(v)
    		@fh.uprint "\t\timage ( "
    		@fh.uprint v
    		@fh.uprintln " )"
    	end
    	
    	def	images
    		@fh.uprint "\timages ( "
    		@fh.uprintln @images.length
    		@images.each { |e| image e }
    		@fh.uprintln "\t)"		
    	end
    	
    	def texture(v)
    		@fh.uprint "\t\ttexture ( "
    		@fh.uprint v.to_s
    		@fh.uprintln " ff000000 )"	
    	end
    	
    	def	textures
    		@fh.uprint "\ttextures ( "
    		@fh.uprintln @textures.length
    		@textures.each { |e| texture e }
    		@fh.uprintln "\t)"		
    	end
    	
    	def light_material(v)
    		@fh.uprint "\t\tlight_material ( 00000000 "
    		@fh.uprint v
    		@fh.uprintln " )"		
    	end
    	
    	def	light_materials
    		@fh.uprint "\tlight_materials ( "
    		@fh.uprintln @light_materials.length
    		@light_materials.each { |e| light_material e }
    		@fh.uprintln "\t)"		
    	end
    	
    	def light_model_cfg(v)
    	
    		case v
    		when 1   #  single stage
    			@fh.uprintln "\t\tlight_model_cfg ( 00000000"
    			@fh.uprintln "\t\t\tuv_ops ( 1"
    			@fh.uprintln "\t\t\t\tuv_op_copy ( 1 0 )"
    			@fh.uprintln "\t\t\t)"
    			@fh.uprintln "\t\t)"
    		when 2  # GlossMap
    			@fh.uprintln "\t\tlight_model_cfg ( 00000000"
    			@fh.uprintln "\t\t\tuv_ops ( 2"
    			@fh.uprintln "\t\t\t\tuv_op_copy ( 1 0 )"
    			@fh.uprintln "\t\t\t\tuv_op_reflectmapfull ( 1 )"
    			@fh.uprintln "\t\t\t)"
    			@fh.uprintln "\t\t)"
    		when 3  # 3 stage bump maps
    			@fh.uprintln "\t\tlight_model_cfg ( 00000000"
    			@fh.uprintln "\t\t\tuv_ops ( 3"
    			@fh.uprintln "\t\t\t\tuv_op_copy ( 1 0 )"
    			@fh.uprintln "\t\t\t\tuv_op_copy ( 1 0 )"
    			@fh.uprintln "\t\t\t\tuv_op_reflectmapfull ( 1 )"
    			@fh.uprintln "\t\t\t)"
    			@fh.uprintln "\t\t)"
    		when 4   #  no texture or uv
    			@fh.uprintln "\t\tlight_model_cfg ( 00000000"
    			@fh.uprintln "\t\t\tuv_ops ( 0 )"
    			@fh.uprintln "\t\t)"
    		end
    	
    	end
    	
    	def	light_model_cfgs
    		@fh.uprint "\tlight_model_cfgs ( "
    
    		@fh.uprintln @light_model_cfgs.length
    		@light_model_cfgs.each { |e| light_model_cfg e }
    
    		@fh.uprintln "\t)"		
    	end
    	
    	def vtx_state(v)
    		@fh.uprint "\t\tvtx_state ( 00000000 "
    		@fh.uprint v.to_s
    		@fh.uprintln " 00000002 )"	
    	end
    	
    	def	vtx_states
    		@fh.uprint "\tvtx_states ( "
    
    		@fh.uprintln @vtx_states.length
    		@vtx_states.each { |e| vtx_state e }
    
    		@fh.uprintln "\t)"		
    	end
    	
    	def prim_state(v)
    		@fh.uprint "\t\tprim_state " + @matrices[@vtx_states[v.vState].matrix].name + "_Prim" + v.sequence.to_s + " ( 00000000 "
    		@fh.uprint v.to_s
    		@fh.uprintln " 1\n\t\t)"	
    	end
    	
    	def	prim_states
    		@fh.uprint "\tprim_states ( "
    		@fh.uprintln @prim_states.length
    		seq=0
    		# sort the states in order, and sort the sequence
    		100.downto(96) do |pri|
    			@prim_states.each do |e|
    				if e.priority==pri
    					e.sequence=seq
    					seq+=1
    					prim_state e
    				end
    			end
    		end
    		@prim_states.each do |e|
    			if e.priority<97
    				prim_state e
    				e.sequence=seq
    				seq+=1
    			end
    		end		
    		@fh.uprintln "\t)"		
    	end
    	
    	def geometry_node(v)
    		@fh.uprintln "\t\t\t\t\t\t\t\t\t\tgeometry_node ( 1 0 0 0 0"
    		@fh.uprintln "\t\t\t\t\t\t\t\t\t\t\tcullable_prims ( " + v.pStates.length.to_s + " " + v.count.to_s + " " + (v.count*3).to_s + " )"
    		@fh.uprintln "\t\t\t\t\t\t\t\t\t\t)"
    	end
    	
    	def vertex(v)
    		v.uprint @fh
    	end
    	
    	def vertex_set(v,cnt)
    		@fh.uprintln "\t\t\t\t\t\t\t\tvertex_set ( " + v.vtx_state.to_s + " " + cnt.to_s + " " + v.vertices.length.to_s + " )"
    		
    	end
    	
    	def primitive(v,cnt)
    		v.offset=cnt
    		if v.primstate then
    			@fh.uprintln "\t\t\t\t\t\t\t\tprim_state_idx ( " + @prim_states[v.primstate].sequence.to_s + " )"
    		else
    			v.uprint @fh
    		end
    	end
    	
    	def sub_object(v)
    		@fh.uprintln "\t\t\t\t\t\tsub_object ( "
    		@fh.uprintln "\t\t\t\t\t\t\tsub_object_header ( " + v.flags + " " + v.sortVector.to_s + " " + v.vol.to_s + " 000001d2 " + v.destFlag
    		@fh.uprintln "\t\t\t\t\t\t\t\tgeometry_info ( " + v.faceNormals.to_s + " " + v.vtx_sets.length.to_s + " 0 " + (v.faceNormals*3).to_s + " 0 0 " + (v.primitives/2).to_s + " 0 0 0"
    		@fh.uprint "\t\t\t\t\t\t\t\t\tgeometry_nodes ( "
    		@fh.uprintln v.geometry_nodes.length
    
    		v.geometry_nodes.each { |e| geometry_node e }
    		
    		@fh.uprintln "\t\t\t\t\t\t\t\t\t)"
    		#							geometry_node_map ( 1 0 )
    		@fh.uprint "\t\t\t\t\t\t\t\t\tgeometry_node_map ( "
    		@fh.uprint @matrices.length
    		0.upto(@matrices.length-1) do |e|
    			@fh.uprint " "
    			ind=v.geometry_nodes.index(SGeomnode.new(e))
    			@fh.uprint ind ? ind ; -1
    		end
    		@fh.uprintln " )"
    
    		@fh.uprintln "\t\t\t\t\t\t\t\t)"
    		
    		#						subobject_shaders ( 1 0 )
    		@fh.uprint "\t\t\t\t\t\t\t\tsubobject_shaders ( "
    		@fh.uprint v.shaders.length
    		v.shaders.each { |e| @fh.uprint " "; @fh.uprint e }
    		@fh.uprintln " )"
    
    		#						subobject_light_cfgs ( 1 0 ) 0
    		@fh.uprint "\t\t\t\t\t\t\t\tsubobject_light_cfgs ( "
    		@fh.uprint v.lightcfgs.length
    		v.lightcfgs.each { |e| @fh.uprint " "; @fh.uprint e }
    		@fh.uprintln " ) " + v.id.to_s
    
    		@fh.uprintln "\t\t\t\t\t\t\t)"
    		@fh.uprint "\t\t\t\t\t\t\tvertices ( "
    		@fh.uprintln v.vertices
    
    		v.vtx_sets.each { |x| x.vertices.each { |e| vertex e } }
    		
    		@fh.uprintln "\t\t\t\t\t\t\t)"
    
    		@fh.uprint "\t\t\t\t\t\t\tvertex_sets ( "
    		@lastv=0
    		@fh.uprintln v.vtx_sets.length
    		count=0
    		v.vtx_sets.each { |e| vertex_set e,count ; count+=e.vertices.length }
    		
    		@fh.uprintln "\t\t\t\t\t\t\t)"
    
    
    		@fh.uprint "\t\t\t\t\t\t\tprimitives ( "
    		@fh.uprintln v.primitives
    		
    		count=0
    		v.vtx_sets.each { |x| x.primitives.each { |e| primitive e,count} ; count+=x.vertices.length }
    
    		@fh.uprintln "\t\t\t\t\t\t\t)"
    		# end of sub_object
    		@fh.uprintln "\t\t\t\t\t\t)"
    
    	end
    	
    	def distance_level(v)
    	
    		@fh.uprintln "\t\t\t\tdistance_level ( "
    		@fh.uprintln "\t\t\t\t\tdistance_level_header ("
    		@fh.uprint "\t\t\t\t\t\tdlevel_selection ( "
    		@fh.uprint v.distance
    		@fh.uprintln " )"
    		
    		@fh.uprint "\t\t\t\t\t\thierarchy ( "
    		@fh.uprint v.hierarchy.length
    		v.hierarchy.each { |e| @fh.uprint " "; @fh.uprint e }
    		@fh.uprintln " )"
    		
    		@fh.uprintln "\t\t\t\t\t)"		
    
    		@fh.uprint "\t\t\t\t\tsub_objects ( "
    		@fh.uprintln v.sub_objects.length
    		v.sub_objects.each { |e| sub_object e }
    		@fh.uprintln "\t\t\t\t\t)"		
    
    		@fh.uprintln "\t\t\t\t)"		
    	
    	end
    	
    	def lod_control
    		@fh.uprintln "\t\tlod_control ("
    		@fh.uprintln "\t\t\tdistance_levels_header ( 0 )"
    		@fh.uprint "\t\t\tdistance_levels ( "
    		@fh.uprintln @distance_levels.length
    		
    		@distance_levels.each { |e| distance_level e }
    
    		@fh.uprintln "\t\t\t)"
    		@fh.uprintln "\t\t)"
    	end
    	
    	def	lod_controls
    		@fh.uprintln "\tlod_controls ( 1"
    		lod_control
    		@fh.uprintln "\t)"		
    	end
    	
    	def anim_node(v)
    		@fh.uprint "\t\t\t\tanim_node "
    		@fh.uprint v.name
    		@fh.uprintln " ("
    		
    		# still to do
    		
    		@fh.uprintln "\t\t\t\t)"
    	end
    	
    	def	animations
    		@fh.uprintln "\tanimations ( 1"
    		@fh.uprintln "\t\tanimation ( " + @keys.to_s + " " + @fps.to_s
    		@fh.uprint "\t\t\tanim_nodes ( "
    		
    		@fh.uprint @anim_nodes.length
    		@anim_nodes.each { |e| anim_node e }
    		
    		@fh.uprintln "\t\t\t)"
    		@fh.uprintln "\t\t)"
    		@fh.uprintln "\t)"		
    	end
    
    
    	# on creation of the TMXfile object
    	def initialize(model,file)
    		# set a few properties
    		@model=model
    		@name=model.title
    		@fileName=file
    		@shader_names=[]
    		@points=[]
    		@normals=[]
    		@uv_points=[]
    		@matrices=[]
    		@colours=[]
    		@images=[]
    		@textures=[]
    		@light_materials=[]
    		@light_model_cfgs=[]
    		@vtx_states=[]
    		@prim_states=[]
    		@distance_levels=[]
    		@anim_nodes=[]
    		@keys=8
    		@fps=30
    		@specular=false
    		@fh = File.new(file,"wb")
    		
    		if @fh then
    			@tw = Sketchup.create_texture_writer
    			# get model bound box
    			@bb=model.bounds
    			@volumes=1
    			# add a single distance level
    			@distance_levels.push SDLevel.new()
    			# add first sub-object
    			@distance_levels[0].sub_objects.push SSObject.new()
    			l=@model.lods[0]
    			@distance_levels[0].distance=l
    			print "\nLOD #{l} 0"
    			# scan the model geometry
    			@lastMatrixid=nil
    			scanModel1(model,-1,0,nil,l)
    			
    			# more layers?
    			1.upto(@model.lods.length-1) do |lay|
    				@lastMatrixid=0
    				l=@model.lods[lay]
    				# add a single distance level
    				@distance_levels.push SDLevel.new()
    				dl=@distance_levels.length-1
    				# add first sub-object
    				@distance_levels[dl].sub_objects.push SSObject.new()
    				# adjust previous DL
    				@distance_levels[dl].distance=l
    				print "\nLOD #{l} #{dl}"
    				scanModel1(model,-1,dl,nil,l.to_i)
    			end
    			
    			
    			# sum up vertices and primitives
    			@distance_levels.each do |dl|
    				dl.sub_objects.each do |so|
    					so.vtx_sets.each do |v|
    						so.vertices+=v.vertices.length
    						so.primitives+=v.primitives.length
    					end
    					if @specular
    						if so.flags=="00000400"
    							so.flags="00000000"
    						else
    							so.flags="00000100"
    						end
    					end
    				end
    			end
    		end
    		# model processing finished - time to save the S file
    	end
    	
    	def saveSD()
    		@fh = File.new(@fileName + "D","wb")
    		# unicode file
    		@fh.write "\377\376"
    		$\="\015\012"
    		@fh.uprintln "SIMISA@@@@@@@@@@JINX0s1t______"
    		@fh.uprintln ""
    		@fh.uprint "shape ( "
    		s=@fileName
    		i=s.rindex("\\")
    		s=s[(i+1)..s.length] if i
    		@fh.uprintln s
    		@fh.uprintln "    ESD_Detail_Level (0)"
    		@fh.uprintln "    ESD_Software_DLev (0)"
    		@fh.uprintln "    ESD_Alternative_Texture (0)"
    		@fh.uprintln "    ESD_Bounding_Box ( " + @bb.min.x.fix.to_m.to_s + " " + @bb.min.z.fix.to_m.to_s + " " + @bb.min.y.fix.to_m.to_s + " " + @bb.max.x.fix.to_m.to_s + " " + @bb.max.z.fix.to_m.to_s + " " + @bb.max.y.fix.to_m.to_s + " )"
    		@fh.uprintln ")"
    		@fh.close()
    	end
    end
    
    
    
    ####################################################################
    # add unicode write to File class
    class File
    	def uprint(s)
    		# print unicode version of ascii
    		s.to_s.each_byte { |c| write [c,0].pack("cc") } if s
    	end
    	def uprintln(s)
    		uprint s
    		uprint $\ if $\
    	end
    end
    
    ####################################################################
    # used by textures array
    class STex
    	attr_accessor ;img,;filter,;mipbias
    	def initialize(id)
    		@mipbias = -3
    		@filter=0
    		@img=id
    	end
    	def to_s
    		@img.to_s + " " + @filter.to_s + " " + @mipbias.to_s
    	end
    end
    
    ####################################################################
    # used by vtx_states
    class SVState
    	attr_accessor ;matrix,;lightMat,;lightCfg
    	def initialize(id)
    		@lightCfg=0
    		@lightMat=-5
    		@matrix=id
    	end
    	def ==(vs)
    		return (@lightMat==vs.lightMat and @lightCfg == vs.lightCfg and @matrix==vs.matrix)
    	end
    	def to_s
    		@matrix.to_s + " " + @lightMat.to_s + " " + @lightCfg.to_s
    	end
    end
    
    ####################################################################
    # prim state
    class SPState
    	attr_accessor ;shader, ;tex_idxs,;zBias,;vState,;alphatestmode,;lightCfg,;priority,;sequence
    	def initialize
    		@tex_idxs=[]
    		@zBias=0
    		@priority=100
    		@alphatestmode=0
    	end
    	
    	def ==(o)
    		if @tex_idxs.length>0
    			return false if @tex_idxs.length!=o.tex_idxs.length
    			return false if @tex_idxs[0]!=o.tex_idxs[0]
    		end
    		return (@shader==o.shader and @vState==o.vState and @alphatestmode==o.alphatestmode and @lightCfg==o.lightCfg)
    	end
    	
    	def to_s
    		s=@shader.to_s + "\n\t\t\ttex_idxs ( " + @tex_idxs.length.to_s
    		tex_idxs.each { |e| s << " " << e.to_s  }
    		s << " ) " + @zBias.to_s + " " + @vState.to_s + " " + @alphatestmode.to_s + " " + @lightCfg.to_s
    	end
    end
    ####################################################################
    class SDLevel
    	attr_accessor ;distance, ;hierarchy,;sub_objects
    	def initialize
    		@hierarchy=[]
    		@distance=2000
    		@sub_objects=[]
    	end
    end
    
    ####################################################################
    class SSObject
    	attr_accessor ;vertices,;primitives,;vtx_sets,;sortVector,;vol,;destFlag,;flags,;faceNormals,;txLightCmds,;trilistIdxs,;trilists,;geometry_nodes,;lightcfgs,;shaders,;id
    	def initialize
    		@vertices=0
    		@primitives=0
    		@vtx_sets=[]
    		@sortVector=-1
    		@vol=-1
    		@destFlag="000001c4"
    		@flags="00000400"
    		@geometry_nodes=[]
    		@lightcfgs=[]
    		@shaders=[]
    		@id=0
    		@faceNormals=0
    		@txLightCmds=0
    		@trilistIdxs=0
    		@trilists=0
    	end
    end
    ####################################################################
    class SVertex
    	attr_accessor ;pointIdx, ;normalIdx ,;colour1,;colour2, ;vertex_uvs
    	def initialize
    		@vertex_uvs=[]
    		@colour1="ffffffff"
    		@colour2="ff000000"
    	end
    	def ==(o)
    		if @vertex_uvs.length>0
    			return false if @vertex_uvs.length!=o.vertex_uvs.length
    			return false if @vertex_uvs[0]!=o.vertex_uvs[0]
    		end
    		return (@pointIdx==o.pointIdx and @normalIdx==o.normalIdx)
    	end
    	def uprint(fh)
    		fh.uprint "\t\t\t\t\t\t\t\tvertex ( 00000000 " + @pointIdx.to_s + " " + @normalIdx.to_s + " " + @colour1 + " " + @colour2 + "\n\t\t\t\t\t\t\t\t\t vertex_uvs ( " + @vertex_uvs.length.to_s
    		@vertex_uvs.each { |e| fh.uprint " " + e.to_s }
    		fh.uprintln " )\n\t\t\t\t\t\t\t\t)"
    	end
    end
    
    class SVtxset
    
    	attr_accessor ;vtx_state,  ;vertices, ;primitives
    	
    	def initialize(vs)
    		@vtx_state=vs
    		@vertices=[]
    		@primitives=[]
    	end
    	def ==(o)
    		return @vtx_state==o.vtx_state
    	end
    end
    
    
    ####################################################################
    class SGeomnode
    	attr_accessor ;pStates, ;count,;matrix
    	def initialize(id)
    		@pStates=[]
    		@count=0
    		@matrix=id
    	end
    	def ==(o)
    		return (@matrix == o.matrix)
    	end
    end
    
    ####################################################################
    class SPrimitive
    	attr_accessor ;vert_idxs, ;normal_idxs, ;primstate, ;offset
    	def initialize
    		@vert_idxs=[]
    		@normal_idxs=[]
    	end
    	def ==(o)
    		return @primstate==o.primstate
    	end
    	def uprint(fh)
    		fh.uprintln "\t\t\t\t\t\t\t\tindexed_trilist ("
    		fh.uprint "\t\t\t\t\t\t\t\t\tvertex_idxs ( " + @vert_idxs.length.to_s
    		width=0
    		@vert_idxs.each do |e|
    			fh.uprint " " + (e+@offset).to_s
    			if width>1000 then
    				fh.uprint "\015\012\t\t\t\t\t\t\t\t\t"
    				width=0
    			else
    				width+=e.to_s.length
    			end
    		end
    		fh.uprintln " )"
    		fh.uprint "\t\t\t\t\t\t\t\t\tnormal_idxs ( " + @normal_idxs.length.to_s
    		
    		width=0
    		@normal_idxs.each do |e|
    			fh.uprint " " + e.to_s + " 3"
    			if width>1000 then
    				fh.uprint "\015\012\t\t\t\t\t\t\t\t\t"
    				width=0
    			else
    				width+=e.to_s.length
    			end
    		end
    		fh.uprintln " )"
    		
    		fh.uprint "\t\t\t\t\t\t\t\t\tflags ( " + @normal_idxs.length.to_s
    		width=0
    		@normal_idxs.each do |e|
    			fh.uprint " 00000000"
    			if width>1000 then
    				fh.uprint "\015\012\t\t\t\t\t\t\t\t\t"
    				width=0
    			else
    				width+=9
    			end
    		end
    		
    		fh.uprintln " )"
    		fh.uprintln "\t\t\t\t\t\t\t\t)"
    	end
    end
    ####################################################################
    # extend 3dmath class matrix
    class Matrix
    	# add name attribute
    	attr_accessor ;name,;polys
    	# copy array to matrix (from SU transromation.to_a
    	def setFromSU(mIn)
    		@m=mIn
    		# swap 2nd/3rd rows and cols
    		@m[2],@m[1]=@m[1],@m[2]
    		@m[10],@m[5]=@m[5],@m[10]
    		@m[14],@m[13]=@m[13],@m[14]
    		@m[4],@m[8]=@m[8],@m[4]
    		@m[6],@m[9]=@m[9],@m[6]
    		@m[7],@m[11]=@m[11],@m[7]
    	end
    end
    ####################################################################
    class Numeric
    	# use 6 decimal places only
    	def fix
    		(self*1000000.0).to_i.to_f/1000000.0
    	end
    end
    
    ####################################################################
    # return index, but add if not found in array
    class Array
    	def addSearch(s)
    		e=index(s)
    		if e then
    			return e
    		else
    			push s
    			return length-1
    		end
    	end
    end
    
    1 Reply Last reply Reply Quote 0
    • 1 / 1
    1 / 1
    • First post
      1/1
      Last post
    Buy SketchPlus
    Buy SUbD
    Buy WrapR
    Buy eBook
    Buy Modelur
    Buy Vertex Tools
    Buy SketchCuisine
    Buy FormFonts

    Advertisement