inline int sortCompare(RexxString *other, sizeC_t startCol, sizeC_t colLength) { int result = 0; if ((startCol < clength ) && (startCol < other->clength)) { sizeC_t stringLength = clength; if (stringLength > other->clength) { stringLength = other->clength; } stringLength = stringLength - startCol + 1; sizeC_t compareLength = colLength; if (compareLength > stringLength) { compareLength = stringLength; } result = memcmp(stringData + size_v(startCol), other->stringData + size_v(startCol), size_v(compareLength)); // todo m17n if (result == 0 && stringLength < colLength) { if (clength > other->clength) { result = 1; } else if (clength < other->clength) { result = -1; } } } else { if (clength == other->clength) { result = 0; } else { result = clength < other->clength ? -1 : 1; } } return result; }
void mesh_parametric_cloth::set_plane_xy_unit(int const size_u_param,int const size_v_param) { mesh_parametric::set_plane_xy_unit(size_u_param,size_v_param); int const N = size_u()*size_v(); speed_data.resize(N); force_data.resize(N); }
inline int rsnprintf(RexxString *s, const char *format, ...) { va_list args; va_start(args, format); int n = Utilities::vsnprintf(s->getWritableData(), size_v(s->getBLength()), format, args); va_end(args); s->finish(n >= 0 ? n : 0); return n; }
inline void finish(stringsizeB_t bl, sizeC_t cl=-1) { this->blength = bl; this->clength = cl == -1 ? sizeC_v(size_v(bl)) // todo m17n: calculate length in characters : cl; }
vec3 mesh_parametric::normal(int const ku,int const kv) const { ASSERT_CPE(ku >= 0 , "Value ku ("+std::to_string(ku)+") should be >=0 "); ASSERT_CPE(ku < size_u() , "Value ku ("+std::to_string(ku)+") should be < size_u ("+std::to_string(size_u())+")"); ASSERT_CPE(ku >= 0 , "Value kv ("+std::to_string(kv)+") should be >=0 "); ASSERT_CPE(ku < size_v() , "Value kv ("+std::to_string(kv)+") should be < size_v ("+std::to_string(size_v())+")"); int const offset = ku+size_u_data*kv; return mesh_basic::normal(offset); }
void mesh_parametric_cloth::integration_step(float const dt) { ASSERT_CPE(speed_data.size() == force_data.size(),"Incorrect size"); ASSERT_CPE(static_cast<int>(speed_data.size()) == size_vertex(),"Incorrect size"); int const Nu = size_u();//nombre de ressort int const Nv = size_v();//nombre de ressort //*************************************************************// // TO DO: Calculer l'integration numerique des positions au cours de l'intervalle de temps dt. //*************************************************************// //security check (throw exception if divergence is detected) static float const LIMIT=30.0f; for(int ku=0 ; ku<Nu; ++ku) { for(int kv=0; kv<Nv; ++kv) { vec3 & p = vertex(ku,kv); speed(ku,kv)=(1-mu*dt)*speed(ku,kv)+ dt*force(ku,kv);//gg c'est beau p = p + dt*speed(ku,kv); // collision avec le sol if (p.z() < -1.101f)// hauteur du sol { p.z()= -1.100f; force(ku,kv).z() = 0.0f; speed(ku,kv).z() = 0.0f; } // collision avec la sphere vec3 centre_sphere = {0.5f,0.05f,-1.1f}; vec3 normale= p-centre_sphere; float rayon =0.4f; if (norm(normale)<rayon) { p= centre_sphere + normale/norm(normale) * rayon; //on annule la composante normale de la force et de la vitesse speed(ku,kv) -= dot (speed(ku,kv),normale/norm(normale)) * normale; force(ku,kv) -= dot (force(ku,kv),normale/norm(normale)) * normale; //on annule la composante normale de la force et de la vitesse } } } }
vec3& mesh_parametric_cloth::force(int const ku,int const kv) { ASSERT_CPE(ku >= 0 , "Value ku ("+std::to_string(ku)+") should be >=0 "); ASSERT_CPE(ku < size_u() , "Value ku ("+std::to_string(ku)+") should be < size_u ("+std::to_string(size_u())+")"); ASSERT_CPE(kv >= 0 , "Value kv ("+std::to_string(kv)+") should be >=0 "); ASSERT_CPE(kv < size_v() , "Value kv ("+std::to_string(kv)+") should be < size_v ("+std::to_string(size_v())+")"); int const offset = ku + size_u()*kv; ASSERT_CPE(offset < static_cast<int>(force_data.size()),"Internal error"); return force_data[offset]; }
bool mesh_parametric::valid_mesh() const { int const total_size=size_u()*size_v(); if(size_vertex()!=total_size || size_color()!=total_size || size_texture_coord()!=total_size || size_normal()!=total_size ) { std::cout<<"mesh parametric has incorrect data size"<<std::endl; return false; } return mesh_basic::valid_mesh(); }
inline void toRxstring(RXSTRING &r) { r.strptr = getWritableData(); r.strlength = size_v(getBLength()); }
inline void toRxstring(CONSTRXSTRING &r) { r.strptr = getStringData(); r.strlength = size_v(getBLength()); } // no encoding support, so better to use blength
inline codepoint_t getCharC(sizeC_t p) { return *(this->stringData+size_v(p)); }; // todo call m17n : convert charpos to bytepos and return a codepoint, not a byte
RexxString *extractC(sizeC_t offset, sizeC_t sublength) // Extract characters { return newString(getStringData() + size_v(offset), size_v(sublength), sublength); // todo m17n }
void mesh_parametric_cloth::update_force() { int const Nu = size_u(); int const Nv = size_v(); int const N_total = Nu*Nv; ASSERT_CPE(static_cast<int>(force_data.size()) == Nu*Nv , "Error of size"); //wind direction vec3 uw=vec3( x_wind,y_wind,z_wind); uw= normalized(uw); //Gravity and wind static vec3 const g (0.0f,0.0f,-9.81f); vec3 const g_normalized = g/N_total; for(int ku=0 ; ku<Nu ; ++ku) { for(int kv=0 ; kv<Nv ; ++kv) { force(ku,kv) = g_normalized; vec3 n=this->normal(ku,kv); force(ku,kv) += Kw*dot(n,uw)*n; } } //*************************************************************// // TO DO, Calculer les forces s'appliquant sur chaque sommet //*************************************************************// //*************************************************************// float L01= 1.0f/(Nu-1); float L02= sqrt(2)/(Nu-1); float L03= 2.0f/(Nu-1); for(int ku=0 ; ku<Nu; ++ku) { for(int kv=0 ; kv<Nv; ++kv) { vec3 const& p = vertex(ku,kv); std::vector<vec3> pvd; std::vector<vec3> pvdiag; std::vector<vec3> pvb; /** cas general **/ //voisin directs if( kv < Nv-1) { pvd.push_back(vertex(ku,kv+1)); } if( kv > 0) { pvd.push_back(vertex(ku,kv-1)); } if( ku < Nu-1) { pvd.push_back(vertex(ku+1,kv)); } if( ku > 0) { pvd.push_back(vertex(ku-1,kv)); } //voisin diagonale if( ku< Nu -1 && kv < Nv-1 ) { pvdiag.push_back(vertex(ku+1,kv+1)); } if( ku < Nu-1 && kv >0 ) { pvdiag.push_back(vertex(ku+1,kv-1)); } if( ku > 0 && kv > 0 ) { pvdiag.push_back(vertex(ku-1,kv-1)); } if( ku>0 && kv< Nu -1) { pvdiag.push_back(vertex(ku-1,kv+1)); } //voisin bend if( ku < Nu -2) { pvb.push_back(vertex(ku+2,kv)); } if( ku >1 ) { pvb.push_back(vertex(ku-2,kv)); } if( kv < Nv -2) { pvb.push_back(vertex(ku,kv+2)); } if( kv >1 ) { pvb.push_back(vertex(ku,kv-2)); } for (int i=0; i<int(pvd.size());i++) { vec3 u=p-pvd[i]; force(ku,kv) += (Kdirect *(L01 - norm(u)) *u) /norm(u); } for (int i=0; i<int (pvdiag.size());i++) { vec3 u=p-pvdiag[i]; force(ku,kv) +=( Kdiag *(L02 - norm(u))*u) /norm(u); } for (int i=0; i<int (pvb.size());i++) { vec3 u=p-pvb[i]; force(ku,kv) +=( Kdouble *(L03 - norm(u))*u) /norm(u); } // on bloque les angles if ((ku == 0 && kv == 0 ) || (ku == 0 && kv == Nv -1)) { //if ((ku == Nu-1 && kv == Nv-1 )||(ku == Nu-1 && kv == 0 )||(ku == 0 && kv == 0 ) || (ku == 0 && kv == Nv -1)) { force(ku,kv) = vec3(0.0f,0.0f, 0.0f); } } } }
// in behaviour RexxString *RexxString::space(RexxInteger *space_count, RexxString *pad) { sizeC_t Spaces; /* requested spacing */ codepoint_t PadChar; /* pad character */ char *Current; /* current pointer position */ const char *Word; /* current word pointer */ const char *NextSite; /* next word */ sizeB_t Count; /* count of words */ sizeB_t WordSize; /* size of words */ sizeB_t Length; /* remaining length */ sizeB_t WordLength; /* word size */ RexxString *Retval; /* return value */ /* get the spacing count */ Spaces = optionalLengthArgument(space_count, 1, ARG_ONE); /* get the pad character */ PadChar = optionalPadArgument(pad, ' ', ARG_TWO); Length = this->getBLength(); /* get the string length */ Count = 0; /* no words yet */ WordSize = 0; /* no characters either */ Word = this->getStringData(); /* point to the string */ /* get the first word */ WordLength = StringUtil::nextWord(&Word, &Length, &NextSite); while (WordLength != 0) { /* loop until we reach tArget */ Count++; /* count the word */ WordSize += WordLength; /* add in the word length */ Word = NextSite; /* copy the start pointer */ /* get the next word */ WordLength = StringUtil::nextWord(&Word, &Length, &NextSite); } if (Count == 0) /* no words? */ { Retval = OREF_NULLSTRING; /* this is a null string */ } else { /* real words */ Count--; /* step back one */ /* get space for output */ Retval = raw_string(WordSize + Count * size_v(Spaces)); // todo m17n : Spaces is a char count /* point to output area */ Current = Retval->getWritableData(); Length = this->getBLength(); /* recover the length */ Word = this->getStringData(); /* point to the string */ /* get the first word */ WordLength = StringUtil::nextWord(&Word, &Length, &NextSite); while (Count-- != 0) { /* loop for each word */ /* copy the word over */ memcpy(Current, Word, WordLength); Current += WordLength; /* step over the word */ if (Spaces != 0) { /* if have gaps... */ /* fill in the pad chars */ memset(Current, PadChar, size_v(Spaces)); // todo m17n Current += size_v(Spaces); /* step over the pad chars */ // todo m17n } Word = NextSite; /* copy the start pointer */ /* get the next word */ WordLength = StringUtil::nextWord(&Word, &Length, &NextSite); } /* copy the word over */ memcpy(Current, Word, WordLength); } return Retval; /* return spaced string */ }