|
| 1 | +#!/usr/bin/env jruby |
| 2 | + |
| 3 | +require 'propane' |
| 4 | +require 'arcball' |
| 5 | +# PixelFlow | Copyright (C) 2016 Thomas Diewald - http://thomasdiewald.com |
| 6 | +# |
| 7 | +# A Processing/Java library for high performance GPU-Computing (GLSL). |
| 8 | +# MIT License: https://opensource.org/licenses/MIT |
| 9 | +# |
| 10 | +class PoissonSampling3D < Propane::App |
| 11 | + load_library :pixel_flow, :peasycam |
| 12 | + |
| 13 | + module Poisson |
| 14 | + java_import 'com.thomasdiewald.pixelflow.java.geometry.DwCube' |
| 15 | + java_import 'com.thomasdiewald.pixelflow.java.geometry.DwIcosahedron' |
| 16 | + java_import 'com.thomasdiewald.pixelflow.java.geometry.DwIndexedFaceSetAble' |
| 17 | + java_import 'com.thomasdiewald.pixelflow.java.geometry.DwMeshUtils' |
| 18 | + java_import 'com.thomasdiewald.pixelflow.java.sampling.PoissonDiscSamping3D' |
| 19 | + java_import 'com.thomasdiewald.pixelflow.java.sampling.PoissonSample' |
| 20 | + java_import 'peasy.PeasyCam' |
| 21 | + java_import 'processing.core.PShape' |
| 22 | + end |
| 23 | + |
| 24 | + include Poisson |
| 25 | + |
| 26 | + attr_reader :cam, :shp_samples_spheres, :shp_samples_points, :shp_gizmo |
| 27 | + attr_reader :display_radius, :generate_spheres, :ifs, :verts_per_face, :samples |
| 28 | + |
| 29 | + def settings |
| 30 | + size(1280, 720, P3D) |
| 31 | + smooth(8) |
| 32 | + end |
| 33 | + |
| 34 | + def setup |
| 35 | + sketch_title 'Sampling Poisson 3D' |
| 36 | + @cam = PeasyCam.new(self, 0, 0, 0, 1000) |
| 37 | + @display_radius = true |
| 38 | + @generate_spheres = true |
| 39 | + @ifs = nil |
| 40 | + @shp_gizmo = nil |
| 41 | + @verts_per_face = 0 |
| 42 | + generate_poisson_sampling |
| 43 | + frame_rate(1_000) |
| 44 | + end |
| 45 | + |
| 46 | + def generate_poisson_sampling |
| 47 | + # create an anonymous class instance in JRuby that implements the java |
| 48 | + # abstract class PoissonDiscSamping3D |
| 49 | + pds = Class.new(PoissonDiscSamping3D) do |
| 50 | + # java_signature 'PoissonSample newInstance(float, float, float, float, float)' |
| 51 | + def newInstance(x, y, z, r, rcollision) |
| 52 | + PoissonSample.new(x, y, z, r, rcollision) |
| 53 | + end |
| 54 | + end.new |
| 55 | + bounds = [-200, -200, 0, 200, 200, 400] |
| 56 | + rmin = 10 |
| 57 | + rmax = 50 |
| 58 | + roff = 1 |
| 59 | + new_points = 50 |
| 60 | + start = Time.now |
| 61 | + pds.generatePoissonSampling(bounds, rmin, rmax, roff, new_points) |
| 62 | + @shp_samples_spheres = create_shape(GROUP) |
| 63 | + @shp_samples_points = create_shape(GROUP) |
| 64 | + @samples = pds.samples |
| 65 | + samples.each do |sample| |
| 66 | + add_shape(sample) |
| 67 | + end |
| 68 | + time = Time.now - start |
| 69 | + start = Time.now |
| 70 | + puts("poisson samples 3D generated") |
| 71 | + puts(" time: #{(time * 1_000).floor}ms") |
| 72 | + puts(" count: #{pds.samples.size}") |
| 73 | + |
| 74 | + time = Time.now - start |
| 75 | + puts("PShapes created") |
| 76 | + puts(" time: #{(time * 1_000).floor}ms") |
| 77 | + puts(" count: #{samples.size}") |
| 78 | + end |
| 79 | + |
| 80 | + def draw |
| 81 | + lights |
| 82 | + point_light(128, 96, 64, -500, -500, -1_000) |
| 83 | + # directionalLight(128, 96, 64, -500, -500, +1_000) |
| 84 | + background(64) |
| 85 | + display_gizmo(500) |
| 86 | + if display_radius |
| 87 | + shape(shp_samples_spheres) |
| 88 | + else |
| 89 | + shape(shp_samples_points) |
| 90 | + end |
| 91 | + end |
| 92 | + |
| 93 | + def add_shape(sample) |
| 94 | + shp_point = create_shape(POINT, sample.x, sample.y, sample.z) |
| 95 | + shp_point.set_stroke(color(255)) |
| 96 | + shp_point.set_stroke_weight(3) |
| 97 | + shp_samples_points.add_child(shp_point) |
| 98 | + if ifs.nil? |
| 99 | + @ifs = DwIcosahedron.new(2) |
| 100 | + @verts_per_face = 3 |
| 101 | + # @ifs = DwCube.new(2) |
| 102 | + # @verts_per_face = 4 |
| 103 | + end |
| 104 | + shp_sphere = create_shape(PShape::GEOMETRY) |
| 105 | + shp_sphere.set_stroke(false) |
| 106 | + shp_sphere.set_fill(color(255)) |
| 107 | + shp_sphere.reset_matrix |
| 108 | + shp_sphere.translate(sample.x, sample.y, sample.z) |
| 109 | + DwMeshUtils::createPolyhedronShape(shp_sphere, ifs, sample.rad, verts_per_face, true) |
| 110 | + shp_samples_spheres.add_child(shp_sphere) |
| 111 | + # @shp_sphere_normals = createShape(PShape::GEOMETRY) |
| 112 | + # shp_sphere_normals.setStroke(false) |
| 113 | + # shp_sphere_normals.setFill(color(255)) |
| 114 | + # shp_sphere_normals.resetMatrix |
| 115 | + # shp_sphere_normals.translate(sample.x, sample.y, sample.z) |
| 116 | + # DwMeshUtils::createPolyhedronShapeNormals(shp_sphere_normals, ifs, sample.rad, 10) |
| 117 | + # shp_samples_spheres.addChild(shp_sphere_normals) |
| 118 | + end |
| 119 | + |
| 120 | + def display_gizmo(s) |
| 121 | + if shp_gizmo.nil? |
| 122 | + stroke_weight(1) |
| 123 | + @shp_gizmo = create_shape |
| 124 | + shp_gizmo.begin_shape(LINES) |
| 125 | + shp_gizmo.stroke(255, 0, 0) |
| 126 | + shp_gizmo.vertex(0, 0, 0) |
| 127 | + shp_gizmo.vertex(s, 0, 0) |
| 128 | + shp_gizmo.stroke(0, 255, 0) |
| 129 | + shp_gizmo.vertex(0, 0, 0) |
| 130 | + shp_gizmo.vertex(0, s, 0) |
| 131 | + shp_gizmo.stroke(0, 0, 255) |
| 132 | + shp_gizmo.vertex(0, 0, 0) |
| 133 | + shp_gizmo.vertex(0, 0, s) |
| 134 | + shp_gizmo.end_shape |
| 135 | + end |
| 136 | + shape shp_gizmo |
| 137 | + end |
| 138 | + |
| 139 | + def key_released |
| 140 | + case key |
| 141 | + when ' ' |
| 142 | + @display_radius = !display_radius |
| 143 | + when 'r' |
| 144 | + generate_poisson_sampling |
| 145 | + end |
| 146 | + end |
| 147 | +end |
| 148 | + |
| 149 | +PoissonSampling3D.new |
0 commit comments