From bbfb79181f716736df413f463b55825866400ed8 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 26 Jan 2011 15:23:26 +0000 Subject: [PATCH] Add classes for building some geometric shapes --- source/box.cpp | 74 ++++++++++++++++++++++++++++++++ source/box.h | 35 +++++++++++++++ source/capsule.cpp | 88 ++++++++++++++++++++++++++++++++++++++ source/capsule.h | 33 ++++++++++++++ source/geometrybuilder.cpp | 45 +++++++++++++++++++ source/geometrybuilder.h | 46 ++++++++++++++++++++ 6 files changed, 321 insertions(+) create mode 100644 source/box.cpp create mode 100644 source/box.h create mode 100644 source/capsule.cpp create mode 100644 source/capsule.h create mode 100644 source/geometrybuilder.cpp create mode 100644 source/geometrybuilder.h diff --git a/source/box.cpp b/source/box.cpp new file mode 100644 index 00000000..3d6f15fd --- /dev/null +++ b/source/box.cpp @@ -0,0 +1,74 @@ +/* $Id$ + +This file is part of libmspgl +Copyright © 2011 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#include +#include "box.h" +#include "primitivebuilder.h" + +using namespace std; + +namespace Msp { +namespace GL { + +BoxBuilder::BoxBuilder(float w, float h, float d): + origin(-w/2, -h/2, -d/2), + span(w, h, d) +{ } + +BoxBuilder::BoxBuilder(const Vector3 &o, const Vector3 &s): + origin(o), + span(s) +{ } + +void BoxBuilder::build(PrimitiveBuilder &builder) const +{ + builder.normal(1, 0, 0); + build_face(builder, Vector3(origin.x+span.x, origin.y, origin.z), Vector3(0, span.y, 0), Vector3(0, 0, span.z)); + builder.normal(0, 1, 0); + build_face(builder, Vector3(origin.x+span.x, origin.y+span.y, origin.z), Vector3(-span.x, 0, 0), Vector3(0, 0, span.z)); + builder.normal(-1, 0, 0); + build_face(builder, Vector3(origin.x, origin.y+span.y, origin.z), Vector3(0, -span.y, 0), Vector3(0, 0, span.z)); + builder.normal(0, -1, 0); + build_face(builder, origin, Vector3(span.x, 0, 0), Vector3(0, 0, span.z)); + builder.normal(0, 0, 1); + build_face(builder, Vector3(origin.x, origin.y, origin.z+span.z), Vector3(span.x, 0, 0), Vector3(0, span.y, 0)); + builder.normal(0, 0, -1); + build_face(builder, Vector3(origin.x+span.x, origin.y, origin.z), Vector3(-span.x, 0, 0), Vector3(0, span.y, 0)); +} + +void BoxBuilder::build_face(PrimitiveBuilder &builder, const Vector3 &o, const Vector3 &s1, const Vector3 &s2) const +{ + if(tangent_attr>=0) + { + builder.attrib(tangent_attr, s1.x, s1.y, s1.z); + builder.attrib(binormal_attr, s2.x, s2.y, s2.z); + } + 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 +#include "capsule.h" +#include "primitivebuilder.h" + +using namespace std; + +namespace Msp { +namespace GL { + +CapsuleBuilder::CapsuleBuilder(float r, float l, unsigned s, unsigned n): + radius(r), + length(l), + segments(s), + rings(n) +{ + if(segments<3) + segments = 3; + rings |= 1; + if(rings<3) + rings = 3; +} + +void CapsuleBuilder::build(PrimitiveBuilder &builder) const +{ + float u_scale = 1.0/segments; + float v_scale = 1/(length+radius*M_PI); + if(tex_fit!=STRETCH) + { + float l1 = radius*M_PI*2; + float l2 = length+radius*M_PI; + if((l1rings/2 ? 0.5 : -0.5); + float v = (i*radius*M_PI/rings+(i>rings/2 ? length : 0))*v_scale; + float ra = (i>rings/2 ? i-1 : i)*M_PI/(rings-1); + float rc = cos(ra); + float rs = sin(ra); + for(unsigned j=0; j<=segments; ++j) + { + float sa = j*M_PI*2/segments; + float sc = cos(sa); + float ss = sin(sa); + builder.normal(rs*sc, rs*ss, -rc); + if(tangent_attr) + { + builder.attrib(tangent_attr, -ss, sc, 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); + } + } + builder.normal(0, 0, 1); + builder.texcoord(0.5, (length+radius*M_PI)*v_scale); + builder.vertex(0, 0, length/2-radius); + + for(unsigned i=0; i + +namespace Msp { +namespace GL { + +class CapsuleBuilder: public GeometryBuilder +{ +private: + float radius; + float length; + unsigned segments; + unsigned rings; + +public: + CapsuleBuilder(float, float, unsigned = 16, unsigned = 9); + + virtual void build(PrimitiveBuilder &) const; +}; + +} // namepace GL +} // namespace Msp + +#endif diff --git a/source/geometrybuilder.cpp b/source/geometrybuilder.cpp new file mode 100644 index 00000000..97c88e06 --- /dev/null +++ b/source/geometrybuilder.cpp @@ -0,0 +1,45 @@ +/* $Id$ + +This file is part of libmspgl +Copyright © 2011 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#include "geometrybuilder.h" +#include "meshbuilder.h" + +namespace Msp { +namespace GL { + +GeometryBuilder::GeometryBuilder(): + tangent_attr(-1), + binormal_attr(-1), + tex_fit(STRETCH) +{ } + +GeometryBuilder &GeometryBuilder::tangent(unsigned t) +{ + tangent_attr = t; + return *this; +} + +GeometryBuilder &GeometryBuilder::binormal(unsigned b) +{ + binormal_attr = b; + return *this; +} + +GeometryBuilder &GeometryBuilder::texture_fit(TextureFit tf) +{ + tex_fit = tf; + return *this; +} + +void GeometryBuilder::build(Mesh &mesh) const +{ + MeshBuilder builder(mesh); + build(builder); +} + +} // namespace GL +} // namespace Msp diff --git a/source/geometrybuilder.h b/source/geometrybuilder.h new file mode 100644 index 00000000..a0538b59 --- /dev/null +++ b/source/geometrybuilder.h @@ -0,0 +1,46 @@ +/* $Id$ + +This file is part of libmspgl +Copyright © 2011 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#ifndef MSP_GL_GEOMETRYBUILDER_H_ +#define MSP_GL_GEOMETRYBUILDER_H_ + +namespace Msp { +namespace GL { + +class Mesh; +class PrimitiveBuilder; + +class GeometryBuilder +{ +public: + enum TextureFit + { + STRETCH, + CUT, + WRAP + }; + +protected: + int tangent_attr; + int binormal_attr; + TextureFit tex_fit; + + GeometryBuilder(); + +public: + GeometryBuilder &tangent(unsigned); + GeometryBuilder &binormal(unsigned); + GeometryBuilder &texture_fit(TextureFit); + + virtual void build(PrimitiveBuilder &) const = 0; + void build(Mesh &) const; +}; + +} // namespace GL +} // namespace Msp + +#endif -- 2.43.0