bool CollisionVolume::testCollision(const VC3 &objectPosition, const VC3 &angles, CollisionData &collisionData, float epsilon) { QUAT rotation = getRotation(angles); //rotation.MakeFromAngles(0, -yRotation, 0); Matrix tm; tm.CreateRotationMatrix(rotation); // Everything's relative etc VC3 rayOrigin = tm.GetTransformedVector(collisionData.rayOrigin - objectPosition) + objectPosition; VC3 rayDirection = tm.GetWithoutTranslation().GetTransformedVector(collisionData.rayDirection); if(!data->possibleCollision(objectPosition, collisionData)) return false; if(!data->accurateCollision(objectPosition, collisionData, rayOrigin, rayDirection)) return false; float collisionDistance = objectPosition.GetRangeTo(collisionData.rayOrigin); VC3 pos = tm.GetInverse().GetTransformedVector(collisionData.collisionPosition - objectPosition) + objectPosition; if(collisionData.hasCollision) if(collisionDistance > pos.GetRangeTo(collisionData.rayOrigin)) return false; collisionData.rayLength = collisionDistance; collisionData.hasCollision = true; collisionData.collisionPosition = objectPosition; collisionData.objectData = data->data; return true; }
bool SphereCollision(const VC3 &pos, float radius, Storm3D_CollisionInfo &info, bool accurate) { if(pos.GetRangeTo(position) < radius + getRadius()) { info.hit = true; return true; } return false; }
float getAmount(const VC3 &pos, float angle, const IStorm3D_Terrain &terrain, float rayHeight) const { float fovRadians = fov * (3.1415927f / 180.f); int index = int(RAY_AMOUNT * (angle + fovRadians) / (2.f * fovRadians)); assert(index >= 0 && index < RAY_AMOUNT); float distance = pos.GetRangeTo(position); if(!lengthOk[index]) { float rayAngle = -fovRadians + float(index) * ((2 * fovRadians) / (RAY_AMOUNT - 1)); VC3 rayDir = direction; float x = rayDir.x; float z = rayDir.z; rayDir.x = x * cosf(rayAngle) + z * sinf(rayAngle); rayDir.y = 0; rayDir.z = -x * sinf(rayAngle) + z * cosf(rayAngle); rayDir.Normalize(); Storm3D_CollisionInfo cInfo; ObstacleCollisionInfo oInfo; terrain.rayTrace(position + VC3(0,rayHeight,0) + (rayDir * .5f), rayDir, range, cInfo, oInfo, true, true); if(oInfo.hit && oInfo.hitAmount > 0) length[index] = oInfo.ranges[0]; else if(cInfo.hit) length[index] = cInfo.range; else length[index] = range; lengthOk[index] = true; } if(distance > length[index]) return 0; return 1.f - distance / range; }
//! Render projection void Storm3D_FakeSpotlight::renderProjection() { if(BUFFER_WIDTH <= 0 || BUFFER_HEIGHT <= 0) return; if(!data->renderTarget) return; VC3 position = data->properties.position; position.y -= data->plane.height; const VC2 &min = data->plane.min; const VC2 &max = data->plane.max; float range = data->properties.range * sqrtf(2.f); VC3 a = position; a.x += min.x; a.z += min.y; float ad = a.GetRangeTo(position) / range; VC3 b = position; b.x += min.x; b.z += max.y; float bd = b.GetRangeTo(position) / range; VC3 c = position; c.x += max.x; c.z += min.y; float cd = c.GetRangeTo(position) / range; VC3 d = position; d.x += max.x; d.z += max.y; float dd = d.GetRangeTo(position) / range; VC3 e = position; float ed = 0.f; ad = bd = cd = dd = 1.f; float buffer[] = { a.x, a.y, a.z, ad, ad, ad, 1.0f, b.x, b.y, b.z, bd, bd, bd, 1.0f, c.x, c.y, c.z, cd, cd, cd, 1.0f, d.x, d.y, d.z, dd, dd, dd, 1.0f, e.x, e.y, e.z, ed, ed, ed, 1.0f }; memcpy(data->vertexBuffer.lock(), buffer, 5 * 7 * sizeof(float)); data->vertexBuffer.unlock(); data->vertexBuffer.apply(0); Storm3D_ShaderManager *manager = Storm3D_ShaderManager::GetSingleton(); manager->setTextureTm(data->properties.shaderProjection[0]); manager->setSpot(COL(), data->properties.position, data->properties.direction, data->properties.range, .1f); D3DXMATRIX identity; D3DXMatrixIdentity(identity); manager->setSpotTarget(data->properties.targetProjection); manager->SetWorldTransform(identity); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 1.0f/255.0f); { //float factor = data->fadeFactor + data->fogFactor * (1.f - data->fadeFactor); //float factor = data->fadeFactor * data->fogFactor; //float factor = data->fadeFactor; float factor = (1.f - data->fadeFactor) + data->fogFactor * (data->fadeFactor); float c0[4] = { factor, factor, factor, 1.f }; glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0, c0); float fogFactor = data->fogFactor; float c2[4] = { fogFactor, fogFactor, fogFactor, 1.f }; glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 2, c2); } { float xd = 1.f / float(data->renderTarget->color->getWidth()); float yd = 1.f / float(data->renderTarget->color->getHeight()); float xd1 = xd * 1.5f; float yd1 = yd * 1.5f; float xd2 = xd * 2.5f; float yd2 = yd * 2.5f; /* float xd = 1.f / float(sourceDesc.Width); float yd = 1.f / float(sourceDesc.Height); float xd1 = xd * 0.5f; float yd1 = yd * 0.5f; float xd2 = xd * 1.5f; float yd2 = yd * 1.5f; */ float deltas1[4] = { -xd2, -yd2, 0, 0 }; float deltas2[4] = { -xd1, yd2, 0, 0 }; float deltas3[4] = { xd1, -yd1, 0, 0 }; float deltas4[4] = { xd2, yd1, 0, 0 }; glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, 5, deltas1); glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, 6, deltas2); glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, 7, deltas3); glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, 8, deltas4); } data->shadowVertexShader->apply(); // fake_shadow_plane_vertex_shader.txt data->indexBuffer->render(4, 5); }