X3D Loader

I’m finishing up my X3D Loader code which uses local caching and Dropbox support for pulling models. One problem that I’ve come across that bothers me, though - I am using string splitting to do the heavy lifting, and it seems that the split() function I have found online in the Lua forums is slow. I’d LOVE to use an unpack() off of a string, but I don’t see any way to do that except to pack strings into a table (which is what I am doing now).

Anyone have a high performing string splitter?

Screenshots don’t work with on my iPad 3 with iOS 6 while the video is running, don’t know why…

Video here: http://www.youtube.com/watch?v=hhR9qD9eiy4&feature=share&list=UUws5tivGh67Ik0aw1i0HQeA

Wow, very nice work. X3D is a complicated format, it must have been a lot of work to parse.

3D models are something I’d like to consider having built-in. But I wouldn’t want to do it wrong, so it’s something to think about for post version 1.5.

Regarding string splitting — have you tried the Lua’s string.gmatch and string.gsub? They work with captures, so they should be helpful for parsing. Though I’m not sure how fast they are (they are native, so I wouldn’t expect them to be slow). There are some examples of splitting here, though I’m sure you’ve already seen this: http://lua-users.org/wiki/SplitJoin

Looks great. I use string.gmatch in my ply loader which is fast enough for me, but i think, my files are smaller, as you load a complete scene. it splits the strings with some kind of regexps.

I used the XmlParser lua project online to do the parsing of the xml file and only look at a few nodes. I have a few debugging statement sand a texture bug to work out, but the core code is like this:

function ReadX3D:ProcessScene()
    -- find scene
    self.renderitems={}
    for i,xmlNode in pairs(self.ParsedFile.ChildNodes) do
        --if (self.elapsed) then coroutine.yield() end
        if (xmlNode.Name=="Head") then end
        --if (xmlNode.Name=="Group") then  for i,masterXmlNode in pairs(xmlNode.ChildNodes) do  
        if (xmlNode.Name=="Scene") then         -- stuff i care about
            for i,subXmlNode in pairs(xmlNode.ChildNodes) do
                -- we dont account for group yet
                if(subXmlNode.Name=="Shape") then
                    --log (subXmlNode.Name)
                    -- create a new shape
                    self.newItem=mesh()
                    for i,subXmlNode2 in pairs(subXmlNode.ChildNodes) do  
                        --log(subXmlNode2.Name) 
                        if(subXmlNode2.Name=="IndexedFaceSet") then
                            self:ParseIFS(subXmlNode2, self.newItem)  
                        end
                        if (subXmlNode2.Name=="Appearance") then
                            self:parseAppearance(subXmlNode2, self.newItem)
                        end
                    end
                    --log("texCoords before insert:"..#self.newItem.texCoords)
                    -- put new shape in a table for later rendering
                    table.insert(self.renderitems, self.newItem)
                end
            end
        end
        -- if we have urls to load, do so...
        if (#self.d.files>0) then
            self.d:LoadAll(self.newItem). -- use lazy loading to get any textures...
        end 
    end
end