From: Mikko Rasa Date: Wed, 26 Jan 2011 18:09:37 +0000 (+0000) Subject: Add capsule and grid builders X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=aa9884e69bc543682d1fe36ec5d054fdf11bcfac Add capsule and grid builders Fix some bugs in the other geometry builders --- diff --git a/source/box.cpp b/source/box.cpp index 3d6f15fd..21d5f33f 100644 --- a/source/box.cpp +++ b/source/box.cpp @@ -42,22 +42,27 @@ void BoxBuilder::build(PrimitiveBuilder &builder) const void BoxBuilder::build_face(PrimitiveBuilder &builder, const Vector3 &o, const Vector3 &s1, const Vector3 &s2) const { + float l1 = 1, l2 = 1; + if(tangent_attr>=0 || tex_fit!=STRETCH) + l1 = sqrt(s1.x*s1.x+s1.y*s1.y+s1.z*s1.z); + if(binormal_attr>=0 || tex_fit!=STRETCH) + l2 = sqrt(s2.x*s2.x+s2.y*s2.y+s2.z*s2.z); + if(tangent_attr>=0) - { - builder.attrib(tangent_attr, s1.x, s1.y, s1.z); - builder.attrib(binormal_attr, s2.x, s2.y, s2.z); - } + builder.attrib(tangent_attr, s1.x/l1, s1.y/l1, s1.z/l1); + if(binormal_attr>=0) + builder.attrib(binormal_attr, s2.x/l2, s2.y/l2, s2.z/l2); + float u_size = 1; float v_size = 1; if(tex_fit!=STRETCH) { - float l1 = sqrt(s1.x*s1.x+s1.y*s1.y+s1.z*s1.z); - float l2 = sqrt(s2.x*s2.x+s2.y*s2.y+s2.z*s2.z); if((l1=0) builder.attrib(tangent_attr, -ss, sc, 0); + if(binormal_attr>=0) builder.attrib(binormal_attr, rc*sc, rc*ss, rs); - } builder.texcoord(j*u_scale, v); builder.vertex(rs*sc*radius, rs*ss*radius, cz-rc*radius); } diff --git a/source/cylinder.cpp b/source/cylinder.cpp new file mode 100644 index 00000000..30c3530c --- /dev/null +++ b/source/cylinder.cpp @@ -0,0 +1,92 @@ +/* $Id$ + +This file is part of libmspgl +Copyright © 2011 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#include +#include "cylinder.h" +#include "primitivebuilder.h" + +using namespace std; + +namespace Msp { +namespace GL { + +CylinderBuilder::CylinderBuilder(float r, float l, unsigned s): + radius(r), + length(l), + segments(s) +{ + if(segments<3) + segments = 3; +} + +void CylinderBuilder::build(PrimitiveBuilder &builder) const +{ + if(binormal_attr>=0) + builder.attrib(binormal_attr, 0, 1, 0); + for(unsigned i=0; i<2; ++i) + { + float z = (i-0.5)*length; + builder.normal(0, 0, i*2.0-1.0); + builder.texcoord(0.5, 0.5); + if(tangent_attr>=0) + builder.attrib(tangent_attr, (i ? 1 : -1), 0, 0); + builder.vertex(0, 0, z); + for(unsigned j=0; j=0) + builder.attrib(binormal_attr, 0, 0, 1); + for(unsigned i=0; i<2; ++i) + { + float z = (i-0.5)*length; + for(unsigned j=0; j<=segments; ++j) + { + float a = j*M_PI*2/segments; + float c = cos(a); + float s = sin(a); + builder.normal(c, s, 0); + builder.texcoord(j*u_scale, i*v_scale); + if(tangent_attr>=0) + builder.attrib(tangent_attr, -s, c, 0); + builder.vertex(radius*c, radius*s, z); + } + } + + unsigned base = 0; + for(unsigned i=0; i<2; ++i) + { + builder.begin(TRIANGLE_FAN); + builder.element(base); + for(unsigned j=0; j<=segments; ++j) + builder.element(base+1+j%segments); + builder.end(); + + base += segments+1; + } + + builder.begin(TRIANGLE_STRIP); + for(unsigned j=0; j<=segments; ++j) + { + builder.element(base+segments+1+j); + builder.element(base+j); + } + builder.end(); +} + +} // namespace GL +} // namespace Msp diff --git a/source/cylinder.h b/source/cylinder.h new file mode 100644 index 00000000..c671bfee --- /dev/null +++ b/source/cylinder.h @@ -0,0 +1,32 @@ +/* $Id$ + +This file is part of libmspgl +Copyright © 2011 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#ifndef CYLINDER_H_ +#define CYLINDER_H_ + +#include "geometrybuilder.h" + +namespace Msp { +namespace GL { + +class CylinderBuilder: public GeometryBuilder +{ +private: + float radius; + float length; + unsigned segments; + +public: + CylinderBuilder(float, float, unsigned = 16); + + virtual void build(PrimitiveBuilder &) const; +}; + +} // namespace GL +} // namespace Msp + +#endif diff --git a/source/geometrybuilder.cpp b/source/geometrybuilder.cpp index 97c88e06..018ea447 100644 --- a/source/geometrybuilder.cpp +++ b/source/geometrybuilder.cpp @@ -35,6 +35,17 @@ GeometryBuilder &GeometryBuilder::texture_fit(TextureFit tf) return *this; } +void GeometryBuilder::adjust_texture_scale(float &u_scale, float &v_scale, float width, float height) const +{ + if(tex_fit!=STRETCH) + { + if((width +#include "grid.h" +#include "primitivebuilder.h" + +using namespace std; + +namespace Msp { +namespace GL { + +GridBuilder::GridBuilder(float w, float h, unsigned u, unsigned v): + origin(-w/2, -h/2, 0), + side1(w, 0, 0), + side2(0, h, 0), + norm(0, 0, 1), + binorm(0, 1, 0), + u_div(u), + v_div(v) +{ + init(false); +} + +GridBuilder::GridBuilder(const Vector3 &o, const Vector3 &s, unsigned u, unsigned v): + origin(o), + u_div(u), + v_div(v) +{ + if(abs(s.z)=0) + builder.attrib(tangent_attr, side1.x, side1.y, side1.z); + if(binormal_attr>=0) + builder.attrib(tangent_attr, binorm.x, binorm.y, binorm.z); + + for(unsigned j=0; j<=v_div; ++j) + { + float v = j*1.0/v_div; + Vector3 row(origin.x+side2.x*v, origin.y+side2.y*v, origin.z+side2.z*v); + v = (row.x*binorm.x+row.y*binorm.y+row.z*binorm.z)*v_scale; + for(unsigned i=0; i<=u_div; ++i) + { + float u = i*1.0/u_div; + Vector3 p(row.x+side1.x*u, row.y+side1.y*u, row.z+side1.z*u); + u = (p.x*side1.x+p.y*side1.y+p.z*side1.z)*u_scale; + builder.texcoord(u, v); + builder.vertex(p); + } + } + + for(unsigned j=0; j