1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Two Factor Authentication is now available on BeyondUnreal Forums. To configure it, visit your Profile and look for the "Two Step Verification" option on the left side. We can send codes via email (may be slower) or you can set up any TOTP Authenticator app on your phone (Authy, Google Authenticator, etc) to deliver codes. It is highly recommended that you configure this to keep your account safe.

Better Inf map editing with sketchup

Discussion in 'Infiltration Development' started by Silver_Ibex, Feb 21, 2011.

  1. Silver_Ibex

    Silver_Ibex Member

    Joined:
    Feb 27, 2001
    Messages:
    654
    Likes Received:
    0
    While chatting on IRC I saw this posted during a discussion of better optimizing of workflow in Ued with external modeling programs, it is a handy ruby script for exporting multiple brushes out of Ued so they can be edited in Sketchup with less work then exporting them one at a time.

    To make a new Ruby file, do the following
    In your Google Sketchup plugins folder, make a new txt file and rename it “Ued_T3D_Multi-Brush_Import.rb”
    And then copy and past into it the code below and save the file.

    Code:
    #===========================================================================================
    # Ued_T3D_Multi-Brush_Import.rb                                                            
    #===========================================================================================
    # This script lets Ued mappers build better custom complex  
    # brushes for their maps with the help of Sketchup.
    # 
    # Place this file in Sketchup "plugins" folder.
    #
    #
    #
    # To use follow these mapping steps. 
    # 
    # 1. Load your map in Ued. 
    # 
    # 2. Select the brushes you want to export in your map then 
    #    invert the selection and delete everything else in the map.
    # 
    # 3. To make the exported file smaller/faster you can rebuild 
    #    the paths (this is to clear the paths out so they don’t get 
    #    exported as part of the .t3d file).
    # 
    # 4. Select all brushes and chose “transform permanently” (the 
    #    Sketchup importer does not see any temporary transform 
    #    scaling and rotations).
    # 
    # 5. You can rebuild the geometry and fix or align textures now 
    #    if you want.     
    # 
    # 6. Export the map as a .t3d file.
    # 
    # 7. In Sketchup, chose import file type "Ued T3D Level File",
    #    and you should then be able to open your .t3d file.
    # 
    # 8. Have fun :)  
    # 
    # 9. to get the stuff back out of Sketchup and back into Ued, 
    #    use Google Sketchup T3D/PSK Exporter for UT3/UT2K4/UT2K3 
    #    - HSKP2UNR found at 
    #    http://forums.epicgames.com/showthread.php?t=619593 
    # 
    class Polygon
      def initialize(texname)
        @vertices = []
        @origin = nil
        @texname = texname
      end
    
      def parse(line)
        if (m = line.match(/Origin(.*),(.*),(.*)/i))
          @origin = Geom::Point3d.new Float(m[1]), Float(m[2]), Float(m[3])
        elsif (m = line.match(/Normal(.*),(.*),(.*)/i))
          @normal = Geom::Vector3d.new Float(m[1]), Float(m[2]), Float(m[3])
        elsif (m = line.match(/TextureU(.*),(.*),(.*)/i))
          @texu = Geom::Vector3d.new Float(m[1]), Float(m[2]), Float(m[3])
        elsif (m = line.match(/TextureV(.*),(.*),(.*)/i))
          @texv = Geom::Vector3d.new Float(m[1]), Float(m[2]), Float(m[3])
        elsif (m = line.match(/Vertex(.*),(.*),(.*)/i))
          @vertices.push(Geom::Point3d.new(Float(m[1]), Float(m[2]), Float(m[3])))
        elsif line.match(/End Polygon/i)
          return true
        end
        return false
      end
    
      def build(transform, group)
        wverts = []
        uvs = []
        idx = 0
        if @vertices.length <= 3
          @vertices.each {|x|
            wverts.push(x.transform(transform))
          }
        else
            wverts.push(@vertices[0].transform(transform))
            wverts.push(@vertices[1].transform(transform))
            wverts.push(@vertices[2].transform(transform))
            v1 = wverts[1] - wverts[0]
            v2 = wverts[2] - wverts[0]
            n = v1.cross(v2)
            plane = [wverts[0], n]
            @vertices.each {|x|
              v = x.transform(transform)
              wverts.push(v.project_to_plane(plane))
            }
        end
        uvs.push(@origin.transform(transform))
        uvs.push(Geom::Point3d.new(0, 0, 0))
        u = @origin + @texu
        v = @origin + @texv
        uvs.push(u.transform(transform))
        uvs.push Geom::Point3d.new(1, 0, 0)
        uvs.push(v.transform(transform))
        uvs.push Geom::Point3d.new(0, 1, 0)
        face = group.entities.add_face wverts
        @texname = "default" if not @texname
        mat = Sketchup.active_model.materials[@texname]
        if not mat
          mat = Sketchup.active_model.materials.add @texname
          mat.texture = @texname + ".jpg"
          if not mat.texture
            file = Sketchup.find_support_file "default.png", "Plugins/"
            mat.texture = file
          end
        end
        face.material = mat
        face.position_material(face.material, uvs, true)
        face.position_material(face.material, uvs, false)
      end
    end
    
    class Brush
      def initialize(name)
        @group = Sketchup.active_model.entities.add_group
        @group.name = name
        @polygons = []
      end
    
      def parse(line)
        if @polygon
          if @polygon.parse(line)
            @polygon = nil
          end
          return false
        end
        if line.match(/Begin Polygon/i)
          m = line.match(/Texture=([._A-Za-z0-9]+)/)
          if m
            texname = m[1]
          else
            texname = "default"
          end
          @polygon = Polygon.new(texname)
          @polygons.push(@polygon)
        elsif line.match(/End Brush/i)
          return true
        end
        return false
      end
    
      def build(transform)
        @polygons.each { |poly|
          poly.build(transform, @group)
        }
      end
    end
    
    class Actor
      def initialize(name)
        @name = name
        @unit_adjust = Geom::Transformation.scaling(0.749906262,-0.749906262,0.749906262)
        @main_scale = Geom::Transformation.new
        @pre_pivot = Geom::Transformation.new
                  @location = Geom::Transformation.new
        @brushes = []
      end
    
      def parse(line)
        if @brush
          if @brush.parse(line)
            @brush = nil
          end
          return false
        end
        if line.match(/OldLocation/)
          # Explicitly skip this
          return false
        elsif line.match(/Location/)
          pos = [0.0, 0.0, 0.0]
          m = line.match(/X=([-0-9.]*)/)
          pos[0] = Float(m[1]) if m
          m = line.match(/Y=([-0-9.]*)/)
          pos[1] = Float(m[1]) if m
          m = line.match(/Z=([-0-9.]*)/)
          pos[2] = Float(m[1]) if m
          @location = Geom::Transformation.translation(Geom::Vector3d.new(pos[0], pos[1], pos[2]))
        elsif line.match(/PrePivot/)
          pos = [0.0, 0.0, 0.0]
          m = line.match(/X=([-0-9.]*)/)
          pos[0] = Float(m[1]) if m
          m = line.match(/Y=([-0-9.]*)/)
          pos[1] = Float(m[1]) if m
          m = line.match(/Z=([-0-9.]*)/)
          pos[2] = Float(m[1]) if m
          @pre_pivot = Geom::Transformation.translation(Geom::Vector3d.new(-pos[0], -pos[1], -pos[2]))
        elsif line.match(/MainScale/)
          scale = [1.0, 1.0, 1.0]
          m = line.match(/X=([-0-9.]*)/)
          scale[0] = Float(m[1]) if m
          m = line.match(/Y=([-0-9.]*)/)
          scale[1] = Float(m[1]) if m
          m = line.match(/Z=([-0-9.]*)/)
          scale[2] = Float(m[1]) if m
          @main_scale = Geom::Transformation.scaling scale[0], scale[1], scale[2]
        elsif line.match(/PostScale/)
          scale = [1.0, 1.0, 1.0]
          m = line.match(/X=([-0-9.]*)/)
          scale[0] = Float(m[1]) if m
          m = line.match(/Y=([-0-9.]*)/)
          scale[1] = Float(m[1]) if m
          m = line.match(/Z=([-0-9.]*)/)
          scale[2] = Float(m[1]) if m
          elsif line.match(/Begin Brush/i)
          name = line.match(/NAME=([^\\b]*)/i)[1]
          @brush = Brush.new(name)
          @brushes.push(@brush)
        elsif line.match(/End Actor/i)
          return true
        end
        return false
      end
    
      def build
        transform = @unit_adjust * @location * @pre_pivot * @main_scale
        @brushes.each { |brush|
          brush.build(transform)
        }
      end
    end
    
    class UDKImporter < Sketchup::Importer
      def description
        return "Ued T3D Level File (*.t3d)"
      end
    
      def file_extension
        return "t3d"
      end
    
      def id
        return "com.tosos.sketchup.importers.UDK"
      end
    
      def supports_options?
        return false
      end
    
      def do_options
      end
    
      def parse_line(line)
        if @actor
          if @actor.parse(line)
            @actor = nil
          end
          return
        end
        if line.match(/Begin Actor/i)
          name = line.match(/NAME=([^\\b]*)/i)[1]
          @actor = Actor.new(name)
          @actors.push(@actor)
        end
      end
    
      def load_file(file_path, status)
        @actors = []
    
        File.open(file_path, "r") do |infile|
          while (line = infile.gets)
            parse_line line
          end
          @actors.each { |a|
           a.build
          }
          @actors = nil
          return 0
        end
    
        return 1
      end
    end
    
    Sketchup.register_importer(UDKImporter.new)
    
    
     
  2. Corporal_Lib [BR]

    Corporal_Lib [BR] Brazilian Graphic Designer & Gun Nut {=)

    Joined:
    Oct 14, 2004
    Messages:
    524
    Likes Received:
    0
    After all Inigo weapon releases, a Silver_Ibex map would breath a lil life to INF´s community... a map or that HUMVEE driveable in INF that could save a lot of COOP time or even better, a huuuge map, with your photorealistc landscape technique and scripted Humvees to transport the players around multiple objectives (an EAS map for sure...)

    OK, just excuse my daydreaming, but I was aching to ask ya that ;D
     
  3. Silver_Ibex

    Silver_Ibex Member

    Joined:
    Feb 27, 2001
    Messages:
    654
    Likes Received:
    0
    Thought I should post a pic showing what imported and edited brushes look like in Sketchup, since they are imported as separate objects they can be moved around and adjusted in Sketchup, unlike HSKP2UNR which merges brushes on import into one object.

    Sketchup is Free, and is extremely powerful for fast editing of brushes made in Ued, the plug-in allows multiple brushes to be imported into Sketchup and then selectively joined or split at will (use the “Explode” and “Make Group” options), brush faces can be modified with far more freedom then standard Ued, you can literally draw new features on the faces of a brush in Sketchup.

    In Sketchup the grid scale options need set up to match an external editor like is talked about the page of this article here
    http://www.maximumpc.com/article/howtos/howto_make_left_4_dead_map_using_google_sketchup?page=0,4

    The one small problem I have with the plug-in is faces on imported brushes sometimes face the wrong way and some may need flipped before you export them back out of Sketchup. This is not a real big deal, just something to watch out for.

    For a fast start, the Google Sketchup tutorial videos are a must watch.
     

    Attached Files:

Share This Page