Help: Plug in bug
-
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
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register LoginAdvertisement