void Matrix4f::setRow( int i, const Vector4f& v ) { m_elements[ i ] = v.x(); m_elements[ i + 4 ] = v.y(); m_elements[ i + 8 ] = v.z(); m_elements[ i + 12 ] = v.w(); }
void Matrix4f::setCol( int j, const Vector4f& v ) { int colStart = 4 * j; m_elements[ colStart ] = v.x(); m_elements[ colStart + 1 ] = v.y(); m_elements[ colStart + 2 ] = v.z(); m_elements[ colStart + 3 ] = v.w(); }
// static QRgb QImageUtils::vector4fToQRgba( const Vector4f& v ) { int r = ColorUtils::floatToInt( v.x() ); int g = ColorUtils::floatToInt( v.y() ); int b = ColorUtils::floatToInt( v.z() ); int a = ColorUtils::floatToInt( v.w() ); return qRgba( r, g, b, a ); }
// for a given state, evaluate f(X,t) vector<Vector3f> PendulumSystem::evalF(vector<Vector3f> state) { vector<Vector3f> f; f.push_back(Vector3f(0,0,0)); f.push_back(Vector3f(0,0,0)); // YOUR CODE HERE for (unsigned i=2; i < state.size(); i+=2) { Vector3f position = state[i]; Vector3f velocity = state[i+1]; Vector3f force = Vector3f(); float mass = 1; float g = -.25; Vector3f gravity = Vector3f(0,mass*g,0); force += gravity; float drag = .1; Vector3f viscousDrag = -drag * velocity; force += viscousDrag; for (unsigned j=0; j < m_vSprings.size(); j++) { Vector4f spring = m_vSprings[j]; float springConstant = spring.z(); float restLength = spring.w(); if (spring.x() == i/2) { Vector3f dist = position - state[spring.y()*2]; force += -springConstant*(dist.abs() - restLength)*(dist.normalized()); } else if (spring.y() == i/2) { Vector3f dist = position - state[spring.x()*2]; force += -springConstant*(dist.abs() - restLength)*(dist.normalized()); } } f.push_back(velocity); f.push_back(force/mass); } return f; }
Vector3f Camera::unProject(const Vector2f& uv, float depth, const Matrix4f& invModelview) const { updateViewMatrix(); updateProjectionMatrix(); Vector3f a(2.*uv.x()/float(mVpWidth)-1., 2.*uv.y()/float(mVpHeight)-1., 1.); a.x() *= depth/mProjectionMatrix(0,0); a.y() *= depth/mProjectionMatrix(1,1); a.z() = -depth; // FIXME /\/| Vector4f b = invModelview * Vector4f(a.x(), a.y(), a.z(), 1.); return Vector3f(b.x(), b.y(), b.z()); }
void CameraSettings::spinModel( const float x, const float y, const float z ) { if( x == 0.f && y == 0.f && z == 0.f ) return; Matrix4f matInverse; cameraRotation_.inverse( matInverse ); Vector4f shift = matInverse * Vector4f( x, y, z, 1 ); modelRotation_.pre_rotate_x( shift.x( )); modelRotation_.pre_rotate_y( shift.y( )); modelRotation_.pre_rotate_z( shift.z( )); setDirty( DIRTY_ALL ); }
void Float4Widget::setValue(Vector4f v) { comboSlider1->blockSignals(true); comboSlider2->blockSignals(true); comboSlider3->blockSignals(true); comboSlider4->blockSignals(true); comboSlider1->setValue(v.x()); comboSlider2->setValue(v.y()); comboSlider3->setValue(v.z()); comboSlider3->setValue(v.w()); comboSlider1->blockSignals(false); comboSlider2->blockSignals(false); comboSlider3->blockSignals(false); comboSlider4->blockSignals(false); }
void DeferredDirectionalLighting::bind(const DirectionalLight& light, const Matrix4f& modelView) { _program.bind(); //tell the shader about uniforms GLint program = _program.getProgram(); Vector3f lightDir = light.getDirection(); //light in view space Vector4f lightDirection(lightDir.x(), lightDir.y(), lightDir.z(), 0); Vector4f lightDirectionView = (modelView) * lightDirection; lightDirectionView.normalize(); glUniform3f(glGetUniformLocation(program, "lightdir"), lightDirectionView.x(), lightDirectionView.y(), lightDirectionView.z()); }
Vector4f operator * ( const Vector4f& v, float f ) { return Vector4f( f * v.x(), f * v.y(), f * v.z(), f * v.w() ); }
Vector4f operator - ( const Vector4f& v ) { return Vector4f( -v.x(), -v.y(), -v.z(), -v.w() ); }
Vector4f operator / ( const Vector4f& v0, const Vector4f& v1 ) { return Vector4f( v0.x() / v1.x(), v0.y() / v1.y(), v0.z() / v1.z(), v0.w() / v1.w() ); }
// static float Vector4f::dot( const Vector4f& v0, const Vector4f& v1 ) { return v0.x() * v1.x() + v0.y() * v1.y() + v0.z() * v1.z() + v0.w() * v1.w(); }
//------------------------------------------------------------------------------ bool MaterialLoader::loadFromVariant(const sn::Variant & doc, sn::Material & mat) const { const AssetMetadata & meta = mat.getAssetMetadata(); // Shader ShaderProgram * shader = getAssetBySerializedLocation<ShaderProgram>(doc["shader"].getString(), meta.project, true); if (shader) mat.setShader(shader); // Depth bool depthTest = false; sn::unserialize(doc["depthTest"], depthTest); mat.setDepthTest(depthTest); // Blending BlendMode blendMode; sn::unserialize(doc["blend"], blendMode); mat.setBlendMode(blendMode); // Params const Variant::Dictionary params = doc["params"].getDictionary(); if (!params.empty()) { for (auto it = params.begin(); it != params.end(); ++it) { auto & v = it->second; // {"@type":"texture|rendertexture", "value":"foobar"} if (v.isDictionary()) { auto a = it->second.getDictionary(); auto typeTag = a["@type"]; auto valueTag = a["value"]; if (typeTag.isString() && valueTag.isString()) { std::string stype = typeTag.getString(); std::string loc = valueTag.getString(); if (stype == "texture") { Texture * tex = getAssetBySerializedLocation<Texture>(loc, meta.project, true); if (tex) mat.setTexture(it->first, tex); else SN_ERROR("Texture not found: " << loc); } else if (stype == "rendertexture") { RenderTexture * rt = getAssetBySerializedLocation<RenderTexture>(loc, meta.project, true); if (rt) mat.setRenderTexture(it->first, rt); else SN_ERROR("RenderTexture not found: " << loc); } else SN_ERROR("Unknown specified type: " << stype); } } else if (v.isArray()) { auto & a = it->second.getArray(); if (a.size() == 2) { Vector2f p; sn::unserialize(v, p); mat.setParam(it->first, p.x(), p.y()); } else if (a.size() == 3) { Vector3f p; sn::unserialize(v, p); mat.setParam(it->first, p.x(), p.y(), p.z()); } else if (a.size() == 4) { Vector4f p; sn::unserialize(v, p); mat.setParam(it->first, p.x(), p.y(), p.z(), p.w()); } // ... } else if (v.isFloat()) { mat.setParam(it->first, static_cast<f32>(v.getFloat())); } // TODO Handle other param types } } return mat.getShader() != nullptr; }
/// Initialize a uniform parameter with a 4D vector void setUniform(const std::string &name, const Vector4f &v, bool warn = true) { glUniform4f(uniform(name, warn), v.x(), v.y(), v.z(), v.w()); }
/** Draw a piecewise cubic curve with transformation and frustum clipping. Only * the part of the curve between startTime and endTime will be drawn. Additionally, * the curve is drawn with a fade effect. The curve is at full opacity at fadeStartTime * and completely transparent at fadeEndTime. fadeStartTime may be greater than * fadeEndTime--this just means that the fade direction will be reversed. * * @param modelview an affine transformation that will be applied to the curve * @param nearZ z coordinate of the near plane * @param farZ z coordinate of the far plane * @param viewFrustumPlaneNormals array of four normals (top, bottom, left, and right frustum planes) * @param subdivisionThreshold * @param startTime the beginning of the time interval * @param endTime the end of the time interval * @param fadeStartTime points on the curve before this time are drawn with full opacity * @param fadeEndTime points on the curve after this time are not drawn */ void CurvePlot::renderFaded(const Eigen::Affine3d& modelview, double nearZ, double farZ, const Eigen::Vector3d viewFrustumPlaneNormals[], double subdivisionThreshold, double startTime, double endTime, const Vector4f& color, double fadeStartTime, double fadeEndTime) const { // Flag to indicate whether we need to issue a glBegin() bool restartCurve = true; if (m_samples.empty() || endTime <= m_samples.front().t || startTime >= m_samples.back().t) return; // Linear search for the first sample unsigned int startSample = 0; while (startSample < m_samples.size() - 1 && startTime > m_samples[startSample].t) startSample++; // Start at the first sample with time <= startTime if (startSample > 0) startSample--; double fadeDuration = fadeEndTime - fadeStartTime; double fadeRate = 1.0 / fadeDuration; const Vector3d& p0_ = m_samples[startSample].position; const Vector3d& v0_ = m_samples[startSample].velocity; Vector4d p0 = modelview * Vector4d(p0_.x(), p0_.y(), p0_.z(), 1.0); Vector4d v0 = modelview * Vector4d(v0_.x(), v0_.y(), v0_.z(), 0.0); double opacity0 = (m_samples[startSample].t - fadeStartTime) * fadeRate; opacity0 = max(0.0, min(1.0, opacity0)); HighPrec_Frustum viewFrustum(nearZ, farZ, viewFrustumPlaneNormals); HighPrec_RenderContext rc(vbuf, viewFrustum, subdivisionThreshold); vbuf.createVertexBuffer(); vbuf.setup(); bool firstSegment = true; bool lastSegment = false; for (unsigned int i = startSample + 1; i < m_samples.size() && !lastSegment; i++) { // Transform the points into camera space. const Vector3d& p1_ = m_samples[i].position; const Vector3d& v1_ = m_samples[i].velocity; Vector4d p1 = modelview * Vector4d(p1_.x(), p1_.y(), p1_.z(), 1.0); Vector4d v1 = modelview * Vector4d(v1_.x(), v1_.y(), v1_.z(), 0.0); double opacity1 = (m_samples[i].t - fadeStartTime) * fadeRate; opacity1 = max(0.0, min(1.0, opacity1)); if (endTime <= m_samples[i].t) { lastSegment = true; } // O(t) is an approximating function for this segment of // the orbit, with 0 <= t <= 1 // C is the viewer position // d(t) = |O(t) - C|, the distance from viewer to the // orbit segment. double curveBoundingRadius = m_samples[i].boundingRadius; // Estimate the minimum possible distance from the // curve to the z=0 plane. If the curve is far enough // away to be approximated as a straight line, we'll just // render it. Otherwise, it should be a performance win // to do a sphere-frustum cull test before subdividing and // rendering segment. double minDistance = abs(p0.z()) - curveBoundingRadius; // Render close segments as splines with adaptive subdivision. The // subdivisions eliminates kinks between line segments and also // prevents clipping precision problems that occur when a // very long line is rendered with a relatively small view // volume. if (curveBoundingRadius >= subdivisionThreshold * minDistance || lastSegment || firstSegment) { // Skip rendering this section if it lies outside the view // frustum. if (viewFrustum.cullSphere(p0, curveBoundingRadius)) { if (!restartCurve) { vbuf.end(); restartCurve = true; } } else { double dt = m_samples[i].t - m_samples[i - 1].t; double t0 = 0.0; double t1 = 1.0; if (firstSegment) { t0 = (startTime - m_samples[i - 1].t) / dt; t0 = std::max(0.0, std::min(1.0, t0)); firstSegment = false; } if (lastSegment) { t1 = (endTime - m_samples[i - 1].t) / dt; } Matrix4d coeff = cubicHermiteCoefficients(p0, p1, v0 * dt, v1 * dt); restartCurve = rc.renderCubicFaded(restartCurve, coeff, t0, t1, color, (fadeStartTime - m_samples[i - 1].t) / dt, fadeRate * dt, curveBoundingRadius, 1); } } else { // Apparent size of curve is small enough that we can approximate // it as a line. // Simple cull test--just check the far plane. This is required because // apparent clipping precision limitations can cause a GPU to draw lines // that lie completely beyond the far plane. if (p0.z() + curveBoundingRadius < farZ) { if (!restartCurve) { vbuf.end(); restartCurve = true; } } else { if (restartCurve) { vbuf.begin(); vbuf.vertex(p0, Vector4f(color.x(), color.y(), color.z(), color.w() * float(opacity0))); restartCurve = false; } vbuf.vertex(p1, Vector4f(color.x(), color.y(), color.z(), color.w() * float(opacity1))); } } p0 = p1; v0 = v1; opacity0 = opacity1; } if (!restartCurve) { vbuf.end(); } vbuf.flush(); vbuf.finish(); }
bool operator == ( const Vector4f& v0, const Vector4f& v1 ) { return( v0.x() == v1.x() && v0.y() == v1.y() && v0.z() == v1.z() && v0.w() == v1.w() ); }
float Vector4f::dot(const Vector4f& other) const { return this->x() * other.x() + this->y() * other.y() + this->z() * other.z() + this->w() * other.w(); }
bool VisionRenderer::getRangeCameraData(Image& image, vector<Vector3f>& points) { unsigned char* colorBuf = 0; unsigned char* pixels = 0; const bool extractColors = (cameraForRendering->imageType() == Camera::COLOR_IMAGE); if(extractColors){ colorBuf = (unsigned char*)alloca(pixelWidth * pixelHeight * 3 * sizeof(unsigned char)); glReadPixels(0, 0, pixelWidth, pixelHeight, GL_RGB, GL_UNSIGNED_BYTE, colorBuf); if(rangeCameraForRendering->isOrganized()){ image.setSize(pixelWidth, pixelHeight, 3); } else { image.setSize(pixelWidth * pixelHeight, 1, 3); } pixels = image.pixels(); } float* depthBuf = (float*)alloca(pixelWidth * pixelHeight * sizeof(float)); glReadPixels(0, 0, pixelWidth, pixelHeight, GL_DEPTH_COMPONENT, GL_FLOAT, depthBuf); const Matrix4f Pinv = renderer.projectionMatrix().inverse().cast<float>(); const float fw = pixelWidth; const float fh = pixelHeight; Vector4f n; n[3] = 1.0f; points.clear(); points.reserve(pixelWidth * pixelHeight); unsigned char* colorSrc = 0; for(int y = pixelHeight - 1; y >= 0; --y){ int srcpos = y * pixelWidth; if(extractColors){ colorSrc = colorBuf + y * pixelWidth * 3; } for(int x=0; x < pixelWidth; ++x){ const float z = depthBuf[srcpos + x]; if(z > 0.0f && z < 1.0f){ n.x() = 2.0f * x / fw - 1.0f; n.y() = 2.0f * y / fh - 1.0f; n.z() = 2.0f * z - 1.0f; const Vector4f o = Pinv * n; const float& w = o[3]; points.push_back(Vector3f(o[0] / w, o[1] / w, o[2] / w)); if(pixels){ pixels[0] = colorSrc[0]; pixels[1] = colorSrc[1]; pixels[2] = colorSrc[2]; pixels += 3; } } else if(rangeCameraForRendering->isOrganized()){ if(z <= 0.0f){ points.push_back(Vector3f::Zero()); } else { points.push_back(Vector3f()); points.back() << (x - pixelWidth / 2) * numeric_limits<float>::infinity(), (y - pixelWidth / 2) * numeric_limits<float>::infinity(), -numeric_limits<float>::infinity(); } if(pixels){ pixels[0] = colorSrc[0]; pixels[1] = colorSrc[1]; pixels[2] = colorSrc[2]; pixels += 3; } } colorSrc += 3; } } if(extractColors && !rangeCameraForRendering->isOrganized()){ image.setSize((pixels - image.pixels()) / 3, 1, 3); } return true; }
// Return the GL restart status: true if the last segment of the // curve was culled and we need to start a new primitive sequence // with glBegin(). bool renderCubicFaded(bool restartCurve, const Matrix4d& coeff, double t0, double t1, const Vector4f& color, double fadeStart, double fadeRate, double curveBoundingRadius, int depth) const { const double dt = (t1 - t0) * InvSubdivisionFactor; double segmentBoundingRadius = curveBoundingRadius * InvSubdivisionFactor; #if DEBUG_ADAPTIVE_SPLINE { int c = depth % 10; glColor4f(SplineColors[c][0], SplineColors[c][1], SplineColors[c][2], 1.0f); ++SegmentCounts[depth]; } #endif Vector4d lastP = coeff * Vector4d(1.0, t0, t0 * t0, t0 * t0 * t0); double lastOpacity = (t0 - fadeStart) * fadeRate; lastOpacity = max(0.0, min(1.0, lastOpacity)); // clamp for (unsigned int i = 1; i <= SubdivisionFactor; i++) { double t = t0 + dt * i; Vector4d p = coeff * Vector4d(1.0, t, t * t, t * t * t); double opacity = (t - fadeStart) * fadeRate; opacity = max(0.0, min(1.0, opacity)); // clamp double minDistance = max(-m_viewFrustum.nearZ(), abs(p.z()) - segmentBoundingRadius); if (segmentBoundingRadius >= m_subdivisionThreshold * minDistance) { if (m_viewFrustum.cullSphere(p, segmentBoundingRadius)) { if (!restartCurve) { m_vbuf.end(); restartCurve = true; } } else { restartCurve = renderCubicFaded(restartCurve, coeff, t - dt, t, color, fadeStart, fadeRate, segmentBoundingRadius, depth + 1); } } else { #if DEBUG_ADAPTIVE_SPLINE { int c = depth % 10; glColor4f(SplineColors[c][0], SplineColors[c][1], SplineColors[c][2], i % 2 ? 0.25f : 1.0f); } #endif if (restartCurve) { m_vbuf.begin(); m_vbuf.vertex(lastP, Vector4f(color.x(), color.y(), color.z(), color.w() * float(lastOpacity))); restartCurve = false; } m_vbuf.vertex(p, Vector4f(color.x(), color.y(), color.z(), color.w() * float(opacity))); } lastP = p; lastOpacity = opacity; } return restartCurve; }