3D Circle Drawer

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

Bate wrote:I finally had some time to code my drawGeodesicLine function. It draws the geodesic line (shortest path) between 2 points on a sphere (with given radius and origin (0,0,0)). The math is correct and everything works fine but I would like to put it in a SceneNode just like Acki did with the circleDrawer. Unfortunately, I didn't succeed in doing so; guess that's because I don't understand everything in his code :oops:

So could maybe someone help me with this? (winking at Acki :wink:)
I'm not sure where you have problems with ??? :shock:

in short:
1st - create a new class derived from ISceneNode
2nd - put your creation function in that class (maybe call it from inside the constructor, too)
3rd - put your "render loop" inside the render function of the class
4th - create an instance of the class on the heap like I did (and don't forget to pass the root scene node or another parent node and the scene manager to it)

I didn't check this, but I think you can use the circle class and just replace the circle creation with your creation function...
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Bate
Posts: 364
Joined: Sun Nov 01, 2009 11:39 pm
Location: Germany

Post by Bate »

Oh, you're right. It's pretty much the same and working now, I just had a mistake within the create function. So thanks for your template :)

circle.hpp

Code: Select all

#include <irrlicht.h>

namespace irr{
namespace scene{

class circleclass : public ISceneNode{
  private:
    core::array<video::S3DVertex> lstVertices;
    core::array<u16> lstIndices;
    core::aabbox3df Box;
    video::SMaterial Material;
    video::IVideoDriver* Driver;

  public:
    circleclass(core::vector3df p1, core::vector3df p2, f32 r, f32 k, ISceneNode* parent, ISceneManager* smgr, s32 id=-1);
    virtual void OnRegisterSceneNode();
    virtual void render();
    virtual const core::aabbox3d<f32>& getBoundingBox() const;
    virtual u32 getMaterialCount();
    virtual video::SMaterial& getMaterial(u32 i);
    virtual void setMaterial(video::SMaterial newMaterial);
    void createCircle(core::vector3df p1, core::vector3df p2, f32 r, f32 k);
};

}} // namespaces
circle.cpp

Code: Select all

#include "circle.h"

using namespace irr;
using namespace core;
using namespace video;

namespace irr{
namespace scene{

circleclass::circleclass(core::vector3df p1, core::vector3df p2, f32 r, f32 k, ISceneNode* parent, ISceneManager* smgr, s32 id):ISceneNode(parent,smgr,id){
  Driver = SceneManager->getVideoDriver();
  Material.EmissiveColor = SColor(255, 255,0,0);
  if(Parent) Parent->addChild(this);
  updateAbsolutePosition();
  createCircle(p1, p2, r, k);
  AutomaticCullingState = EAC_FRUSTUM_BOX;
}

void circleclass::OnRegisterSceneNode(){
  if(IsVisible) SceneManager->registerNodeForRendering(this);
  ISceneNode::OnRegisterSceneNode();
}

void circleclass::render(){
  // Prep to render
  Driver->setMaterial(Material);
  Driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
  // render
  Driver->drawVertexPrimitiveList(&lstVertices[0], lstVertices.size(), &lstIndices[0], lstIndices.size() - 1, video::EVT_STANDARD, EPT_LINE_STRIP, video::EIT_16BIT);
}

const core::aabbox3d<f32>& circleclass::getBoundingBox() const{
  return Box;
}
u32 circleclass::getMaterialCount(){
  return 1;
}
video::SMaterial& circleclass::getMaterial(u32 i){
  return Material;
}
void circleclass::setMaterial(video::SMaterial newMaterial){
  Material = newMaterial;
}

void circleclass::createCircle(core::vector3df p1, core::vector3df p2, f32 r, f32 k){

lstIndices.push_back(lstVertices.size());
lstVertices.push_back( S3DVertex(p1, vector3df(0,0,0), SColor(255, 255,0,0), vector2df(0,0) ));



for(f32 i = 1; i < k; i++)
{

f32 t;


t = squareroot(
                ( pow(r,2) * pow(k,2) ) /
                  (
                    ( pow((k-i),2) * pow(p1.X,2) + 2 * (k-i) * p1.X * i * p2.X + pow(i,2) * pow(p2.X,2) ) +
                    ( pow((k-i),2) * pow(p1.Y,2) + 2 * (k-i) * p1.Y * i * p2.Y + pow(i,2) * pow(p2.Y,2) ) +
                    ( pow((k-i),2) * pow(p1.Z,2) + 2 * (k-i) * p1.Z * i * p2.Z + pow(i,2) * pow(p2.Z,2) )
                  )
              );

S3DVertex newVertex;

newVertex.Pos = t * (
                      ( ((k-i) / k) * p1 ) +
                      ( (i/k) * p2 )
                    );

newVertex.Color = SColor(255, 255,0,0);


lstIndices.push_back(lstVertices.size());
lstVertices.push_back(newVertex);


}


lstIndices.push_back(lstVertices.size());
lstVertices.push_back( S3DVertex(p2, vector3df(0,0,0), SColor(255, 255,0,0), vector2df(0,0) ));


}

}} // namespaces
Material color is already set by the contructor so you don't have to create a material unless you want different colors.

Code: Select all

// EXAMPLE
vector3df p1 = vector3df(52,0,0);
vector3df p2 = vector3df(0,52,0);

circleclass* circleNode = new circleclass(p1, p2, 52, 100, smgr->getRootSceneNode(), smgr);
circleNode->drop();
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

one final suggestion: you should rename the class, bc it doesn't create a circle anymore, to avoid confusions... ;)
(same for the createCircle function)
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
erivera
Posts: 3
Joined: Mon Mar 22, 2010 1:23 am

Post by erivera »

[quote="Acki"]well, I rewrote your code (took me less than 15 mins) to be efficient and made a benchmark test... :lol:

this are 200 circles using your code (FPS = 11):
Image

and this are the same 200 circles using my code (FPS = 104 !!!):
Image


Thanks Acki, I have tried your code, all right mate, but I have a question, Could you tell me what is the reason to use lstIndices.size() / 2
in:
Driver->drawVertexPrimitiveList(&lstVertices[0], lstVertices.size(),
&lstIndices[0], lstIndices.size() / 2, video::EVT_STANDARD, EPT_LINES,
video::EIT_16BIT);

?

What is the connection of the vertex count, you say: // We want the vertex count to reflect a polygon// ?

I note that when you change:
EPT_LINES by EPT_LINE_STRIP

Only a semi-circle appears.
And when you change lstIndices.size() / 2 by lstIndices.size() , an error happens.?

The reason is that I only would like to have simple line 3d, but with your code, and not with the code of another guy.

I hope your help, thanks a lot.
To share is great! Thanks.
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

erivera wrote:Thanks Acki, I have tried your code, all right mate, but I have a question, Could you tell me what is the reason to use lstIndices.size() / 2
well, each line is build out of 2 points/vertices (start and end) but the draw function needs the amount of primitives, so you simply divide the overall vertices by the needed vertices per primitive...
e.g. if you want to draw triangle faces (EPT_TRIANGLES) you have 3 vertices per primitive and so you divide the amount by 3...
erivera wrote:I note that when you change:
EPT_LINES by EPT_LINE_STRIP

Only a semi-circle appears.
that's because a line strip is build in another way, so you'll have to change the draw function acordingly... ;)
erivera wrote:And when you change lstIndices.size() / 2 by lstIndices.size() , an error happens.?
because you tell the draw function there are double as much primitives as there are realy are (see above)... :lol:
erivera wrote:I hope your help, thanks a lot.
I hope I did !!!! ;)
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Post Reply