Everything is now working except for noise height mapping.
This commit is contained in:
parent
f596260f1b
commit
16e397b8bf
2 changed files with 14578 additions and 19 deletions
14440
data/noice.obj
Normal file
14440
data/noice.obj
Normal file
File diff suppressed because it is too large
Load diff
157
src/main.rs
157
src/main.rs
|
@ -7,12 +7,17 @@ extern crate cgmath;
|
||||||
|
|
||||||
use std::io::Result;
|
use std::io::Result;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use obj::{Obj, SimplePolygon};
|
use std::f32::consts::PI;
|
||||||
use std::f64::consts::PI;
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
use obj::{Obj, SimplePolygon, IndexTuple};
|
||||||
use noise::Fbm;
|
use noise::Fbm;
|
||||||
use noise::Seedable;
|
use noise::Seedable;
|
||||||
use noise::MultiFractal;
|
use noise::MultiFractal;
|
||||||
use noise::NoiseModule;
|
use noise::NoiseModule;
|
||||||
|
use cgmath::Vector3;
|
||||||
|
use cgmath::ElementWise;
|
||||||
|
use cgmath::Array;
|
||||||
|
|
||||||
// A function called test that takes in 1 32-bit integer
|
// A function called test that takes in 1 32-bit integer
|
||||||
// and returns a 32-bit integer.
|
// and returns a 32-bit integer.
|
||||||
|
@ -62,22 +67,19 @@ fn find_l_w(obj: &Obj<SimplePolygon>) -> (f32, f32) {
|
||||||
if let Some(first) = obj.position.first() {
|
if let Some(first) = obj.position.first() {
|
||||||
let initial = (first[0], first[1], first[0], first[1]);
|
let initial = (first[0], first[1], first[0], first[1]);
|
||||||
|
|
||||||
let min_maxes = obj.position.iter().fold(initial, |acc, point| {
|
let min_maxes = obj.position.iter().fold(initial, |mut acc, point| {
|
||||||
let acc = if acc.0 > point[0] {
|
if acc.0 > point[0] {
|
||||||
(point[0], acc.1, acc.2, acc.3)
|
acc.0 = point[0];
|
||||||
} else if acc.2 < point[0] {
|
} else if acc.2 < point[0] {
|
||||||
(acc.0, acc.1, point[0], acc.3)
|
acc.2 = point[0];
|
||||||
} else {
|
}
|
||||||
acc
|
|
||||||
};
|
|
||||||
|
|
||||||
if acc.1 > point[1] {
|
if acc.1 > point[1] {
|
||||||
(acc.0, point[1], acc.2, acc.3)
|
acc.1 = point[1];
|
||||||
} else if acc.3 < point[1] {
|
} else if acc.3 < point[1] {
|
||||||
(acc.0, acc.1, acc.2, point[1])
|
acc.3 = point[1];
|
||||||
} else {
|
|
||||||
acc
|
|
||||||
}
|
}
|
||||||
|
acc
|
||||||
});
|
});
|
||||||
|
|
||||||
(min_maxes.2 - min_maxes.0, min_maxes.3 - min_maxes.1)
|
(min_maxes.2 - min_maxes.0, min_maxes.3 - min_maxes.1)
|
||||||
|
@ -93,27 +95,144 @@ fn find_l_w(obj: &Obj<SimplePolygon>) -> (f32, f32) {
|
||||||
* to the initial input obj's position.
|
* to the initial input obj's position.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fn calculate_angle(count: i32, current_layer: i32) -> f64 {
|
fn calculate_angle(current_duplicate: i32, current_layer: i32) -> f32 {
|
||||||
((count as f64) / (2.0 * (current_layer as f64))) * (0.5 * PI)
|
(current_duplicate / (2 * current_layer)) as f32 * (0.5 * PI)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calculate_translation(current_layer: i32, length: f32, width: f32, angle: f32) -> Vector3<f32> {
|
||||||
|
Vector3::new(length * angle.cos(), width * angle.sin(), 0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn duplicate(
|
||||||
|
positions: Vec<Vector3<f32>>,
|
||||||
|
translation: Vector3<f32>,
|
||||||
|
height_vec: Vector3<f32>,
|
||||||
|
) -> Vec<Vector3<f32>> {
|
||||||
|
positions
|
||||||
|
.iter()
|
||||||
|
.map(|point| {
|
||||||
|
//height_vec.mul_element_wise(point.clone()) + translation
|
||||||
|
point.clone() + translation
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_city(
|
fn generate_city(
|
||||||
positions: Vec<[f32; 3]>,
|
positions: Vec<Vector3<f32>>,
|
||||||
layers: i32,
|
layers: i32,
|
||||||
spacing: f32,
|
spacing: f32,
|
||||||
length: f32,
|
length: f32,
|
||||||
width: f32,
|
width: f32,
|
||||||
) -> Vec<[f32; 3]> {
|
) -> Vec<Vector3<f32>> {
|
||||||
positions
|
let length = length + spacing;
|
||||||
|
let width = width + spacing;
|
||||||
|
|
||||||
|
let mut temp = Vector3::new(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
//let mut coord = Vector3::new(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
(1..layers).fold(positions.clone(), |acc_positions, current_layer| {
|
||||||
|
temp.x = -length * (current_layer as f32);
|
||||||
|
temp.y = -width * (current_layer as f32);
|
||||||
|
|
||||||
|
(0..(current_layer * 8)).fold(acc_positions, |mut acc_positions, current_duplicate| {
|
||||||
|
|
||||||
|
let angle = calculate_angle(current_duplicate, current_layer);
|
||||||
|
|
||||||
|
let translation = calculate_translation(current_layer, length, width, angle);
|
||||||
|
temp += translation;
|
||||||
|
|
||||||
|
let height_vec = Vector3::new(1.0, 1.0, 1.0);
|
||||||
|
|
||||||
|
let x = Vector3::new(1.0, 1.0, 1.0);
|
||||||
|
|
||||||
|
acc_positions.extend(duplicate(positions.clone(), temp, height_vec));
|
||||||
|
|
||||||
|
acc_positions
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn copy_faces(
|
||||||
|
faces: Vec<Vec<IndexTuple>>,
|
||||||
|
n_positions: usize,
|
||||||
|
layers: usize,
|
||||||
|
) -> Vec<Vec<IndexTuple>> {
|
||||||
|
(0..(2 * layers - 1).pow(2)).fold(Vec::new(), |mut acc_faces, current_value| {
|
||||||
|
let offset = n_positions * current_value + 1;
|
||||||
|
|
||||||
|
acc_faces.extend(faces.iter().map(|current_face| {
|
||||||
|
current_face
|
||||||
|
.iter()
|
||||||
|
.map(|index_tuple| {
|
||||||
|
IndexTuple(
|
||||||
|
index_tuple.0 + offset,
|
||||||
|
index_tuple.1.map(|i| i + offset),
|
||||||
|
index_tuple.2.map(|j| j + offset),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}));
|
||||||
|
|
||||||
|
acc_faces
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn save(filename: &Path, positions: Vec<Vector3<f32>>, faces: Vec<Vec<IndexTuple>>) {
|
||||||
|
let mut file = File::create(filename).unwrap();
|
||||||
|
|
||||||
|
for pos in positions {
|
||||||
|
write!(file, "v {} {} {}\n", pos[0], pos[1], pos[2]).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
for face in faces {
|
||||||
|
write!(file, "f");
|
||||||
|
for value in face {
|
||||||
|
write!(file, " {}/", value.0).unwrap();
|
||||||
|
if let Some(i) = value.1 {
|
||||||
|
write!(file, "{}", i).unwrap();
|
||||||
|
}
|
||||||
|
write!(file, "/").unwrap();
|
||||||
|
if let Some(j) = value.2 {
|
||||||
|
write!(file, "{}", j).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
write!(file, "\n").unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
||||||
let path = Path::new("data/teapot.obj");
|
let path = Path::new("data/test.obj");
|
||||||
let maybe_obj: Result<Obj<SimplePolygon>> = Obj::load(&path);
|
let maybe_obj: Result<Obj<SimplePolygon>> = Obj::load(&path);
|
||||||
|
|
||||||
if let Ok(obj) = maybe_obj {
|
if let Ok(obj) = maybe_obj {
|
||||||
println!("Position: {:?}", obj.position);
|
println!("Position: {:?}", obj.position);
|
||||||
|
|
||||||
|
let layers = 10;
|
||||||
|
let spacing = 1.0;
|
||||||
|
|
||||||
|
let (length, width) = find_l_w(&obj);
|
||||||
|
|
||||||
|
println!("Length: {} Width: {}", length, width);
|
||||||
|
|
||||||
|
let input_positions = obj.position
|
||||||
|
.iter()
|
||||||
|
.map(|point| Vector3::new(point[0], point[1], point[2]))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let output_positions = generate_city(input_positions, layers, spacing, length, width);
|
||||||
|
|
||||||
|
println!("Objects: {:?}", obj.objects[0].groups[0].polys[0]);
|
||||||
|
|
||||||
|
// I have two faces, blurry's the one I'm not.
|
||||||
|
let output_faces = copy_faces(
|
||||||
|
obj.objects[0].groups[0].polys.clone(),
|
||||||
|
obj.position.len(),
|
||||||
|
layers as usize,
|
||||||
|
);
|
||||||
|
|
||||||
|
save(Path::new("data/noice.obj"), output_positions, output_faces);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
else if Err(error) = maybe_obj {
|
else if Err(error) = maybe_obj {
|
||||||
|
|
Reference in a new issue