Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Modifying Mesh Vertices

edited March 2012 in Questions Posts: 65

Hi,

I'm using this star burst effect I created (feel free to use it if you like it) but I've got a feeling that my method for animating the mesh's vertices is not optimal. Basically I'm iterating over the existing mesh.vertices, modifying each vertex and copying it into a new table, then setting mesh.vertices to the new table. See the StarburstView:update() method for that code. Is there a more efficient way? I've tried modifying each vertex in place (eg: mesh.virtices[i].x = whatever) as well as removing and reinserting vertices into the existing mesh.vertices table, but neither of those things seemed to work at all (it was as if mesh.vertices is immutable).

Any advice appreciated, cheers!



--# Main displayMode(FULLSCREEN) -- Use this function to perform your initial setup function setup() c = color(255, 103, 0, 224) starburstView = StarburstView(WIDTH/2, HEIGHT/2, WIDTH/1.5, 3, 20, c) end -- This function gets called once every frame function draw() -- This sets a dark background color background(0, 0, 0, 255) -- This sets the line thickness strokeWidth(5) fill(243, 9, 9, 255) -- Do your drawing here starburstView:draw() end --# StarburstView StarburstView = class() function StarburstView:init(x, y, radius, lifetime, numRays, colour) -- you can accept and set parameters here self.x = x self.y = y self.radius = radius self.lifetime = lifetime self.numRays = numRays self.lifetimeLeft = self.lifetime self.maxSwellTime = self.lifetime / 2 self.swellRadsPerTime = math.rad(180 / self.lifetime) self.currentSwellRad = math.rad(0) local brt = 100 self.colour = color(colour.r+brt, colour.g+brt, colour.b+brt, colour.a) self.colourVar = 100 -- how much the colour can vary from the original in each channel self:buildMesh() end function StarburstView:buildMesh() self.mesh = mesh() self.raySpeeds = {} local vertices = {} local colours = {} for rayNum = 1, self.numRays do local rotation = math.rad(math.random(360)) local rotWidth = math.rad(math.random(40)) local rndRad = self.radius * (1+math.random()) local v1 = vec2(0,0) local v2 = vec2(0, rndRad):rotate(rotation) local v3 = vec2(0, rndRad):rotate(rotation + rotWidth) table.insert(vertices, v1) table.insert(vertices, v2) table.insert(vertices, v3) table.insert(colours, self:randomColour()) table.insert(colours, self:randomColour()) table.insert(colours, self:randomColour()) self:addRandomSpeeds(rotWidth) end self.mesh.vertices = vertices self.mesh.colors = colours end function StarburstView:addRandomSpeeds(rotWidth) local speed = math.rad(math.random(50, 200)) local catchupSpeed = rotWidth / self.lifetime table.insert(self.raySpeeds, speed + catchupSpeed) -- first edge table.insert(self.raySpeeds, speed) -- second edge end function StarburstView:randomColour() local r = self:randomColourChanel(self.colour.r) local g = self:randomColourChanel(self.colour.g) local b = self:randomColourChanel(self.colour.b) return color(r, g, b, 128) end function StarburstView:randomColourChanel(chanel) return chanel - self.colourVar + math.random(self.colourVar*2) end function StarburstView:update() local newVertices = {} for rayNum = 1, self.numRays do local i = ((rayNum-1) * 3) + 1 local v1 = self.mesh.vertices[i] local v2 = self.mesh.vertices[i+1] local v3 = self.mesh.vertices[i+2] local j = ((rayNum-1) * 2) + 1 local edge1Speed = self.raySpeeds[j] local edge2Speed = self.raySpeeds[j+1] v2 = v2:rotate(edge1Speed * DeltaTime) v3 = v3:rotate(edge2Speed * DeltaTime) table.insert(newVertices, v1) table.insert(newVertices, v2) table.insert(newVertices, v3) end self.mesh.vertices = newVertices self.lifetimeLeft = self.lifetimeLeft - DeltaTime self.currentSwellRad = self.currentSwellRad + self.swellRadsPerTime * DeltaTime end function StarburstView:draw() if self.lifetimeLeft >= 0 then pushMatrix() pushStyle() self:update() translate(self.x, self.y) scale(math.sin(self.currentSwellRad)) self.mesh:draw() popMatrix() popStyle() end end

Comments

  • SimeonSimeon Admin Mod
    Posts: 4,927

    Looks great! Just tried it out. Very cool effect.

    We've added the following functions in the next update. These make it more efficient to access single, or small numbers of vertices in mesh — they do not require updating the whole table and instead index the existing vertex buffer.

    v = mesh:vertex( index ) -- Read vertex at indes
    
    -- Set vertex at index
    mesh:vertex( index, x, y )
    mesh:vertex( index, x, y, z )
    mesh:vertex( index, vec2 )
    mesh:vertex( index, vec3 )
    
    v = mesh:color( index ) -- Read color at indes
    
    -- Set color at index
    mesh:color( index, r, g, b )
    mesh:color( index, r, g, b, a )
    mesh:color( index, color )
    
    v = mesh:texCoord( index ) -- Read texCoord at indes
    
    -- Set texCoord at index
    mesh:texCoord( index, x, y )
    mesh:texCoord( index, vec2 )
    
    mesh.size -- Get number of vertices in mesh
    
  • Posts: 65

    Cool I'll give that a shot when it comes out - might be able to up the number of rays I'm using :). Thanks!

  • edited March 2012 Posts: 65

    Hi,

    Now that mesh vertices are 3D, what's the best idom for rotating them in 2D space, instead of what I had above as this (which no longer works):

    local v2 = self.mesh.vertices[i+1]
    ...
    v2 = v2:rotate(edge1Speed * DeltaTime)
    

    Thanks!

  • SimeonSimeon Admin Mod
    Posts: 4,927

    @peteroyle it should work in 1.3.6 (it will use a 2D vector rotate if you call v:rotate on a vec3). However for now you can do:

    local v2 = self.mesh.vertex( i + 1 ) -- This is faster than mesh.vertices!
    v2 = vec2(v2.x,v2.y):rotate( edgelSpeed * DeltaTime )
    
  • Posts: 65

    Thanks Simeon. I'll switch to mesh.vertex and use the vec2 workaround for the time being.

Sign In or Register to comment.