#A ring library

1 messages · Page 1 of 1 (latest)

vestal wraith
#

Neat. What's it called?

vagrant cloak
high sierra
#

i am confusing it with Circles!

vestal wraith
#

I understand the confusion. I, too, believed that Circles! was capable of a lot more

stiff canyon
#

Rings!, Circles!, what's next?

vestal wraith
#

I will be dropping my magnum opus, Ovals! soon

vagrant cloak
#

I mean technically I've also made Cubes!

vestal wraith
#

Show us!

vagrant cloak
#

Squares are 2D though

empty cove
#

my screen is 2d

#

as long as they are not leaving my screen and come outside they are 2d for me catsit

odd knoll
vagrant cloak
#

Sounds like a satisfied customer to me

near phoenix
#

@vagrant cloak Don't forget to update the Gist with the missing color

vagrant cloak
#

Did I forget the color again

near phoenix
#

Seems like it

#

I just grabbed the code to start converting it into a wiki example

vagrant cloak
#

Lol fucking hell of course I did

#

Let me finish my food and fix it

near phoenix
#

So

#

In many of the places that someone would want this kind of ring effect, they probably wouldn't actually want it to be sphere-based, but instead a cylinder

vagrant cloak
#

Yeah, in many cases you would probably want a cylinder instead

#

No built-in method for drawing those though

near phoenix
#

Plus it's gotta be somewhat expensive to generate a sphere mesh every frame with render.DrawSphere

vagrant cloak
#

I don't know the performance difference between render.DrawSphere and all of the stuff involved with manually creating an IMesh and drawing that instead

near phoenix
#

So really the way to do this is to generate IMeshes for the shapes and cache the most recent handful of them so they can be looked up easily

near phoenix
#

But I think we can safely say that NOT generating a mesh every frame is going to be more efficient than generating a mesh every frame

vagrant cloak
#

Oh look, found it

#

He says, before opening the file in question and seeing

void CRender::DrawSphere( const Vector &vCenter, int nRadius )
{
    Assert(0);
}
near phoenix
#

I'm hoping Rubat will slide me the source for render.DrawSphere so I can convert it to lua and do some performance comparison testing

vagrant cloak
#

Well there is the source for DrawBox

#
void CRender::DrawBox( const Vector &vMins, const Vector &vMaxs, bool bFill)
{
    Vector points[8];
    PointsFromBox( vMins, vMaxs, points );

    if ( bFill )
    {
        Assert(0);
    }
    else
    {
        // Draw the box bottom, top, and one corner edge.

        meshBuilder.Begin( m_pMesh, MATERIAL_LINE_STRIP, 9 );

        meshBuilder.Position3fv( &points[0].x );
        meshBuilder.Color4ubv( (byte*)&m_DrawColor );
        meshBuilder.AdvanceVertex();

        meshBuilder.Position3fv( &points[1].x );
        meshBuilder.Color4ubv( (byte*)&m_DrawColor );
        meshBuilder.AdvanceVertex();

        meshBuilder.Position3fv( &points[3].x );
        meshBuilder.Color4ubv( (byte*)&m_DrawColor );
        meshBuilder.AdvanceVertex();

        meshBuilder.Position3fv( &points[2].x );
        meshBuilder.Color4ubv( (byte*)&m_DrawColor );
        meshBuilder.AdvanceVertex();

        meshBuilder.Position3fv( &points[6].x );
        meshBuilder.Color4ubv( (byte*)&m_DrawColor );
        meshBuilder.AdvanceVertex();

        meshBuilder.Position3fv( &points[7].x );
        meshBuilder.Color4ubv( (byte*)&m_DrawColor );
        meshBuilder.AdvanceVertex();

        meshBuilder.Position3fv( &points[5].x );
        meshBuilder.Color4ubv( (byte*)&m_DrawColor );
        meshBuilder.AdvanceVertex();

        meshBuilder.Position3fv( &points[4].x );
        meshBuilder.Color4ubv( (byte*)&m_DrawColor );
        meshBuilder.AdvanceVertex();

        meshBuilder.Position3fv( &points[0].x );
        meshBuilder.Color4ubv( (byte*)&m_DrawColor );
        meshBuilder.AdvanceVertex();

        meshBuilder.Position3fv( &points[2].x );
        meshBuilder.Color4ubv( (byte*)&m_DrawColor );
        meshBuilder.AdvanceVertex();

        meshBuilder.End();
        m_pMesh->Draw();

        // Draw the three missing edges.
        
        meshBuilder.Begin( m_pMesh, MATERIAL_LINES, 3 );

        meshBuilder.Position3fv( &points[4].x );
        meshBuilder.Color4ubv( (byte*)&m_DrawColor );
        meshBuilder.AdvanceVertex();

        meshBuilder.Position3fv( &points[6].x );
        meshBuilder.Color4ubv( (byte*)&m_DrawColor );
        meshBuilder.AdvanceVertex();

        meshBuilder.Position3fv( &points[1].x );
        meshBuilder.Color4ubv( (byte*)&m_DrawColor );
        meshBuilder.AdvanceVertex();

        meshBuilder.Position3fv( &points[5].x );
        meshBuilder.Color4ubv( (byte*)&m_DrawColor );
        meshBuilder.AdvanceVertex();

        meshBuilder.Position3fv( &points[3].x );
        meshBuilder.Color4ubv( (byte*)&m_DrawColor );
        meshBuilder.AdvanceVertex();

        meshBuilder.Position3fv( &points[7].x );
        meshBuilder.Color4ubv( (byte*)&m_DrawColor );
        meshBuilder.AdvanceVertex(); 

        meshBuilder.End();
        m_pMesh->Draw();
    }
}
#

Assuming that it is just a direct binding

near phoenix
#

Where're you gettin' that from?

vagrant cloak
#

Places

near phoenix
#

sussy

vagrant cloak
near phoenix
#

Perchance

vagrant cloak
#

That's debug overlay stuff

#

I mean the other function was from hammer so shrug, good chance that Garry at some point made his own render funcs that took from the hammer funcs and added similar things for other primitives

near phoenix
#

I'm going to convert it to lua and compare it against render.drawsphere for the same inputs and see if the outputs are the same

#

Wait

#

No

#

It doesn't have the same signature, even

vagrant cloak
#

You can try the comparison with drawbox

near phoenix
#

Nah, see, boxes are a static runtime

#

No loops required

#

The loops are going to be important for determining how things scale when the polycount of the sphere increases

vagrant cloak
#

Either way I guess there's an idea for another library, something for generating IMesh primitives

#

mesh.Cylinder(material, height, radius, steps)

near phoenix
#

I think material is wrong

#

Feels like this should be an enum of some kind, not an IMaterial

#

I dunno man, seems like your library is bad and you should feel bad

#

(I'm testing some very low polycount spheres)

#

This is 3, 5, and 7, respectively. Seems like it maybe doesn't like low odd numbers?

#

4 is fine, for example

#

Huh, seems like it's any odd number actually

#

It's just less visible with high numbers

vagrant cloak
#

Yeah that's definitely something with DrawSphere then

near phoenix
vagrant cloak
#

Go look at how 3 step drawsphere looks outside of the lib

near phoenix
vagrant cloak
#

Oh you know what @near phoenix it's a symmetry problem

#

Since the lib works by drawing the sphere multiple times, sometimes inside-out

#

Which means the positions of the uneven vertices are going to flip when it does

near phoenix
#

Yeah, I thought that kind of thing might come up

#

Hang on

#

You actually want to use this

#

render.CullMode

This lets you control if the front faces or back faces are culled

vagrant cloak
#

I'll give it a go later

near phoenix
#

Also you should probably use render.OverrideColorWriteEnable to prevent drawing to the Color Channel while creating the mask, instead of relying on a transparent color

#

Makes it really easy to comment out and what's being drawn

vagrant cloak
#

Also fixed some stuff to do with the radii calculations so negative thickness works properly now

#

Though in this case it's 0 radius, 100 thickness

#

Also, with a bit of fuckery (frames permitting) you can get a soft edge going

near phoenix
#

How are you softening that edge?

#

I suppose you could draw to a render target and blur it?

#

Seems expensive

vagrant cloak
#

Just drawing 10 rings

#

Probably a decent example

#

Well that was interesting, hit save after changing some code and it just killed the renderer

#

Oh, turns out I was passing nil as the radius... how could that black out everything though, including the console?

#

... right

#

render.OverrideColorWriteEnable(true, false)

#

Anyways, gist is updated

near phoenix
#

But you're at least drawing them with a lower polycount, right

#

...right

vagrant cloak
#
-- Draws a ring around the player with a softened edge
-- Note that this example isn't particularly performant, especially with higher step counts
hook.Add("PostDrawTranslucentRenderables", "Rings Example", function()
    local pos = LocalPlayer():GetPos()
    local radius = 100
    local steps = 20
    local color = Color(255, 0, 0, 10)

    for i = 0, 10 do
        render.DrawRing(pos, radius, -i, steps, color)
    end
end)
near phoenix
#

sickening

vagrant cloak
#

20 < 50 though

near phoenix
#

20 do be less than 50

vagrant cloak
#

Oh interesting, the border issue is actually part of a stencil index I can't really fix

#

Index 1 where the actual ring is being drawn

#

Index 2 where the problem areas end up

#

Also turns out that the use case of using a radius of 0 and a thickness of whatever you want your radius to be won't work with multi-ring setups

#

Since it recreates the same issue, except the overlap area is everywhere

near phoenix
#

Current status:

#

Trying to verbalize what each of these spheres is doing is haaaarrdddd

vagrant cloak
#

Yep

empty cove
#

this has to be the greatest addition to garrysmod since multiplayer prayge

whole tangle
#

Is this tool in a usable state atm/

near phoenix
#

Yes

#

It's probably got some bugs somewhere in there, but for the most part it should be fine for most usages

near phoenix
#

Part of getting someone to properly understand this as a wiki example is going to be understanding what inverting a model's faces does

#

I've been playing around with ways of visualizing that

vagrant cloak
#

Yeah it's usable, the things you saw above are more just edge cases that don't work quite right

whole tangle
#

Would you recommend I didn't permanently draw a ring under players depending on their team 😛

vagrant cloak
#

Should be fine as long as you understand that it's going to show those rings through walls and things like that (unless you draw them for LocalPlayer only)

whole tangle
#

Hmm. Was planning more for ease for knowing which team someone is on

#

for a JVS

#

it's fine i guess i'll just plug in a range check and call it a day

#

I'll probably avoid the softened edge one though if I'm gonna do that

#

Even though it looks nice 😦

vagrant cloak
#

JVS?

whole tangle
#

Oh shoot, I don't want to clutter up your thread for this tool, should we talk elsewhere?

whole tangle
vagrant cloak
#

Ah

whole tangle
#

I went on to the server I was developing to play for the first time and I ended up fragging some teammates just cos I didn't know who was my team lol

vagrant cloak
near phoenix
#

FYI I'm planning to add sphere generation to this library that matches render.DrawSphere

#

Couldn't find the source, so I'm just going to recreate it

vagrant cloak
#

Should be easy now that I've done some helper funcs for all the mesh stuff

near phoenix
#

Can you point them out to me? I’m looking at how you’ve implemented cylinder and using that as a sort of style guide

vagrant cloak
#

Oh, hadn't pushed that file yet it seems

#
local function addVertex(pos, normal, u, v, color)
    mesh.Position(pos) mesh.Normal(normal)
    mesh.TexCoord(0, u, v) mesh.Color(color:Unpack())
    mesh.AdvanceVertex()
end

-- Bottom face
if radius1 != 0 then
    addVertex(Vector(0, 0, 0), nDown, 0.5, 0, color)
    addVertex(indices[1],      nDown, 1,   1, color)
    addVertex(indices[2],      nDown, 0,   1, color)
end
near phoenix
#

Oh, I was just thinking about making that

#

Convenient

near phoenix
#

I'm going to be including this in a pull request (Assuming I get this godforsaken sphere to generate) but I'll add it here for now

IsGeneratingMesh = false
hook.Add( "OnLuaError", "PrimitiveMeshCrashAvoidance", function()
    if IsGeneratingMesh then
        mesh.End()
        print( "Prevented mesh-related crash!" )
    end
end )
function Cylinder( iMesh, height, radius1, radius2, steps, color )
  -- Code goes here

  if iMesh then
    mesh.Begin( iMesh, MATERIAL_TRIANGLES, primitiveCount )
  else
    mesh.Begin( nil, MATERIAL_TRIANGLES, primitiveCount )
  end
  IsGeneratingMesh = true

  -- Mesh generation code goes here

  IsGeneratingMesh = false
  mesh.End()
end
vagrant cloak
#

That crashes for you?

#

On my end it just transitions into an error refusing to mesh.Begin until mesh.End is called

#

Oh @near phoenix are you trying to do a render.DrawSphere function atm or trying to get an IMesh first?

near phoenix
#

render.DrawSphere

vagrant cloak
#

Yeah try it with an IMesh instead, since cam.PushModelMatrix will brick your game much quickly if that goes wrong

#

Unless you're not using that at all in which case idk

near phoenix
#

I dunno

#

Whatever the case, that hook saves me from crashes and does nothing in other cases

near phoenix
#

I'm trying to reverse engineer their mesh generation by staring at it