void Cylinder::generatePosition(Particle& particle,bool full) const { float cRadius = full ? random(0.0f,radius) : radius, cLength = full ? random(0.0f,length)-length*0.5f : length, cAngle = random(0.0f,3.15f * 2); // 3.15 > PI, but it has no importance here... // ofxSPK Changed: Why it was not TWO_PI??? // We need at least two points to compute a base Vector3D rPoint = getTransformedPosition() + Vector3D(10.0f,10.0f,10.0f); float dist = dotProduct(tDirection,rPoint); while(dist == 0.0f || tDirection*dist +getTransformedPosition() == rPoint) { // avoid dist == 0, which leads to a div by zero. rPoint += Vector3D(10.0f,10.0f,random(-10.0f,10.0f)); dist = dotProduct(tDirection,rPoint); } Vector3D p1 = tDirection*dist +getTransformedPosition(); dist = getDist(p1,rPoint); Vector3D a = (rPoint - p1) / dist; Vector3D tmp1 = tDirection, tmp2 = a; tmp2.crossProduct(tmp1*(-1)); Vector3D b = tmp2; particle.position() = getTransformedPosition() + cLength * tDirection + a * cRadius * std::cos(cAngle) + b * cRadius * std::sin(cAngle); }
bool Plane::intersects(const Vector3D& v0,const Vector3D& v1,float radius,Vector3D* normal) const { float dist0 = dotProduct(tNormal,v0 - getTransformedPosition()); if (std::abs(dist0) < radius) return false; // the particle is already intersecting the plane, the intersection is ignored float dist1 = dotProduct(tNormal,v1 - getTransformedPosition()); if (std::abs(dist1) < radius) { if (normal != NULL) *normal = (dist0 < 0.0f ? -tNormal : tNormal); return true; } if (dist1 > 0.0f) dist1 -= radius; else dist1 += radius; if ((dist0 < 0.0f) == (dist1 < 0.0f)) // both particles are on the same side return false; if (normal != NULL) *normal = (dist0 < 0.0f ? -tNormal : tNormal); return true; }
bool Plane::intersects(const Vector3D& v0,const Vector3D& v1,Vector3D* intersection,Vector3D* normal) const { float dist0 = dotProduct(tNormal,v0 - getTransformedPosition()); float dist1 = dotProduct(tNormal,v1 - getTransformedPosition()); if ((dist0 <= 0.0f) == (dist1 <= 0.0f)) // both points are on the same side return false; if (intersection != NULL) { if (dist0 <= 0.0f) dist0 = -dist0; else dist1 = -dist1; if (normal != NULL) *normal = tNormal; float ti = dist0 / (dist0 + dist1); Vector3D vDir = v1 - v0; float norm = vDir.getNorm(); norm *= ti; ti = norm < APPROXIMATION_VALUE ? 0.0f : ti * (norm - APPROXIMATION_VALUE) / norm; vDir *= ti; *intersection = v0 + vDir; } return true; }
void Cylinder::moveAtBorder(Vector3D& v,bool inside) const { float approx = inside ? -APPROXIMATION_VALUE : APPROXIMATION_VALUE; float dist = dotProduct(tDirection,v - getTransformedPosition()); Vector3D ext = v - (tDirection*dist + getTransformedPosition()); float r = ext.getNorm(); ext = ext / r; if(dist > length*0.5f) { v -= tDirection * (dist - length*0.5f - approx); if(r > radius) v -= ext*(r-radius-approx); return; } else if(dist < -length * 0.5f) { v += tDirection * (length*0.5f - dist - approx); if(r > radius) v -= ext*(r-radius-approx); return; } if(r > radius) v -= ext*(r-radius-approx); else v += ext*(radius-r+approx); }
bool Cylinder::contains(const Vector3D& v) const { float dist = dotProduct(tDirection,v - getTransformedPosition()); Vector3D ext = v - (tDirection*dist + getTransformedPosition()); float r = ext.getNorm(); return dist <= length*0.5f && dist >= -length*0.5f && r <= radius; }
Vector3D Cylinder::computeNormal(const Vector3D& point) const { float dist = dotProduct(tDirection,point - getTransformedPosition()); if(dist >= length*0.5f) return tDirection; if(dist <= -length*0.5f) return -tDirection; Vector3D ext = point - (tDirection*dist + getTransformedPosition()); float r = ext.getNorm(); ext = ext / r; return ext; }
void Sphere::moveAtBorder(Vector3D& v,bool inside) const { Vector3D vDir = v - getTransformedPosition(); float norm = vDir.getNorm(); if (inside) vDir *= (radius + APPROXIMATION_VALUE) / norm; else vDir *= (radius - APPROXIMATION_VALUE) / norm; v = getTransformedPosition() + vDir; }
vec3 Point::computeNormal(const vec3& point) const { vec3 normal(point - getTransformedPosition()); normalizeOrRandomize(normal); return normal; }
bool Sphere::intersects(const Vector3D& v0,const Vector3D& v1,Vector3D* intersection,Vector3D* normal) const { float r2 = radius * radius; float dist0 = getSqrDist(getTransformedPosition(),v0); float dist1 = getSqrDist(getTransformedPosition(),v1); if ((dist0 <= r2) == (dist1 <= r2)) return false; if (intersection != NULL) { Vector3D vDir = v1 - v0; float norm = vDir.getNorm(); float d = dotProduct(vDir,getTransformedPosition() - v0) / norm; float a = std::sqrt(r2 - dist0 + d * d); float ti; if (dist0 <= r2) ti = d - a; else ti = d + a; ti /= norm; if (ti < 0.0f) ti = 0.0f; if (ti > 1.0f) ti = 1.0f; norm *= ti; ti = norm < APPROXIMATION_VALUE ? 0.0f : ti * (norm - APPROXIMATION_VALUE) / norm; vDir *= ti; *intersection = v0 + vDir; if (normal != NULL) { if (dist0 <= r2) *normal = getTransformedPosition() - *intersection; else *normal = *intersection - getTransformedPosition(); normal->normalize(); } } return true; }
void MOCamera::updateListener(void) { MSoundContext * soundContext = MEngine::getInstance()->getSoundContext(); MVector3 position = getTransformedPosition(); MVector3 direction = getRotatedVector(MVector3(0, 0, -1)); MVector3 up = getRotatedVector(MVector3(0, 1, 0)); soundContext->updateListenerPosition(position, direction, up); }
void Sphere::generatePosition(Particle& particle,bool full) const { do particle.position() = Vector3D(random(-radius,radius),random(-radius,radius),random(-radius,radius)); while (particle.position().getSqrNorm() > radius * radius); if ((!full)&&(radius > 0.0f)) particle.position() *= radius / particle.position().getNorm(); particle.position() += getTransformedPosition(); }
void Plane::moveAtBorder(Vector3D& v,bool inside) const { float dist = dotProduct(tNormal,v - getTransformedPosition()); if ((dist <= 0.0f) == inside) inside ? dist += APPROXIMATION_VALUE : dist -= APPROXIMATION_VALUE; else inside ? dist -= APPROXIMATION_VALUE : dist += APPROXIMATION_VALUE; v += tNormal * -dist; }
bool AABox::intersects(const Vector3D& v0,const Vector3D& v1,Vector3D* intersection,Vector3D* normal) const { float tEnter = 0.0f; float tExit = 1.0f; int axis; if (!slabIntersects(v0.x,v1.x,getTransformedPosition().x - dimension.x * 0.5f,getTransformedPosition().x + dimension.x * 0.5f,tEnter,tExit,axis,0)) return false; if (!slabIntersects(v0.y,v1.y,getTransformedPosition().y - dimension.y * 0.5f,getTransformedPosition().y + dimension.y * 0.5f,tEnter,tExit,axis,1)) return false; if (!slabIntersects(v0.z,v1.z,getTransformedPosition().z - dimension.z * 0.5f,getTransformedPosition().z + dimension.z * 0.5f,tEnter,tExit,axis,2)) return false; if ((tEnter <= 0.0f)&&(tExit >= 1.0f)) return false; if (intersection != NULL) { if (tEnter <= 0.0f) { tEnter = tExit; axis = (axis & 0xF0) >> 4; } else
void AABox::generatePosition(Particle& particle,bool full) const { particle.position().x = getTransformedPosition().x + random(-dimension.x * 0.5f,dimension.x * 0.5f); particle.position().y = getTransformedPosition().y + random(-dimension.y * 0.5f,dimension.y * 0.5f); particle.position().z = getTransformedPosition().z + random(-dimension.z * 0.5f,dimension.z * 0.5f); if (!full) { int axis = random(0,3); int sens = (random(0,2) << 1) - 1; switch(axis) { case 0 : particle.position().x = getTransformedPosition().x + sens * dimension.x * 0.5f; break; case 1 : particle.position().y = getTransformedPosition().y + sens * dimension.y * 0.5f; break; default : particle.position().z = getTransformedPosition().z + sens * dimension.z * 0.5f; break; } } }
void MOLight::updateVisibility(MOCamera * camera) { MFrustum * frustum = camera->getFrustum(); // TODO: use different test for spot and directional MVector3 min = getTransformedPosition() - m_radius; MVector3 max = getTransformedPosition() + m_radius; MVector3 points[8] = { MVector3(min.x, min.y, min.z), MVector3(min.x, max.y, min.z), MVector3(max.x, max.y, min.z), MVector3(max.x, min.y, min.z), MVector3(min.x, min.y, max.z), MVector3(min.x, max.y, max.z), MVector3(max.x, max.y, max.z), MVector3(max.x, min.y, max.z) }; // is box in frustum setVisible(frustum->isVolumePointsVisible(points, 8)); }
bool Cylinder::intersects(const Vector3D& v0,const Vector3D& v1,Vector3D* intersection,Vector3D* normal) const { if(!intersection) return false; // mindist between line directed by tDir and line(v0 v1). Vector3D u = v1 - v0; u.normalize(); if(tDirection == u || tDirection == -u) // colinear { float dist = dotProduct(tDirection,v0 - getTransformedPosition()); Vector3D ext = v0 - (tDirection*dist + getTransformedPosition()); float r = ext.getNorm(); ext = ext / r; if(r == radius) //intersection { *intersection = getTransformedPosition() + ext * radius; if(normal) *normal = computeNormal(*intersection); return true; } else if(r < radius) { *intersection = getTransformedPosition() + tDirection * length*0.5f + ext * r; if(normal) *normal = computeNormal(*intersection); return true; } return false; } else { Vector3D pp = getTransformedPosition() - v0, uv = u; uv.crossProduct(tDirection); float dist = std::abs(dotProduct(pp,uv))/uv.getNorm(); float d = dotProduct(tDirection,v0 - getTransformedPosition()); Vector3D ext = v0 - (tDirection*d + getTransformedPosition()); float r = ext.getNorm(); float ah = std::cos(std::asin(dist/r))*r; Vector3D h = v0 + u*ah; if(contains(h)) // intersection { float offset = 3.1415926535897932384626433832795f*0.5f*dist/radius; *intersection = h - offset * u; if(normal) *normal = computeNormal(*intersection); return true; } return false; } }
bool AABox::contains(const Vector3D& v) const { if ((v.x >= getTransformedPosition().x - dimension.x * 0.5f)&&(v.x <= getTransformedPosition().x + dimension.x * 0.5f) &&(v.y >= getTransformedPosition().y - dimension.y * 0.5f)&&(v.y <= getTransformedPosition().y + dimension.y * 0.5f) &&(v.z >= getTransformedPosition().z - dimension.z * 0.5f)&&(v.z <= getTransformedPosition().z + dimension.z * 0.5f)) return true; return false; }
MVector3 MOCamera::getUnProjectedPoint(const MVector3 & point) const { MVector4 nPoint; nPoint.x = (2 * ((point.x - m_currentViewport[0]) / ((float)m_currentViewport[2]))) - 1; nPoint.y = (2 * ((point.y - m_currentViewport[1]) / ((float)m_currentViewport[3]))) - 1; nPoint.z = (2 * point.z) - 1; nPoint.w = 1; MMatrix4x4 matrix = (m_currentProjMatrix * m_currentViewMatrix).getInverse(); MVector4 v = matrix * nPoint; if(v.w == 0) return getTransformedPosition(); float iw = 1.0f / v.w; return MVector3(v.x, v.y, v.z)*iw; }
bool Sphere::contains(const Vector3D& v) const { return getSqrDist(getTransformedPosition(),v) <= radius * radius; }
Vector3D Sphere::computeNormal(const Vector3D& point) const { Vector3D normal(point - getTransformedPosition()); normalizeOrRandomize(normal); return normal; }