optimize light selection
This commit is contained in:
parent
1a30887a7d
commit
7a58ba9733
6 changed files with 62 additions and 13 deletions
src/scene
|
@ -1,3 +1,4 @@
|
|||
use cgmath::AbsDiffEq;
|
||||
use cgmath::{InnerSpace, MetricSpace, Vector3};
|
||||
|
||||
use crate::vertex;
|
||||
|
@ -12,7 +13,7 @@ pub enum LightType {
|
|||
|
||||
pub trait Light {
|
||||
fn get_light_type(&self) -> LightType;
|
||||
fn weighted_distance(&self, center: Vector3<usize>) -> f32;
|
||||
fn weighted_distance(&self, pos: Vector3<usize>, size: Vector3<usize>) -> f32;
|
||||
}
|
||||
|
||||
pub trait LightSource: Light + Memorizable {}
|
||||
|
@ -57,8 +58,53 @@ impl Light for PointLight {
|
|||
LightType::POINT
|
||||
}
|
||||
|
||||
fn weighted_distance(&self, center: Vector3<usize>) -> f32 {
|
||||
let distance = self.pos.distance(vertex::Vec3{x: center.x as f32, y: center.y as f32, z: center.z as f32});
|
||||
fn weighted_distance(&self, pos: Vector3<usize>, size: Vector3<usize>) -> f32 {
|
||||
let low_end = vertex::Vec3{x: pos.x as f32, y: pos.y as f32, z: pos.z as f32};
|
||||
let high_end = vertex::Vec3{x: (pos.x + size.x) as f32, y: (pos.y + size.y) as f32, z: (pos.z + size.z) as f32};
|
||||
let distance;
|
||||
if low_end.x <= self.pos.x && self.pos.x <= high_end.x && low_end.y <= self.pos.y && self.pos.y <= high_end.y && low_end.z <= self.pos.z && self.pos.z <= high_end.z {
|
||||
let diff_low = self.pos - low_end;
|
||||
let diff_high = self.pos - high_end;
|
||||
distance = diff_low.x.abs().min(diff_low.y.abs().min(diff_low.z.abs().min(diff_high.x.abs().min(diff_high.y.abs().min(diff_high.z.abs())))));
|
||||
} else {
|
||||
let mut offset_vec = vertex::Vec3 {x: 0.0, y: 0.0, z: 0.0};
|
||||
|
||||
while !(low_end.x <= self.pos.x + offset_vec.x && self.pos.x + offset_vec.x <= high_end.x && low_end.y <= self.pos.y + offset_vec.y && self.pos.y + offset_vec.y <= high_end.y && low_end.z <= self.pos.z + offset_vec.z && self.pos.z + offset_vec.z <= high_end.z) {
|
||||
let diff_low = (self.pos + offset_vec) - low_end;
|
||||
let diff_high = (self.pos + offset_vec) - high_end;
|
||||
|
||||
let mut new_diff = vertex::Vec3 {x: 0.0, y: 0.0, z: 0.0};
|
||||
if diff_low.x.abs() < diff_high.x.abs() {
|
||||
new_diff.x += diff_low.x;
|
||||
} else {
|
||||
new_diff.x += diff_high.x;
|
||||
}
|
||||
|
||||
if diff_low.y.abs() < diff_high.y.abs() {
|
||||
new_diff.y += diff_low.y;
|
||||
} else {
|
||||
new_diff.y += diff_high.y;
|
||||
}
|
||||
|
||||
if diff_low.z.abs() < diff_high.z.abs() {
|
||||
new_diff.z += diff_low.z;
|
||||
} else {
|
||||
new_diff.z += diff_high.z;
|
||||
}
|
||||
|
||||
if ((new_diff.x < new_diff.y || new_diff.y == 0.0) && (new_diff.x < new_diff.z || new_diff.z == 0.0) && new_diff.x != 0.0) {
|
||||
offset_vec.x -= new_diff.x;
|
||||
} else {
|
||||
if (new_diff.y < new_diff.z || new_diff.z == 0.0) && new_diff.y != 0.0 {
|
||||
offset_vec.y -= new_diff.y;
|
||||
} else {
|
||||
offset_vec.z -= new_diff.z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
distance = offset_vec.magnitude();
|
||||
}
|
||||
let light_intensity = self.color.magnitude();
|
||||
|
||||
light_intensity / distance.powf(2.0)
|
||||
|
@ -106,7 +152,7 @@ impl Light for DirectionalLight {
|
|||
LightType::DIRECTION
|
||||
}
|
||||
|
||||
fn weighted_distance(&self, center: Vector3<usize>) -> f32 {
|
||||
fn weighted_distance(&self, pos: Vector3<usize>, size: Vector3<usize>) -> f32 {
|
||||
let light_intensity = self.color.magnitude();
|
||||
|
||||
light_intensity
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue