framework2
1144 строки · 38.4 Кб
1//
2// of3dPrimitive.cpp
3// openFrameworksLib
4//
5// Created by Nick Hardeman on 9/14/12.
6//
7//
8
9#include "of3dPrimitives.h"
10#include "ofGraphics.h"
11#include "ofRectangle.h"
12#include "ofVboMesh.h"
13#include "ofTexture.h"
14#include "of3dUtils.h"
15
16using std::vector;
17using std::shared_ptr;
18
19of3dPrimitive::of3dPrimitive()
20:usingVbo(true)
21,mesh(new ofVboMesh)
22{
23setScale(1.0, 1.0, 1.0);
24}
25
26//----------------------------------------------------------
27of3dPrimitive::~of3dPrimitive() {
28
29}
30
31//----------------------------------------------------------
32of3dPrimitive::of3dPrimitive(const of3dPrimitive & mom):ofNode(mom){
33texCoords = mom.texCoords;
34usingVbo = mom.usingVbo;
35if(usingVbo){
36mesh = std::make_shared<ofVboMesh>();
37}else{
38mesh = std::make_shared<ofMesh>();
39}
40*mesh = *mom.mesh;
41}
42
43//----------------------------------------------------------
44of3dPrimitive::of3dPrimitive(const ofMesh & mesh)
45:usingVbo(true)
46,mesh(new ofVboMesh(mesh)){
47
48}
49
50//----------------------------------------------------------
51of3dPrimitive & of3dPrimitive::operator=(const of3dPrimitive & mom){
52if(&mom!=this){
53(*(ofNode*)this)=mom;
54texCoords = mom.texCoords;
55setUseVbo(mom.usingVbo);
56*mesh = *mom.mesh;
57}
58return *this;
59}
60
61// GETTERS //
62//----------------------------------------------------------
63ofMesh* of3dPrimitive::getMeshPtr() {
64return mesh.get();
65}
66
67//----------------------------------------------------------
68ofMesh& of3dPrimitive::getMesh() {
69return *mesh;
70}
71
72//----------------------------------------------------------
73const ofMesh* of3dPrimitive::getMeshPtr() const{
74return mesh.get();
75}
76
77//----------------------------------------------------------
78const ofMesh& of3dPrimitive::getMesh() const{
79return *mesh;
80}
81
82//----------------------------------------------------------
83glm::vec4* of3dPrimitive::getTexCoordsPtr() {
84return& texCoords;
85}
86
87//----------------------------------------------------------
88glm::vec4& of3dPrimitive::getTexCoords() {
89return texCoords;
90}
91
92//----------------------------------------------------------
93const glm::vec4* of3dPrimitive::getTexCoordsPtr() const{
94return& texCoords;
95}
96
97//----------------------------------------------------------
98const glm::vec4& of3dPrimitive::getTexCoords() const{
99return texCoords;
100}
101
102//----------------------------------------------------------
103vector<ofIndexType> of3dPrimitive::getIndices( int startIndex, int endIndex ) const {
104vector<ofIndexType> indices;
105indices.assign( getMesh().getIndices().begin()+startIndex, getMesh().getIndices().begin()+endIndex );
106return indices;
107}
108
109
110//----------------------------------------------------------
111bool of3dPrimitive::hasScaling() const{
112glm::vec3 scale = getScale();
113return (scale.x != 1.f || scale.y != 1.f || scale.z != 1.f);
114}
115//----------------------------------------------------------
116bool of3dPrimitive::hasNormalsEnabled() const {
117return getMesh().hasNormals();
118}
119
120//----------------------------------------------------------
121void of3dPrimitive::enableNormals() {
122getMesh().enableNormals();
123}
124//----------------------------------------------------------
125void of3dPrimitive::enableTextures() {
126getMesh().enableTextures();
127}
128//----------------------------------------------------------
129void of3dPrimitive::enableColors() {
130getMesh().enableColors();
131}
132//----------------------------------------------------------
133void of3dPrimitive::disableNormals() {
134getMesh().disableNormals();
135}
136//----------------------------------------------------------
137void of3dPrimitive::disableTextures() {
138getMesh().disableTextures();
139}
140//----------------------------------------------------------
141void of3dPrimitive::disableColors() {
142getMesh().disableColors();
143}
144
145// SETTERS //
146
147//----------------------------------------------------------
148void of3dPrimitive::mapTexCoords( float u1, float v1, float u2, float v2 ) {
149
150auto prevTcoord = getTexCoords();
151
152for(std::size_t j = 0; j < getMesh().getNumTexCoords(); j++ ) {
153auto tcoord = getMesh().getTexCoord(j);
154tcoord.x = ofMap(tcoord.x, prevTcoord.x, prevTcoord.z, u1, u2);
155tcoord.y = ofMap(tcoord.y, prevTcoord.y, prevTcoord.w, v1, v2);
156
157getMesh().setTexCoord(j, tcoord);
158}
159
160texCoords = {u1, v1, u2, v2};
161}
162
163//----------------------------------------------------------
164void of3dPrimitive::mapTexCoordsFromTexture( const ofTexture& inTexture ) {
165bool bNormalized = true;
166#ifndef TARGET_OPENGLES
167bNormalized = (inTexture.getTextureData().textureTarget!=GL_TEXTURE_RECTANGLE_ARB);
168#endif
169
170const ofTextureData& tdata = inTexture.getTextureData();
171if(bNormalized){
172mapTexCoords( 0, 0, tdata.tex_t, tdata.tex_u );
173}else{
174mapTexCoords(0, 0, inTexture.getWidth(), inTexture.getHeight());
175}
176
177auto tcoords = getTexCoords();
178mapTexCoords(tcoords.x, tcoords.y, tcoords.z, tcoords.w);
179}
180
181//----------------------------------------------------------
182void of3dPrimitive::normalizeAndApplySavedTexCoords() {
183auto tcoords = getTexCoords();
184// when a new mesh is created, it uses normalized tex coords, we need to reset them
185// but save the ones used previously //
186texCoords = {0.f, 0.f, 1.f, 1.f};
187mapTexCoords(tcoords.x, tcoords.y, tcoords.z, tcoords.w);
188}
189
190//--------------------------------------------------------------
191void of3dPrimitive::drawVertices() const{
192draw(OF_MESH_POINTS);
193}
194
195//--------------------------------------------------------------
196void of3dPrimitive::drawWireframe() const{
197draw(OF_MESH_WIREFRAME);
198}
199
200//--------------------------------------------------------------
201void of3dPrimitive::drawFaces() const{
202draw(OF_MESH_FILL);
203}
204
205//--------------------------------------------------------------
206void of3dPrimitive::draw(ofPolyRenderMode renderType) const{
207ofGetCurrentRenderer()->draw(*this, renderType);
208}
209
210//--------------------------------------------------------------
211void of3dPrimitive::draw() const{
212draw(OF_MESH_FILL);
213}
214
215//--------------------------------------------------------------
216void of3dPrimitive::drawNormals(float length, bool bFaceNormals) const{
217ofNode::transformGL(ofGetCurrentRenderer().get());
218
219if(getMesh().usingNormals()) {
220const auto& normals = getMesh().getNormals();
221const auto& vertices = getMesh().getVertices();
222glm::vec3 normal;
223glm::vec3 vert;
224
225normalsMesh.setMode( OF_PRIMITIVE_LINES );
226normalsMesh.getVertices().resize( normals.size() * 2);
227
228if(bFaceNormals) {
229for(size_t i = 0; i < normals.size(); i++ ) {
230if(i % 3 == 0) {
231vert = (vertices[i]+vertices[i+1]+vertices[i+2]) / 3;
232} else if(i % 3 == 1) {
233vert = (vertices[i-1]+vertices[i]+vertices[i+1]) / 3;
234} else if ( i % 3 == 2) {
235vert = (vertices[i-2]+vertices[i-1]+vertices[i]) / 3;
236}
237normalsMesh.setVertex(i*2, vert);
238normal = glm::normalize(toGlm(normals[i]));
239normal *= length;
240normalsMesh.setVertex(i*2+1, vert+normal);
241}
242} else {
243for(size_t i = 0; i < normals.size(); i++) {
244vert = vertices[i];
245normal = glm::normalize(toGlm(normals[i]));
246normalsMesh.setVertex( i*2, vert);
247normal *= length;
248normalsMesh.setVertex(i*2+1, vert+normal);
249}
250}
251normalsMesh.draw();
252} else {
253ofLogWarning("of3dPrimitive") << "drawNormals(): mesh normals are disabled";
254}
255
256
257ofNode::restoreTransformGL(ofGetCurrentRenderer().get());
258}
259
260//--------------------------------------------------------------
261void of3dPrimitive::drawAxes(float a_size) const{
262ofNode::transformGL(ofGetCurrentRenderer().get());
263ofDrawAxis(a_size);
264ofNode::restoreTransformGL(ofGetCurrentRenderer().get());
265}
266
267//--------------------------------------------------------------
268void of3dPrimitive::setUseVbo(bool useVbo){
269if(useVbo!=usingVbo){
270shared_ptr<ofMesh> newMesh;
271if(useVbo){
272newMesh = std::make_shared<ofVboMesh>();
273}else{
274newMesh = std::make_shared<ofMesh>();
275}
276*newMesh = *mesh;
277mesh = newMesh;
278}
279usingVbo = useVbo;
280}
281
282//--------------------------------------------------------------
283bool of3dPrimitive::isUsingVbo() const{
284return usingVbo;
285}
286
287// PLANE PRIMITIVE //
288//--------------------------------------------------------------
289ofPlanePrimitive::ofPlanePrimitive() {
290texCoords = {0.f, 0.f, 1.f, 1.f};
291set( 200, 100, 6, 3);
292}
293
294//--------------------------------------------------------------
295ofPlanePrimitive::ofPlanePrimitive(float width, float height, int columns, int rows, ofPrimitiveMode mode) {
296texCoords = {0.f, 0.f, 1.f, 1.f};
297set(width, height, columns, rows, mode);
298}
299
300//--------------------------------------------------------------
301ofPlanePrimitive::~ofPlanePrimitive() {}
302
303//--------------------------------------------------------------
304void ofPlanePrimitive::set(float _width, float _height, int columns, int rows, ofPrimitiveMode mode) {
305
306width = _width;
307height = _height;
308resolution = { columns, rows };
309
310getMesh() = ofMesh::plane( getWidth(), getHeight(), getResolution().x, getResolution().y, mode );
311
312normalizeAndApplySavedTexCoords();
313
314}
315
316//--------------------------------------------------------------
317void ofPlanePrimitive::set( float _width, float height ) {
318width = _width;
319setHeight(height);
320}
321
322//--------------------------------------------------------------
323void ofPlanePrimitive::setWidth( float _width ) {
324width = _width;
325setResolution( getResolution().x, getResolution().y );
326}
327
328//--------------------------------------------------------------
329void ofPlanePrimitive::setHeight(float _height) {
330height = _height;
331setResolution( getResolution().x, getResolution().y );
332}
333
334//--------------------------------------------------------------
335void ofPlanePrimitive::resizeToTexture( ofTexture& inTexture, float scale ) {
336set(inTexture.getWidth() * scale, inTexture.getHeight() * scale);
337mapTexCoordsFromTexture( inTexture );
338}
339
340//--------------------------------------------------------------
341void ofPlanePrimitive::setColumns( int columns ) {
342setResolution( columns, getNumRows() );
343}
344
345//--------------------------------------------------------------
346void ofPlanePrimitive::setRows( int rows ) {
347setResolution( getNumColumns(), rows );
348}
349
350//--------------------------------------------------------------
351void ofPlanePrimitive::setResolution( int columns, int rows ) {
352resolution = { columns, rows };
353ofPrimitiveMode mode = getMesh().getMode();
354
355set( getWidth(), getHeight(), getResolution().x, getResolution().y, mode );
356}
357
358//--------------------------------------------------------------
359void ofPlanePrimitive::setMode(ofPrimitiveMode mode) {
360ofPrimitiveMode currMode = getMesh().getMode();
361
362if( mode != currMode )
363set( getWidth(), getHeight(), getResolution().x, getResolution().y, mode );
364}
365
366//--------------------------------------------------------------
367int ofPlanePrimitive::getNumColumns() const {
368return (int)resolution.x;
369}
370
371//--------------------------------------------------------------
372int ofPlanePrimitive::getNumRows() const {
373return (int)resolution.y;
374}
375
376//--------------------------------------------------------------
377glm::vec2 ofPlanePrimitive::getResolution() const {
378return resolution;
379}
380
381//--------------------------------------------------------------
382float ofPlanePrimitive::getWidth() const {
383return width;
384}
385
386//--------------------------------------------------------------
387float ofPlanePrimitive::getHeight() const {
388return height;
389}
390
391
392
393
394
395// SPHERE PRIMITIVE //
396//----------------------------------------------------------
397ofSpherePrimitive::ofSpherePrimitive() {
398texCoords = {0.f, 0.f, 1.f, 1.f};
399radius = 20;
400setResolution( 16 );
401}
402
403//----------------------------------------------------------
404ofSpherePrimitive::ofSpherePrimitive( float _radius, int res, ofPrimitiveMode mode ) {
405radius = _radius;
406texCoords = {0.f, 0.f, 1.f, 1.f};
407setResolution( res );
408}
409
410//----------------------------------------------------------
411ofSpherePrimitive::~ofSpherePrimitive() {
412
413}
414
415//----------------------------------------------------------
416void ofSpherePrimitive::set( float _radius, int res, ofPrimitiveMode mode ) {
417radius = _radius;
418resolution = res;
419
420getMesh() = ofMesh::sphere( getRadius(), getResolution(), mode );
421
422normalizeAndApplySavedTexCoords();
423}
424
425//----------------------------------------------------------
426void ofSpherePrimitive::setResolution( int res ) {
427resolution = res;
428ofPrimitiveMode mode = getMesh().getMode();
429
430set(getRadius(), getResolution(), mode );
431}
432
433//----------------------------------------------------------
434void ofSpherePrimitive::setMode( ofPrimitiveMode mode ) {
435ofPrimitiveMode currMode = getMesh().getMode();
436if(currMode != mode)
437set(getRadius(), getResolution(), mode );
438}
439
440//----------------------------------------------------------
441void ofSpherePrimitive::setRadius(float _radius) {
442radius = _radius;
443setResolution( getResolution() );
444}
445
446//----------------------------------------------------------
447float ofSpherePrimitive::getRadius() const {
448return radius;
449}
450
451//----------------------------------------------------------
452int ofSpherePrimitive::getResolution() const {
453return resolution;
454}
455
456
457// ICO SPHERE //
458//----------------------------------------------------------
459ofIcoSpherePrimitive::ofIcoSpherePrimitive() {
460texCoords = {0.f, 0.f, 1.f, 1.f};
461radius = 20;
462setResolution( 2 );
463}
464
465//----------------------------------------------------------
466ofIcoSpherePrimitive::ofIcoSpherePrimitive( float _radius, int iterations ) {
467texCoords = {0.f, 0.f, 1.f, 1.f};
468radius = _radius;
469setResolution( iterations );
470}
471
472//----------------------------------------------------------
473ofIcoSpherePrimitive::~ofIcoSpherePrimitive() {
474
475}
476
477//----------------------------------------------------------
478void ofIcoSpherePrimitive::set(float _radius, int res ) {
479radius = _radius;
480setResolution(res);
481}
482
483//----------------------------------------------------------
484void ofIcoSpherePrimitive::setResolution( int iterations ) {
485// store the number of iterations in the resolution //
486resolution = iterations;
487
488getMesh() = ofMesh::icosphere( getRadius(), getResolution() );
489normalizeAndApplySavedTexCoords();
490}
491
492//----------------------------------------------------------
493void ofIcoSpherePrimitive::setMode( ofPrimitiveMode mode ) {
494// ofIcoSpherePrimitive only works with OF_PRIMITIVE_TRIANGLES //
495setResolution( getResolution() );
496}
497
498//----------------------------------------------------------
499void ofIcoSpherePrimitive::setRadius(float _radius) {
500radius = _radius;
501setResolution( getResolution() );
502}
503
504//----------------------------------------------------------
505float ofIcoSpherePrimitive::getRadius() const {
506return radius;
507}
508
509//----------------------------------------------------------
510int ofIcoSpherePrimitive::getResolution() const {
511return resolution;
512}
513
514
515
516//--------------------------------------------------------------
517ofCylinderPrimitive::ofCylinderPrimitive() {
518texCoords = {0.f, 0.f, 1.f, 1.f};
519set( 60, 80, 6, 3, 2, true );
520}
521
522//--------------------------------------------------------------
523ofCylinderPrimitive::ofCylinderPrimitive( float radius, float height, int radiusSegments, int heightSegments, int capSegments, bool bCapped, ofPrimitiveMode mode ) {
524texCoords = {0.f, 0.f, 1.f, 1.f};
525set( radius, height, radiusSegments, heightSegments, capSegments, bCapped, mode );
526}
527
528//--------------------------------------------------------------
529ofCylinderPrimitive::~ofCylinderPrimitive() {}
530
531//--------------------------------------------------------------
532void ofCylinderPrimitive::set(float _radius, float _height, int radiusSegments, int heightSegments, int capSegments, bool _bCapped, ofPrimitiveMode mode) {
533radius = _radius;
534height = _height;
535bCapped = _bCapped;
536resolution = {radiusSegments, heightSegments, capSegments};
537
538int resX = std::max(getResolution().x,0.0f);
539int resY = std::max(getResolution().y-1,0.0f);
540int resZ = std::max(getResolution().z-1,0.0f);
541
542int indexStep = 2;
543if(mode == OF_PRIMITIVE_TRIANGLES) {
544indexStep = 6;
545resX = std::max(resX,0);
546}
547
548// 0 -> top cap
549strides[0][0] = 0;
550strides[0][1] = (resX+1) * (resZ+1) * indexStep;
551vertices[0][0] = 0;
552vertices[0][1] = (getResolution().x+1) * (getResolution().z+1);
553
554// 1 -> cylinder //
555if(bCapped) {
556strides[1][0] = strides[0][0] + strides[0][1];
557vertices[1][0] = vertices[0][0] + vertices[0][1];
558} else {
559strides[1][0] = 0;
560vertices[1][0] = 0;
561}
562strides[1][1] = (resX+1) * (resY+1) * indexStep;
563vertices[1][1] = (getResolution().x+1) * (getResolution().y+1);
564
565// 2 -> bottom cap
566strides[2][0] = strides[1][0] + strides[1][1];
567strides[2][1] = (resX+1) * (resZ+1) * indexStep;
568vertices[2][0] = vertices[1][0]+vertices[1][1];
569vertices[2][1] = (getResolution().x+1) * (getResolution().z+1);
570
571
572getMesh() = ofMesh::cylinder( getRadius(), getHeight(), getResolution().x, getResolution().y, getResolution().z, getCapped(), mode );
573
574normalizeAndApplySavedTexCoords();
575
576}
577
578//--------------------------------------------------------------
579void ofCylinderPrimitive::set( float _radius, float height, bool _bCapped ) {
580radius = _radius;
581bCapped = _bCapped;
582setHeight( height );
583}
584
585//--------------------------------------------------------------
586void ofCylinderPrimitive::setRadius( float _radius ) {
587radius = _radius;
588setResolution( getResolution().x, getResolution().y, getResolution().z );
589}
590
591//--------------------------------------------------------------
592void ofCylinderPrimitive::setHeight( float _height ) {
593height = _height;
594setResolution(getResolution().x, getResolution().y, getResolution().z);
595}
596
597//--------------------------------------------------------------
598void ofCylinderPrimitive::setCapped(bool _bCapped) {
599bCapped = _bCapped;
600setResolution( getResolution().x, getResolution().y, getResolution().z );
601}
602
603//--------------------------------------------------------------
604void ofCylinderPrimitive::setResolutionRadius( int radiusRes ) {
605setResolution( radiusRes, getResolutionHeight(), getResolutionCap() );
606}
607
608//--------------------------------------------------------------
609void ofCylinderPrimitive::setResolutionHeight( int heightRes ) {
610setResolution( getResolutionRadius(), heightRes, getResolutionCap() );
611}
612
613//--------------------------------------------------------------
614void ofCylinderPrimitive::setResolutionCap( int capRes ) {
615setResolution( getResolutionRadius(), getResolutionHeight(), capRes );
616}
617
618//--------------------------------------------------------------
619void ofCylinderPrimitive::setResolution( int radiusSegments, int heightSegments, int capSegments ) {
620ofPrimitiveMode mode = getMesh().getMode();
621set( getRadius(), getHeight(), radiusSegments, heightSegments, capSegments, getCapped(), mode );
622}
623
624//----------------------------------------------------------
625void ofCylinderPrimitive::setMode( ofPrimitiveMode mode ) {
626ofPrimitiveMode currMode = getMesh().getMode();
627if(currMode != mode)
628set( getRadius(), getHeight(), getResolution().x, getResolution().y, getResolution().z, getCapped(), mode );
629}
630
631//--------------------------------------------------------------
632void ofCylinderPrimitive::setTopCapColor( ofColor color ) {
633if(getMesh().getMode() != OF_PRIMITIVE_TRIANGLE_STRIP) {
634ofLogWarning("ofCylinderPrimitive") << "setTopCapColor(): must be in triangle strip mode";
635}
636getMesh().setColorForIndices( strides[0][0], strides[0][0]+strides[0][1], color );
637}
638
639//--------------------------------------------------------------
640void ofCylinderPrimitive::setCylinderColor( ofColor color ) {
641if(getMesh().getMode() != OF_PRIMITIVE_TRIANGLE_STRIP) {
642ofLogWarning("ofCylinderPrimitive") << "setCylinderMode(): must be in triangle strip mode";
643}
644getMesh().setColorForIndices( strides[1][0], strides[1][0]+strides[1][1], color );
645}
646
647//--------------------------------------------------------------
648void ofCylinderPrimitive::setBottomCapColor( ofColor color ) {
649if(getMesh().getMode() != OF_PRIMITIVE_TRIANGLE_STRIP) {
650ofLogWarning("ofCylinderPrimitive") << "setBottomCapColor(): must be in triangle strip mode";
651}
652getMesh().setColorForIndices( strides[2][0], strides[2][0]+strides[2][1], color );
653}
654
655//--------------------------------------------------------------
656vector<ofIndexType> ofCylinderPrimitive::getTopCapIndices() const {
657return of3dPrimitive::getIndices( strides[0][0], strides[0][0] + strides[0][1] );
658}
659
660//--------------------------------------------------------------
661ofMesh ofCylinderPrimitive::getTopCapMesh() const {
662if(getMesh().getMode() != OF_PRIMITIVE_TRIANGLE_STRIP) {
663ofLogWarning("ofCylinderPrimitive") << "getTopCapMesh(): must be in triangle strip mode";
664return ofMesh();
665}
666return getMesh().getMeshForIndices( strides[0][0], strides[0][0]+strides[0][1],
667vertices[0][0], vertices[0][0]+vertices[0][1] );
668}
669
670//--------------------------------------------------------------
671vector<ofIndexType> ofCylinderPrimitive::getCylinderIndices() const {
672if(getMesh().getMode() != OF_PRIMITIVE_TRIANGLE_STRIP) {
673ofLogWarning("ofCylinderPrimitive") << "getCylinderIndices(): must be in triangle strip mode";
674}
675return of3dPrimitive::getIndices( strides[1][0], strides[1][0] + strides[1][1] );
676}
677
678//--------------------------------------------------------------
679ofMesh ofCylinderPrimitive::getCylinderMesh() const {
680if(getMesh().getMode() != OF_PRIMITIVE_TRIANGLE_STRIP) {
681ofLogWarning("ofCylinderPrimitive") << "setCylinderMesh(): must be in triangle strip mode";
682return ofMesh();
683}
684return getMesh().getMeshForIndices( strides[1][0], strides[1][0]+strides[1][1],
685vertices[1][0], vertices[1][0]+vertices[1][1] );
686}
687
688//--------------------------------------------------------------
689vector<ofIndexType> ofCylinderPrimitive::getBottomCapIndices() const {
690if(getMesh().getMode() != OF_PRIMITIVE_TRIANGLE_STRIP) {
691ofLogWarning("ofCylinderPrimitive") << "getBottomCapIndices(): must be in triangle strip mode";
692}
693return of3dPrimitive::getIndices( strides[2][0], strides[2][0] + strides[2][1] );
694}
695
696//--------------------------------------------------------------
697ofMesh ofCylinderPrimitive::getBottomCapMesh() const {
698if(getMesh().getMode() != OF_PRIMITIVE_TRIANGLE_STRIP) {
699ofLogWarning("ofCylinderPrimitive") << "getBottomCapMesh(): must be in triangle strip mode";
700return ofMesh();
701}
702return getMesh().getMeshForIndices( strides[2][0], strides[2][0]+strides[2][1],
703vertices[2][0], vertices[2][0]+vertices[2][1] );
704}
705
706//--------------------------------------------------------------
707int ofCylinderPrimitive::getResolutionRadius() const {
708return (int)resolution.x;
709}
710
711//--------------------------------------------------------------
712int ofCylinderPrimitive::getResolutionHeight() const {
713return (int)resolution.y;
714}
715
716//--------------------------------------------------------------
717int ofCylinderPrimitive::getResolutionCap() const {
718return (int)resolution.z;
719}
720
721//--------------------------------------------------------------
722glm::vec3 ofCylinderPrimitive::getResolution() const {
723return resolution;
724}
725
726//--------------------------------------------------------------
727float ofCylinderPrimitive::getHeight() const {
728return height;
729}
730
731//--------------------------------------------------------------
732float ofCylinderPrimitive::getRadius() const {
733return radius;
734}
735
736//--------------------------------------------------------------
737bool ofCylinderPrimitive::getCapped() const {
738return bCapped;
739}
740
741
742
743
744
745// Cone Primitive //
746//--------------------------------------------------------------
747ofConePrimitive::ofConePrimitive() {
748texCoords = {0.f, 0.f, 1.f, 1.f};
749set( 20, 70, 8, 3, 2 );
750}
751
752//--------------------------------------------------------------
753ofConePrimitive::ofConePrimitive( float radius, float height, int radiusSegments, int heightSegments, int capSegments, ofPrimitiveMode mode ) {
754texCoords = {0.f, 0.f, 1.f, 1.f};
755set( radius, height, radiusSegments, heightSegments, capSegments, mode );
756}
757
758//--------------------------------------------------------------
759ofConePrimitive::~ofConePrimitive() {}
760
761//--------------------------------------------------------------
762void ofConePrimitive::set( float _radius, float _height, int radiusSegments, int heightSegments, int capSegments, ofPrimitiveMode mode ) {
763radius = _radius;
764height = _height;
765resolution = {radiusSegments, heightSegments, capSegments};
766
767int resX = std::max(getResolution().x, 0.0f);
768int resY = std::max(getResolution().y-1, 0.0f);
769int resZ = std::max(getResolution().z-1, 0.0f);
770
771int indexStep = 2;
772if(mode == OF_PRIMITIVE_TRIANGLES) {
773indexStep = 6;
774resX = std::max(resX-1, 0);
775}
776
777strides[ 0 ][0] = 0;
778strides[ 0 ][1] = (resX+1)*(resY+1) * indexStep;
779vertices[0][0] = 0;
780vertices[0][1] = (getResolution().x+1) * (getResolution().y+1);
781
782strides[ 1 ][0] = strides[ 0 ][0] + strides[ 0 ][1];
783strides[ 1 ][1] = (resX+1)*(resZ+1) * indexStep;
784vertices[1][0] = vertices[0][0] + vertices[0][1];
785vertices[1][1] = (getResolution().x+1) * (getResolution().z+1);
786
787getMesh() = ofMesh::cone( getRadius(), getHeight(), getResolution().x, getResolution().y, getResolution().z, mode );
788
789normalizeAndApplySavedTexCoords();
790
791}
792
793//--------------------------------------------------------------
794void ofConePrimitive::set( float _radius, float _height ) {
795radius = _radius;
796height = _height;
797setResolution( getResolution().x, getResolution().y, getResolution().z );
798}
799
800//--------------------------------------------------------------
801void ofConePrimitive::setResolutionRadius( int radiusRes ) {
802setResolution( radiusRes, getResolutionHeight(), getResolutionCap() );
803}
804
805//--------------------------------------------------------------
806void ofConePrimitive::setResolutionHeight( int heightRes ) {
807setResolution( getResolutionRadius(), heightRes, getResolutionCap() );
808}
809
810//--------------------------------------------------------------
811void ofConePrimitive::setResolutionCap( int capRes ) {
812setResolution( getResolutionRadius(), getResolutionHeight(), capRes );
813}
814
815//--------------------------------------------------------------
816void ofConePrimitive::setResolution( int radiusRes, int heightRes, int capRes ) {
817ofPrimitiveMode mode = getMesh().getMode();
818set( getRadius(), getHeight(), radiusRes, heightRes, capRes, mode );
819}
820
821//----------------------------------------------------------
822void ofConePrimitive::setMode( ofPrimitiveMode mode ) {
823ofPrimitiveMode currMode = getMesh().getMode();
824if(currMode != mode)
825set( getRadius(), getHeight(), getResolution().x, getResolution().y, getResolution().z, mode );
826}
827
828//--------------------------------------------------------------
829void ofConePrimitive::setRadius( float _radius ) {
830radius = _radius;
831setResolution(getResolution().x, getResolution().y, getResolution().z);
832}
833
834//--------------------------------------------------------------
835void ofConePrimitive::setHeight(float _height) {
836height = _height;
837setResolution(getResolution().x, getResolution().y, getResolution().z);
838}
839
840//--------------------------------------------------------------
841void ofConePrimitive::setTopColor( ofColor color ) {
842if(getMesh().getMode() != OF_PRIMITIVE_TRIANGLE_STRIP) {
843ofLogWarning("ofConePrimitive") << "setTopColor(): must be in triangle strip mode";
844}
845getMesh().setColorForIndices( strides[0][0], strides[0][0]+strides[0][1], color );
846}
847
848//--------------------------------------------------------------
849void ofConePrimitive::setCapColor( ofColor color ) {
850if(getMesh().getMode() != OF_PRIMITIVE_TRIANGLE_STRIP) {
851ofLogWarning("ofConePrimitive") << "setCapColor(): must be in triangle strip mode";
852}
853getMesh().setColorForIndices( strides[1][0], strides[1][0]+strides[1][1], color );
854}
855
856//--------------------------------------------------------------
857vector<ofIndexType> ofConePrimitive::getConeIndices() const {
858if(getMesh().getMode() != OF_PRIMITIVE_TRIANGLE_STRIP) {
859ofLogWarning("ofConePrimitive") << "getConeIndices(): must be in triangle strip mode";
860}
861return of3dPrimitive::getIndices(strides[0][0], strides[0][0]+strides[0][1]);
862}
863
864//--------------------------------------------------------------
865ofMesh ofConePrimitive::getConeMesh() const {
866int startIndex = strides[0][0];
867int endIndex = startIndex + strides[0][1];
868
869int startVertIndex = vertices[0][0];
870int endVertIndex = startVertIndex + vertices[0][1];
871if(getMesh().getMode() != OF_PRIMITIVE_TRIANGLE_STRIP) {
872ofLogWarning("ofConePrimitive") << "getConeMesh(): must be in triangle strip mode";
873return ofMesh();
874}
875return getMesh().getMeshForIndices( startIndex, endIndex, startVertIndex, endVertIndex );
876}
877
878//--------------------------------------------------------------
879vector<ofIndexType> ofConePrimitive::getCapIndices() const {
880if(getMesh().getMode() != OF_PRIMITIVE_TRIANGLE_STRIP) {
881ofLogWarning("ofConePrimitive") << "getCapIndices(): must be in triangle strip mode";
882}
883return of3dPrimitive::getIndices( strides[1][0], strides[1][0] + strides[1][1] );
884}
885
886//--------------------------------------------------------------
887ofMesh ofConePrimitive::getCapMesh() const {
888int startIndex = strides[1][0];
889int endIndex = startIndex + strides[1][1];
890
891int startVertIndex = vertices[1][0];
892int endVertIndex = startVertIndex + vertices[1][1];
893if(getMesh().getMode() != OF_PRIMITIVE_TRIANGLE_STRIP) {
894ofLogWarning("ofConePrimitive") << "getCapMesh(): must be in triangle strip mode";
895return ofMesh();
896}
897return getMesh().getMeshForIndices( startIndex, endIndex, startVertIndex, endVertIndex );
898}
899
900//--------------------------------------------------------------
901int ofConePrimitive::getResolutionRadius() const {
902return (int)resolution.x;
903}
904
905//--------------------------------------------------------------
906int ofConePrimitive::getResolutionHeight() const {
907return (int)resolution.y;
908}
909
910//--------------------------------------------------------------
911int ofConePrimitive::getResolutionCap() const {
912return (int)resolution.z;
913}
914
915//--------------------------------------------------------------
916glm::vec3 ofConePrimitive::getResolution() const {
917return resolution;
918}
919
920//--------------------------------------------------------------
921float ofConePrimitive::getRadius() const {
922return radius;
923}
924
925//--------------------------------------------------------------
926float ofConePrimitive::getHeight() const {
927return height;
928}
929
930
931
932
933
934// BOX PRIMITIVE //
935//--------------------------------------------------------------
936ofBoxPrimitive::ofBoxPrimitive() {
937texCoords = {0.f, 0.f, 1.f, 1.f};
938set(100, 100, 100, 2, 2, 2);
939}
940
941//--------------------------------------------------------------
942ofBoxPrimitive::ofBoxPrimitive( float width, float height, float depth, int resWidth, int resHeight, int resDepth ) {
943texCoords = {0.f, 0.f, 1.f, 1.f};
944set(width, height, depth, resWidth, resHeight, resDepth );
945}
946
947//--------------------------------------------------------------
948ofBoxPrimitive::~ofBoxPrimitive() {}
949
950//--------------------------------------------------------------
951void ofBoxPrimitive::set( float width, float height, float depth, int resWidth, int resHeight, int resDepth) {
952
953size.x = width;
954size.y = height;
955size.z = depth;
956
957resolution = {resWidth, resHeight, resDepth};
958
959int resX = getResolution().x;
960int resY = getResolution().y;
961int resZ = getResolution().z;
962
963//FRONT, resY, resX
964strides[ SIDE_FRONT ][0] = 0;
965strides[ SIDE_FRONT ][1] = (resY)*(resX)*6;
966vertices[SIDE_FRONT][0] = 0;
967vertices[SIDE_FRONT][1] = (resX+1) * (resY+1);
968
969//RIGHT, resY, resZ
970strides[ SIDE_RIGHT ][0] = strides[ SIDE_FRONT ][0] + strides[ SIDE_FRONT ][1];
971strides[ SIDE_RIGHT ][1] = (resY)*(resZ)*6;
972vertices[SIDE_RIGHT][0] = vertices[SIDE_FRONT][0] + vertices[SIDE_FRONT][1];
973vertices[SIDE_RIGHT][1] = (resY+1) * (resZ+1);
974
975//LEFT, resY, resZ
976strides[ SIDE_LEFT ][0] = strides[ SIDE_RIGHT ][0] + strides[ SIDE_RIGHT ][1];
977strides[ SIDE_LEFT ][1] = (resY)*(resZ)*6;
978vertices[SIDE_LEFT][0] = vertices[SIDE_RIGHT][0] + vertices[SIDE_RIGHT][1];
979vertices[SIDE_LEFT][1] = (resY+1) * (resZ+1);
980
981//BACK, resY, resX
982strides[ SIDE_BACK ][0] = strides[ SIDE_LEFT ][0] + strides[ SIDE_LEFT ][1];
983strides[ SIDE_BACK ][1] = (resY)*(resX)*6;
984vertices[SIDE_BACK][0] = vertices[SIDE_LEFT][0] + vertices[SIDE_LEFT][1];
985vertices[SIDE_BACK][1] = (resY+1) * (resZ+1);
986
987//TOP, resZ, resX
988strides[ SIDE_TOP ][0] = strides[ SIDE_BACK ][0] + strides[ SIDE_BACK ][1];
989strides[ SIDE_TOP ][1] = (resZ)*(resX)*6;
990vertices[SIDE_TOP][0] = vertices[SIDE_BACK][0] + vertices[SIDE_BACK][1];
991vertices[SIDE_TOP][1] = (resY+1) * (resZ+1);
992
993//BOTTOM, resZ, resX
994strides[ SIDE_BOTTOM ][0] = strides[ SIDE_TOP ][0]+strides[ SIDE_TOP ][1];
995strides[ SIDE_BOTTOM ][1] = (resZ)*(resX)*6;
996vertices[SIDE_BOTTOM][0] = vertices[SIDE_TOP][0] + vertices[SIDE_TOP][1];
997vertices[SIDE_BOTTOM][1] = (resY+1) * (resZ+1);
998
999getMesh() = ofMesh::box( getWidth(), getHeight(), getDepth(), getResolution().x, getResolution().y, getResolution().z );
1000
1001normalizeAndApplySavedTexCoords();
1002}
1003
1004//--------------------------------------------------------------
1005void ofBoxPrimitive::set( float width, float height, float depth ) {
1006set( width, height, depth, getResolution().x, getResolution().y, getResolution().z );
1007}
1008
1009//--------------------------------------------------------------
1010void ofBoxPrimitive::set( float size ) {
1011set( size, size, size );
1012}
1013
1014//--------------------------------------------------------------
1015void ofBoxPrimitive::setWidth( float a_width ) {
1016size.x = a_width;
1017set( getWidth(), getHeight(), getDepth() );
1018}
1019
1020//--------------------------------------------------------------
1021void ofBoxPrimitive::setHeight( float a_height ) {
1022size.y = a_height;
1023set( getWidth(), getHeight(), getDepth() );
1024}
1025
1026//--------------------------------------------------------------
1027void ofBoxPrimitive::setDepth( float a_depth ) {
1028size.z = a_depth;
1029set( getWidth(), getHeight(), getDepth() );
1030}
1031
1032//--------------------------------------------------------------
1033void ofBoxPrimitive::resizeToTexture( ofTexture& inTexture ) {
1034set(inTexture.getWidth(), inTexture.getHeight(), inTexture.getWidth());
1035mapTexCoordsFromTexture( inTexture );
1036}
1037
1038//--------------------------------------------------------------
1039vector<ofIndexType> ofBoxPrimitive::getSideIndices( int sideIndex ) const {
1040
1041if(sideIndex < 0 || sideIndex >= SIDES_TOTAL) {
1042ofLogWarning("ofBoxPrimitive") << "getSideIndices(): faceIndex out of bounds, returning SIDE_FRONT";
1043sideIndex = SIDE_FRONT;
1044}
1045
1046return getIndices(strides[sideIndex][0], strides[sideIndex][0]+strides[sideIndex][1]);
1047}
1048
1049//--------------------------------------------------------------
1050ofMesh ofBoxPrimitive::getSideMesh( int sideIndex ) const {
1051
1052if(sideIndex < 0 || sideIndex > SIDES_TOTAL) {
1053ofLogWarning("ofBoxPrimitive") << "getSideMesh(): faceIndex out of bounds, using SIDE_FRONT";
1054sideIndex = SIDE_FRONT;
1055}
1056int startIndex = strides[sideIndex][0];
1057int endIndex = startIndex+strides[sideIndex][1];
1058
1059int startVertIndex = vertices[sideIndex][0];
1060int endVertIndex = startVertIndex + vertices[sideIndex][1];
1061
1062return getMesh().getMeshForIndices( startIndex, endIndex, startVertIndex, endVertIndex );
1063}
1064
1065//--------------------------------------------------------------
1066void ofBoxPrimitive::setResolution( int res ) {
1067setResolution(res, res, res);
1068}
1069
1070//--------------------------------------------------------------
1071void ofBoxPrimitive::setResolutionWidth( int widthRes ) {
1072setResolution( widthRes, getResolutionHeight(), getResolutionDepth() );
1073}
1074
1075//--------------------------------------------------------------
1076void ofBoxPrimitive::setResolutionHeight( int heightRes ) {
1077setResolution( getResolutionWidth(), heightRes, getResolutionDepth() );
1078}
1079
1080//--------------------------------------------------------------
1081void ofBoxPrimitive::setResolutionDepth( int depthRes ) {
1082setResolution( getResolutionWidth(), getResolutionHeight(), depthRes );
1083}
1084
1085//--------------------------------------------------------------
1086void ofBoxPrimitive::setResolution( int resWidth, int resHeight, int resDepth ) {
1087resolution = {resWidth, resHeight, resDepth};
1088set( getWidth(), getHeight(), getDepth() );
1089}
1090
1091//----------------------------------------------------------
1092void ofBoxPrimitive::setMode( ofPrimitiveMode mode ) {
1093// only supports triangles //
1094setResolution( getResolution().x, getResolution().y, getResolution().z );
1095}
1096
1097//--------------------------------------------------------------
1098void ofBoxPrimitive::setSideColor( int sideIndex, ofColor color ) {
1099if(sideIndex < 0 || sideIndex >= SIDES_TOTAL) {
1100ofLogWarning("ofBoxPrimitive") << "setSideColor(): sideIndex out of bounds, setting SIDE_FRONT";
1101sideIndex = SIDE_FRONT;
1102}
1103getMesh().setColorForIndices( strides[sideIndex][0], strides[sideIndex][0]+strides[sideIndex][1], color );
1104}
1105
1106//--------------------------------------------------------------
1107int ofBoxPrimitive::getResolutionWidth() const {
1108return (int)resolution.x;
1109}
1110
1111//--------------------------------------------------------------
1112int ofBoxPrimitive::getResolutionHeight() const {
1113return (int)resolution.y;
1114}
1115
1116//--------------------------------------------------------------
1117int ofBoxPrimitive::getResolutionDepth() const {
1118return (int)resolution.z;
1119}
1120
1121//--------------------------------------------------------------
1122glm::vec3 ofBoxPrimitive::getResolution() const {
1123return resolution;
1124}
1125
1126//--------------------------------------------------------------
1127float ofBoxPrimitive::getWidth() const {
1128return size.x;
1129}
1130
1131//--------------------------------------------------------------
1132float ofBoxPrimitive::getHeight() const {
1133return size.y;
1134}
1135
1136//--------------------------------------------------------------
1137float ofBoxPrimitive::getDepth() const {
1138return size.z;
1139}
1140
1141//--------------------------------------------------------------
1142glm::vec3 ofBoxPrimitive::getSize() const {
1143return size;
1144}
1145