Split out some code for refactoring purposes
This commit is contained in:
@@ -9,9 +9,14 @@
|
|||||||
#include <scene/3d/collision_shape.h>
|
#include <scene/3d/collision_shape.h>
|
||||||
#include "roads.h"
|
#include "roads.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FLAGS_SIDEWALK = (1 << 0),
|
||||||
|
FLAGS_INTERSECTION = (1 << 1),
|
||||||
|
FLAGS_WALL = (1 << 2),
|
||||||
|
};
|
||||||
|
|
||||||
void Roads::_bind_methods()
|
void Roads::_bind_methods()
|
||||||
{
|
{
|
||||||
ClassDB::bind_method(D_METHOD("curve_mesh", "points", "width", "flags", "sidewalk_width"), &Roads::curve_mesh);
|
|
||||||
ClassDB::bind_method(D_METHOD("add_scene_element", "root", "surface", "p2", "shape"), &Roads::add_scene_element);
|
ClassDB::bind_method(D_METHOD("add_scene_element", "root", "surface", "p2", "shape"), &Roads::add_scene_element);
|
||||||
}
|
}
|
||||||
void Roads::_get_property_list(List<PropertyInfo> *p_list) const
|
void Roads::_get_property_list(List<PropertyInfo> *p_list) const
|
||||||
@@ -171,21 +176,36 @@ Ref<Curve3D> Roads::build_curve(Vector3 p1, Vector3 p2, Vector3 p3, float total_
|
|||||||
assert(curve3->get_baked_length() > 0);
|
assert(curve3->get_baked_length() > 0);
|
||||||
return curve3;
|
return curve3;
|
||||||
}
|
}
|
||||||
|
inline float Roads::get_total_width(float width, int flags, float sidewalk_width)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
float total_width = 0.0f;
|
||||||
|
PoolVector<String> parts_list = rg->build_item_list(width, flags, sidewalk_width);
|
||||||
|
for (i = 0; i < parts_list.size(); i++)
|
||||||
|
total_width += offsets[parts_list[i]].x;
|
||||||
|
return total_width;
|
||||||
|
}
|
||||||
|
|
||||||
Array Roads::curve_mesh(PoolVector<Vector3> points, float width1, float width2, int flags, float sidewalk_width)
|
inline Ref<Curve3D> Roads::get_curve(const PoolVector<Vector3> &points, float width, int flags, float sidewalk_width)
|
||||||
|
{
|
||||||
|
float total_width = get_total_width(width, flags, sidewalk_width);
|
||||||
|
Ref<Curve3D> curve = build_curve(points[0], points[1], points[2], total_width);
|
||||||
|
return curve;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array Roads::curve_mesh(const PoolVector<Vector3> &points, Ref<Curve3D> curve3, float width1, float width2, int flags, float sidewalk_width)
|
||||||
{
|
{
|
||||||
float tx = 0.0f, total_width1 = 0.0f, total_width2 = 0.0f, t = 0.0f, l;
|
float tx = 0.0f, total_width1 = 0.0f, total_width2 = 0.0f, t = 0.0f, l;
|
||||||
int i;
|
int i;
|
||||||
Array ret;
|
Array ret;
|
||||||
all_offsets();
|
all_offsets();
|
||||||
|
total_width1 = get_total_width(width1, flags, sidewalk_width);
|
||||||
|
total_width2 = get_total_width(width2, flags, sidewalk_width);
|
||||||
PoolVector<String> parts_list1 = build_item_list(width1, flags, sidewalk_width);
|
PoolVector<String> parts_list1 = build_item_list(width1, flags, sidewalk_width);
|
||||||
for (i = 0; i < parts_list1.size(); i++)
|
|
||||||
total_width1 += offsets[parts_list1[i]].x;
|
|
||||||
PoolVector<String> parts_list2 = build_item_list(width2, flags, sidewalk_width);
|
PoolVector<String> parts_list2 = build_item_list(width2, flags, sidewalk_width);
|
||||||
for (i = 0; i < parts_list2.size(); i++)
|
|
||||||
total_width2 += offsets[parts_list2[i]].x;
|
|
||||||
assert(total_width1 >= 3.0f && total_width2 >= 3.0f);
|
assert(total_width1 >= 3.0f && total_width2 >= 3.0f);
|
||||||
Ref<Curve3D> curve3 = build_curve(points[0], points[1], points[2], total_width2);
|
// Ref<Curve3D> curve3 = build_curve(points[0], points[1], points[2], total_width2);
|
||||||
|
// Ref<Curve3D> curve3 = get_curve(points, width2, flags, sidewalk_width);
|
||||||
l = curve3->get_baked_length();
|
l = curve3->get_baked_length();
|
||||||
assert(l > 0.0f);
|
assert(l > 0.0f);
|
||||||
PoolVector<Vector3> new_verts, new_normals;
|
PoolVector<Vector3> new_verts, new_normals;
|
||||||
@@ -321,9 +341,11 @@ static Ref<ConcavePolygonShape> create_concave_polygon_shape(Vector<Array> surfa
|
|||||||
return shape;
|
return shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Roads::make_vmesh(Node *root, Ref<Material> mat, Ref<ArrayMesh> mesh, MeshInstance *xmi, Vector3 p1, Vector3 p2,
|
static inline PoolVector<Vector3> make_points(const PoolVector<Vector3> &ipoints)
|
||||||
Vector3 p3, float width1, float width2, int flags, float sidewalk_width)
|
|
||||||
{
|
{
|
||||||
|
Vector3 p1 = ipoints[0],
|
||||||
|
p2 = ipoints[1],
|
||||||
|
p3 = ipoints[2];
|
||||||
Vector3 m1 = p1 - p2;
|
Vector3 m1 = p1 - p2;
|
||||||
Vector3 m2 = Vector3();
|
Vector3 m2 = Vector3();
|
||||||
Vector3 m3 = p3 - p2;
|
Vector3 m3 = p3 - p2;
|
||||||
@@ -339,7 +361,16 @@ int Roads::make_vmesh(Node *root, Ref<Material> mat, Ref<ArrayMesh> mesh, MeshIn
|
|||||||
points.resize(3);
|
points.resize(3);
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
points.write()[i] = pts[i].snapped(Vector3(4.0f, 0.1f, 4.0f));
|
points.write()[i] = pts[i].snapped(Vector3(4.0f, 0.1f, 4.0f));
|
||||||
Array rdata = curve_mesh(points, width1, width2, flags, sidewalk_width);
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Roads::make_vmesh(Node *root, Ref<Material> mat, Ref<ArrayMesh> mesh, MeshInstance *xmi, RoadMeshData *data)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
PoolVector<Vector3> points = make_points(data->points);
|
||||||
|
rg->all_offsets();
|
||||||
|
Ref<Curve3D> curve3 = get_curve(points, data->width2, data->flags, data->sidewalk_width);
|
||||||
|
Array rdata = curve_mesh(points, curve3, data->width1, data->width2, data->flags, data->sidewalk_width);
|
||||||
Ref<ArrayMesh> mdata = mesh;
|
Ref<ArrayMesh> mdata = mesh;
|
||||||
assert(mdata.is_valid());
|
assert(mdata.is_valid());
|
||||||
mdata->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, rdata);
|
mdata->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, rdata);
|
||||||
@@ -349,7 +380,7 @@ int Roads::make_vmesh(Node *root, Ref<Material> mat, Ref<ArrayMesh> mesh, MeshIn
|
|||||||
Ref<ConcavePolygonShape> shape = create_concave_polygon_shape(surfaces);
|
Ref<ConcavePolygonShape> shape = create_concave_polygon_shape(surfaces);
|
||||||
mdata->surface_set_material(0, mat);
|
mdata->surface_set_material(0, mat);
|
||||||
xmi->set_mesh(mdata);
|
xmi->set_mesh(mdata);
|
||||||
call_deferred("add_scene_element", root, xmi, p2, shape);
|
call_deferred("add_scene_element", root, xmi, data->points[1], shape);
|
||||||
return xmi->get_instance_id();
|
return xmi->get_instance_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,27 +446,39 @@ void Roads::process_vshapes()
|
|||||||
List<int>::Element *e;
|
List<int>::Element *e;
|
||||||
for (e = active_vshapes.front(); e; e = e->next()) {
|
for (e = active_vshapes.front(); e; e = e->next()) {
|
||||||
i = e->get();
|
i = e->get();
|
||||||
const struct RoadGrid::vshape &v = vshapes[i];
|
struct RoadGrid::vshape &v = rg->get_vshapes().write()[i];
|
||||||
assert(v.p1.distance_squared_to(v.p2) > 2.0f);
|
assert(v.p1.distance_squared_to(v.p2) > 2.0f);
|
||||||
assert(v.p2.distance_squared_to(v.p3) > 2.0f);
|
assert(v.p2.distance_squared_to(v.p3) > 2.0f);
|
||||||
assert(v.p1.distance_squared_to(v.p3) > 2.0f);
|
assert(v.p1.distance_squared_to(v.p3) > 2.0f);
|
||||||
|
float sidewalk_width = 6.0f;
|
||||||
if (vshapes[i].instance < 0) {
|
if (vshapes[i].instance < 0) {
|
||||||
if (thread.thread.is_started())
|
if (thread.thread.is_started())
|
||||||
thread.thread.wait_to_finish();
|
thread.thread.wait_to_finish();
|
||||||
thread.mat = mat;
|
thread.mat = mat;
|
||||||
thread.vshape = i;
|
|
||||||
thread.width = 6.0;
|
|
||||||
thread.sidewalk_width = 3.0;
|
|
||||||
thread.flags = FLAGS_SIDEWALK|FLAGS_INTERSECTION;
|
|
||||||
thread.root = this;
|
thread.root = this;
|
||||||
Ref<ArrayMesh> mesh;
|
Ref<ArrayMesh> mesh;
|
||||||
mesh.instance();
|
mesh.instance();
|
||||||
thread.mesh = mesh;
|
thread.mesh = mesh;
|
||||||
thread.xmi = memnew(MeshInstance);
|
thread.xmi = memnew(MeshInstance);
|
||||||
|
create_data(&v, &thread.data,
|
||||||
|
FLAGS_SIDEWALK|FLAGS_INTERSECTION,
|
||||||
|
sidewalk_width);
|
||||||
thread.thread.start(generate_threaded, &thread);
|
thread.thread.start(generate_threaded, &thread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void Roads::create_data(struct RoadGrid::vshape *v, struct RoadMeshData *data, int flags, float sidewalk_width)
|
||||||
|
{
|
||||||
|
data->points.resize(3);
|
||||||
|
data->points.write()[0] = v->p1;
|
||||||
|
data->points.write()[1] = v->p2;
|
||||||
|
data->points.write()[2] = v->p3;
|
||||||
|
data->width1 = v->depth1;
|
||||||
|
data->width2 = v->depth2;
|
||||||
|
data->flags = flags;
|
||||||
|
data->sidewalk_width = sidewalk_width;
|
||||||
|
data->vshape = v;
|
||||||
|
}
|
||||||
|
|
||||||
void Roads::_notification(int p_what)
|
void Roads::_notification(int p_what)
|
||||||
{
|
{
|
||||||
@@ -456,19 +499,11 @@ void Roads::generate_threaded(void *p_userdata)
|
|||||||
{
|
{
|
||||||
struct thread_data *data = (struct thread_data *)p_userdata;
|
struct thread_data *data = (struct thread_data *)p_userdata;
|
||||||
Roads *obj = Object::cast_to<Roads>(data->root);
|
Roads *obj = Object::cast_to<Roads>(data->root);
|
||||||
obj->mutex.lock();
|
int instance = obj->make_vmesh(obj, data->mat, data->mesh, data->xmi, &data->data);
|
||||||
RoadGrid *rg = RoadsData::get_singleton()->get_road_grid();
|
|
||||||
const PoolVector<RoadGrid::vshape> &vshapes = rg->get_vshapes();
|
|
||||||
Vector3 p1 = vshapes[data->vshape].p1;
|
|
||||||
Vector3 p2 = vshapes[data->vshape].p2;
|
|
||||||
Vector3 p3 = vshapes[data->vshape].p3;
|
|
||||||
float width1 = vshapes[data->vshape].depth1;
|
|
||||||
float width2 = vshapes[data->vshape].depth2;
|
|
||||||
obj->mutex.unlock();
|
|
||||||
int instance = obj->make_vmesh(obj, data->mat, data->mesh, data->xmi, p1, p2, p3, width1, width2, data->flags, data->sidewalk_width);
|
|
||||||
assert(instance >= 0);
|
assert(instance >= 0);
|
||||||
obj->mutex.lock();
|
obj->mutex.lock();
|
||||||
rg->get_vshapes().write()[data->vshape].instance = instance;
|
|
||||||
|
data->data.vshape->instance = instance;
|
||||||
obj->mutex.unlock();
|
obj->mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,16 @@
|
|||||||
#include <scene/resources/concave_polygon_shape.h>
|
#include <scene/resources/concave_polygon_shape.h>
|
||||||
|
|
||||||
class StaticBody;
|
class StaticBody;
|
||||||
|
struct RoadGrid::vshape;
|
||||||
|
|
||||||
|
struct RoadMeshData {
|
||||||
|
PoolVector<Vector3> points;
|
||||||
|
float width1;
|
||||||
|
float width2;
|
||||||
|
int flags;
|
||||||
|
float sidewalk_width;
|
||||||
|
struct RoadGrid::vshape *vshape;
|
||||||
|
};
|
||||||
|
|
||||||
class Roads: public MeshInstance {
|
class Roads: public MeshInstance {
|
||||||
GDCLASS(Roads, MeshInstance);
|
GDCLASS(Roads, MeshInstance);
|
||||||
@@ -25,13 +35,10 @@ protected:
|
|||||||
struct thread_data {
|
struct thread_data {
|
||||||
Thread thread;
|
Thread thread;
|
||||||
Ref<Material> mat;
|
Ref<Material> mat;
|
||||||
int vshape;
|
|
||||||
float width;
|
|
||||||
float sidewalk_width;
|
|
||||||
int flags;
|
|
||||||
Node *root;
|
Node *root;
|
||||||
Ref<ArrayMesh> mesh;
|
Ref<ArrayMesh> mesh;
|
||||||
MeshInstance *xmi;
|
MeshInstance *xmi;
|
||||||
|
struct RoadMeshData data;
|
||||||
};
|
};
|
||||||
struct thread_data thread;
|
struct thread_data thread;
|
||||||
static void generate_threaded(void *p_userdata);
|
static void generate_threaded(void *p_userdata);
|
||||||
@@ -70,11 +77,16 @@ public:
|
|||||||
void all_offsets();
|
void all_offsets();
|
||||||
PoolVector<String> build_item_list(float width, int flags, float sidewalk_width) const;
|
PoolVector<String> build_item_list(float width, int flags, float sidewalk_width) const;
|
||||||
Ref<Curve3D> build_curve(Vector3 p1, Vector3 p2, Vector3 p3, float total_width) const;
|
Ref<Curve3D> build_curve(Vector3 p1, Vector3 p2, Vector3 p3, float total_width) const;
|
||||||
Array curve_mesh(PoolVector<Vector3> points, float width1, float width2, int flags, float sidewalk_width);
|
// Array curve_mesh(PoolVector<Vector3> points, float width1, float width2, int flags, float sidewalk_width);
|
||||||
int make_vmesh(Node *root, Ref<Material> mat, Ref<ArrayMesh> mesh, MeshInstance *xmi, Vector3 p1, Vector3 p2,
|
Array curve_mesh(const PoolVector<Vector3> &points, Ref<Curve3D> curve3, float width1, float width2, int flags, float sidewalk_width);
|
||||||
Vector3 p3, float width1, float width2, int flags, float sidewalk_width);
|
int make_vmesh(Node *root, Ref<Material> mat, Ref<ArrayMesh> mesh, MeshInstance *xmi, RoadMeshData *data);
|
||||||
void process_vshapes();
|
void process_vshapes();
|
||||||
|
void create_data(struct RoadGrid::vshape *v,
|
||||||
|
struct RoadMeshData *data,
|
||||||
|
int flags, float sidewalk_width);
|
||||||
void add_scene_element(Node *root, Node *xnode, const Vector3 &p2, Ref<ConcavePolygonShape> shape);
|
void add_scene_element(Node *root, Node *xnode, const Vector3 &p2, Ref<ConcavePolygonShape> shape);
|
||||||
|
inline float get_total_width(float width, int flags, float sidewalk_width);
|
||||||
|
inline Ref<Curve3D> get_curve(const PoolVector<Vector3> &points, float width, int flags, float sidewalk_width);
|
||||||
};
|
};
|
||||||
|
|
||||||
class RoadsData: public Object {
|
class RoadsData: public Object {
|
||||||
|
|||||||
Reference in New Issue
Block a user