WString l2w(const String& lstr) { return l2w(lstr.c_str(), lstr.size()); #if 0 size_t len = lstr.size(); WString result; result.resize(len); size_t count = mbstowcs(&result[0], &lstr[0], len); AX_ASSERT(count <= len); result.resize(count); return result; #endif }
WString l2w(const char* localstr) { return l2w(localstr, strlen(localstr)); #if 0 size_t len = strlen(localstr); WString result; result.resize(len); size_t count = mbstowcs(&result[0], localstr, len); AX_ASSERT(count <= len); result.resize(count); return result; #endif }
// Generate local to world from face info (pos, normal, etc) Matrix3 plDistributor::IGenerateTransform(int iRepNode, int iFace, const Point3& pt, const Point3& bary) const { const float kMinVecLengthSq = 1.e-6f; Matrix3 l2w(true); // First, set the scale Point3 scale; switch( fScaleLock ) { case kLockX | kLockY: scale.x = fRand.RandRangeF(fScaleLo.x, fScaleHi.x); scale.y = scale.x; scale.z = fRand.RandRangeF(fScaleLo.z, fScaleHi.z); break; case kLockX | kLockY | kLockZ: scale.x = fRand.RandRangeF(fScaleLo.x, fScaleHi.x); scale.y = scale.z = scale.x; break; default: scale.x = fRand.RandRangeF(fScaleLo.x, fScaleHi.x); scale.y = fRand.RandRangeF(fScaleLo.y, fScaleHi.y); scale.z = fRand.RandRangeF(fScaleLo.z, fScaleHi.z); break; } l2w.Scale(scale); // Next up, get the rotation. // First we'll randomly rotate about local Z float azimRot = fRand.RandMinusOneToOne() * fAzimuthRange; Matrix3 azimMat; azimMat.SetRotateZ(azimRot); l2w = l2w * azimMat; // Now align with the surface. // Get the interpolated surface normal. Point3 surfNorm = IGetSurfaceNormal(iFace, bary); Matrix3 repNodeTM = fRepNodes[iRepNode]->GetNodeTM(TimeValue(0)); Point3 alignVec = repNodeTM.GetRow(2); alignVec = alignVec * fWorldToSurfVec; alignVec = FNormalize(alignVec); Point3 norm = surfNorm + (alignVec - surfNorm) * fAlignWgt; // The norm can come out of this zero length, if the surace normal // is directly opposite the "natural" up direction and the weight // is 50% (for example). In that case, this is just a bad place // to drop this replicant. if( norm.LengthSquared() < kMinVecLengthSq ) { l2w.IdentityMatrix(); return l2w; } norm = norm.Normalize(); // Randomize through the cone around that. Point3 rndNorm = norm; Point3 rndDir = IPerpAxis(norm); Point3 rndOut = rndDir ^ norm; rndDir *= fRand.RandMinusOneToOne(); float len = sqrt(1.f - rndDir.LengthSquared()); rndOut *= len; if( fRand.RandMinusOneToOne() < 0 ) rndOut *= -1.f; Point3 rndPol = rndDir + rndOut; float polScale = fRand.RandZeroToOne() * fTanPolarRange; // Combine using the bunching factor polScale = polScale * (1.f - fPolarBunch) + polScale * polScale * fPolarBunch; rndPol *= polScale; rndNorm += rndPol; norm = rndNorm.Normalize(); // Have "up" alignment, now just generate random dir vector perpindicular to up Point3 dir = repNodeTM.GetRow(1); dir = dir * fWorldToSurfVec; Point3 out = dir ^ norm; if( out.LengthSquared() < kMinVecLengthSq ) { if( fAzimuthRange < M_PI * 0.5f ) { l2w.IdentityMatrix(); return l2w; } else { dir = IPerpAxis(norm); out = dir ^ norm; } } out = FNormalize(out); dir = norm ^ out; // If our "up" direction points into the surface, return an "up" direction // tangent to the surface. Also, make the "dir" direction point out from // the surface. So if the alignVec/fAlignWgt turns the replicant around // to penetrate the surface, it just lies down instead. // // There's an early out here, for the case where the surface normal is // exactly opposed to the destination normal. This usually means the // surface normal is directly opposite the alignVec. In that // case, we just want to bag it. if( DotProd(norm, surfNorm) < 0 ) { dir = surfNorm; dir = dir.Normalize(); out = dir ^ norm; if( out.LengthSquared() < kMinVecLengthSq ) { l2w.IdentityMatrix(); return l2w; } out = out.Normalize(); norm = out ^ dir; } Matrix3 align; align.Set(out, dir, norm, Point3(0,0,0)); l2w = l2w * align; // Lastly, set the position. Point3 pos = pt; const float offset = fRand.RandRangeF(fOffsetMin, fOffsetMax); pos += norm * offset; l2w.Translate(pos); l2w = l2w * fSurfNode->GetObjectTM(TimeValue(0)); return l2w; }
hsMatrix44 plSpanInstance::getLocalToWorld() const { hsMatrix44 l2w; l2w(0, 0) = fL2W[0][0]; l2w(0, 1) = fL2W[0][1]; l2w(0, 2) = fL2W[0][2]; l2w(0, 3) = fL2W[0][3]; l2w(1, 0) = fL2W[1][0]; l2w(1, 1) = fL2W[1][1]; l2w(1, 2) = fL2W[1][2]; l2w(1, 3) = fL2W[1][3]; l2w(2, 0) = fL2W[2][0]; l2w(2, 1) = fL2W[2][1]; l2w(2, 2) = fL2W[2][2]; l2w(2, 3) = fL2W[2][3]; return l2w; }
String l2u(const String& lstr) { return w2u(l2w(lstr)); }
String l2u(const char* localstr) { WString ws = l2w(localstr); return w2u(ws); }