00001 /*================================================================================= 00002 *** THE CONTENT OF THIS WORK IS PROPRIETARY TO FEI S.A.S, (FEI S.A.S.), *** 00003 *** AND IS DISTRIBUTED UNDER A LICENSE AGREEMENT. *** 00004 *** *** 00005 *** REPRODUCTION, DISCLOSURE, OR USE, IN WHOLE OR IN PART, OTHER THAN AS *** 00006 *** SPECIFIED IN THE LICENSE ARE NOT TO BE UNDERTAKEN EXCEPT WITH PRIOR *** 00007 *** WRITTEN AUTHORIZATION OF FEI S.A.S. *** 00008 *** *** 00009 *** RESTRICTED RIGHTS LEGEND *** 00010 *** USE, DUPLICATION, OR DISCLOSURE BY THE GOVERNMENT OF THE CONTENT OF THIS *** 00011 *** WORK OR RELATED DOCUMENTATION IS SUBJECT TO RESTRICTIONS AS SET FORTH IN *** 00012 *** SUBPARAGRAPH (C)(1) OF THE COMMERCIAL COMPUTER SOFTWARE RESTRICTED RIGHT *** 00013 *** CLAUSE AT FAR 52.227-19 OR SUBPARAGRAPH (C)(1)(II) OF THE RIGHTS IN *** 00014 *** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 52.227-7013. *** 00015 *** *** 00016 *** COPYRIGHT (C) 1996-2019 BY FEI S.A.S, *** 00017 *** BORDEAUX, FRANCE *** 00018 *** ALL RIGHTS RESERVED *** 00019 =================================================================================*/ 00020 00021 #pragma once 00022 00023 #include <Inventor/bundles/SoBundle.h> 00024 #include <Inventor/elements/SoTangentElement.h> 00025 #include <Inventor/elements/SoTangentBindingElement.h> 00026 #include <Inventor/misc/SoTangentGenerator.h> 00027 00028 class SoTangentCache; 00029 00040 { 00041 public: 00042 SoTangentBundle( SoAction* action ); 00043 00044 virtual ~SoTangentBundle(); 00045 00046 // Returns true if tangents need to be generated. 00047 bool shouldGenerate( int numNeeded ); 00048 00049 // Initializes generation in the case where shouldGenerate() is 00050 // not called. (shouldGenerate() does this automatically). 00051 void initGenerator( int initialNum = 100 ); 00052 00054 // 00055 // If shouldGenerate() returns TRUE, these methods can be used by 00056 // shapes to specify the geometry to generate tangents for. They 00057 // are front-ends to methods on the SoTangentGenerator class: 00058 // 00059 00060 // Send a line strip's worth of vertices. Begin a strip, send as 00061 // many vertices as you want, and then end the strip. 00062 void beginLineStrip() 00063 { 00064 m_generator->beginLineStrip(); 00065 } 00066 00067 void lineStripVertex( const SbVec3f& point ) 00068 { 00069 m_generator->lineStripVertex( point ); 00070 } 00071 00072 void endLineStrip() 00073 { 00074 m_generator->endLineStrip(); 00075 } 00076 00077 // See SoTangentGenerator for details. 00078 void setupIndexedVertexArray( const SbVec3f* pointArray ) 00079 { 00080 m_generator->setupIndexedVertexArray( pointArray ); 00081 } 00082 00083 void lineStripVertex( const int32_t index ) 00084 { 00085 m_generator->lineStripVertex( index ); 00086 } 00087 00088 void setupApproxShapeSize( const int32_t numVert ) 00089 { 00090 m_generator->setupApproxShapeSize( numVert ); 00091 } 00092 00093 // Calculates the tangents once all vertices have been sent. The 00094 // tangents are stored by the bundle so the caller does not have to 00095 // deal with them directly. The startIndex argument specifies the 00096 // index at which the generated tangents will begin-- it can be 00097 // used by shapes that allow the coordinates and tangents to be 00098 // offset (non-indexed shapes). If addToState is TRUE, the 00099 // state will be pushed, the tangents will be added to the 00100 // state; otherwise, you can just use 00101 // getGeneratedTangents/getNumGeneratedTangents to get the generated 00102 // tangents. 00103 // 00104 // The tangent bundle DOES NOT FREE the generated tangents! It is 00105 // expected that tangents will be added to a tangent cache, and the 00106 // tangent cache will free the tangents. 00107 // 00108 void generate( int startIndex = 0, bool addToState = true ); 00109 00110 // Returns the generated tangents. 00111 const SbVec3f* getGeneratedTangents() const 00112 { 00113 return m_generator->getTangents(); 00114 } 00115 00116 int getNumGeneratedTangents() const 00117 { 00118 return m_generator->getNumTangents(); 00119 } 00120 00121 SoTangentBindingElement::Binding getTangentBinding() const 00122 { 00123 return m_generator->getBinding(); 00124 } 00125 00126 00127 // This allows shapes that generate their own tangents (for 00128 // efficiency) to store the resulting tangents in the state. The 00129 // bundle takes care of pushing/popping the state. 00130 // Note: This method only adds the tangents to the state, it does 00131 // NOT store a pointer to them (so you cannot call the 00132 // getGenerated() routines) 00133 void set( 00134 int32_t numTangents, 00135 const SbVec3f* tangents, 00136 SoTangentBindingElement::Binding binding /*= SoTangentBindingElement::PER_VERTEX */, 00137 int startIndex = 0 00138 ); 00139 00140 // to set the SoTangentBundle from a SoTangentCache 00141 void set( SoTangentCache* tc ); 00142 00143 // Returns indexed tangent. This can be used for primitive 00144 // generation or during rendering 00145 const SbVec3f& get( int index ) const 00146 { 00147 return m_tangElt->getNum() != 0 ? m_tangElt->get( index - m_startIndex ) : s_zVers; 00148 } 00149 00150 int getStartIndex() const 00151 { 00152 return m_startIndex; 00153 } 00154 00155 private: 00156 SoTangentGenerator* m_generator; 00157 00158 private: 00159 // Tangent elements: 00160 const SoTangentElement* m_tangElt; 00161 bool m_pushedState; // We pushed state to set tangents 00162 SoNode* m_currentNode; // Node that created the bundle 00163 static const SbVec3f s_zVers; 00164 int m_startIndex; // this the offset used in indexing the tangents WITHOUT allocating useless memory 00165 bool m_tangSetOrGen; 00166 }; 00167