Преглед на файлове

Add properties to disable top/bottom cap generation in TubeTrailMesh

This can be used to improve generation and rendering performance,
or for certain special effects such as particle trails.
Hugo Locurcio преди 3 години
родител
ревизия
6e330e8a75
променени са 3 файла, в които са добавени 128 реда и са изтрити 83 реда
  1. 6 0
      doc/classes/TubeTrailMesh.xml
  2. 114 83
      scene/resources/primitive_meshes.cpp
  3. 8 0
      scene/resources/primitive_meshes.h

+ 6 - 0
doc/classes/TubeTrailMesh.xml

@@ -7,6 +7,12 @@
 	<tutorials>
 	<tutorials>
 	</tutorials>
 	</tutorials>
 	<members>
 	<members>
+		<member name="cap_bottom" type="bool" setter="set_cap_bottom" getter="is_cap_bottom" default="true">
+			If [code]true[/code], generates a cap at the bottom of the tube. This can be set to [code]false[/code] to speed up generation and rendering when the cap is never seen by the camera.
+		</member>
+		<member name="cap_top" type="bool" setter="set_cap_top" getter="is_cap_top" default="true">
+			If [code]true[/code], generates a cap at the top of the tube. This can be set to [code]false[/code] to speed up generation and rendering when the cap is never seen by the camera.
+		</member>
 		<member name="curve" type="Curve" setter="set_curve" getter="get_curve">
 		<member name="curve" type="Curve" setter="set_curve" getter="get_curve">
 		</member>
 		</member>
 		<member name="radial_steps" type="int" setter="set_radial_steps" getter="get_radial_steps" default="8">
 		<member name="radial_steps" type="int" setter="set_radial_steps" getter="get_radial_steps" default="8">

+ 114 - 83
scene/resources/primitive_meshes.cpp

@@ -2171,6 +2171,24 @@ int TubeTrailMesh::get_section_rings() const {
 	return section_rings;
 	return section_rings;
 }
 }
 
 
+void TubeTrailMesh::set_cap_top(bool p_cap_top) {
+	cap_top = p_cap_top;
+	_request_update();
+}
+
+bool TubeTrailMesh::is_cap_top() const {
+	return cap_top;
+}
+
+void TubeTrailMesh::set_cap_bottom(bool p_cap_bottom) {
+	cap_bottom = p_cap_bottom;
+	_request_update();
+}
+
+bool TubeTrailMesh::is_cap_bottom() const {
+	return cap_bottom;
+}
+
 void TubeTrailMesh::set_curve(const Ref<Curve> &p_curve) {
 void TubeTrailMesh::set_curve(const Ref<Curve> &p_curve) {
 	if (curve == p_curve) {
 	if (curve == p_curve) {
 		return;
 		return;
@@ -2284,49 +2302,21 @@ void TubeTrailMesh::_create_mesh_array(Array &p_arr) const {
 		thisrow = point;
 		thisrow = point;
 	}
 	}
 
 
-	// add top
-	float scale_pos = 1.0;
-	if (curve.is_valid() && curve->get_point_count() > 0) {
-		scale_pos = curve->sample_baked(0);
-	}
-
-	if (scale_pos > CMP_EPSILON) {
-		float y = depth * 0.5;
-
-		thisrow = point;
-		points.push_back(Vector3(0.0, y, 0));
-		normals.push_back(Vector3(0.0, 1.0, 0.0));
-		ADD_TANGENT(1.0, 0.0, 0.0, 1.0)
-		uvs.push_back(Vector2(0.25, 0.75));
-		point++;
-
-		bone_indices.push_back(0);
-		bone_indices.push_back(0);
-		bone_indices.push_back(0);
-		bone_indices.push_back(0);
-
-		bone_weights.push_back(1.0);
-		bone_weights.push_back(0);
-		bone_weights.push_back(0);
-		bone_weights.push_back(0);
-
-		float rm = radius * scale_pos;
-
-		for (int i = 0; i <= radial_steps; i++) {
-			float r = i;
-			r /= radial_steps;
-
-			float x = sin(r * Math_TAU);
-			float z = cos(r * Math_TAU);
+	if (cap_top) {
+		// add top
+		float scale_pos = 1.0;
+		if (curve.is_valid() && curve->get_point_count() > 0) {
+			scale_pos = curve->sample_baked(0);
+		}
 
 
-			float u = ((x + 1.0) * 0.25);
-			float v = 0.5 + ((z + 1.0) * 0.25);
+		if (scale_pos > CMP_EPSILON) {
+			float y = depth * 0.5;
 
 
-			Vector3 p = Vector3(x * rm, y, z * rm);
-			points.push_back(p);
+			thisrow = point;
+			points.push_back(Vector3(0.0, y, 0));
 			normals.push_back(Vector3(0.0, 1.0, 0.0));
 			normals.push_back(Vector3(0.0, 1.0, 0.0));
 			ADD_TANGENT(1.0, 0.0, 0.0, 1.0)
 			ADD_TANGENT(1.0, 0.0, 0.0, 1.0)
-			uvs.push_back(Vector2(u, v));
+			uvs.push_back(Vector2(0.25, 0.75));
 			point++;
 			point++;
 
 
 			bone_indices.push_back(0);
 			bone_indices.push_back(0);
@@ -2339,57 +2329,59 @@ void TubeTrailMesh::_create_mesh_array(Array &p_arr) const {
 			bone_weights.push_back(0);
 			bone_weights.push_back(0);
 			bone_weights.push_back(0);
 			bone_weights.push_back(0);
 
 
-			if (i > 0) {
-				indices.push_back(thisrow);
-				indices.push_back(point - 1);
-				indices.push_back(point - 2);
-			}
-		}
-	}
+			float rm = radius * scale_pos;
 
 
-	float scale_neg = 1.0;
-	if (curve.is_valid() && curve->get_point_count() > 0) {
-		scale_neg = curve->sample_baked(1.0);
-	}
+			for (int i = 0; i <= radial_steps; i++) {
+				float r = i;
+				r /= radial_steps;
 
 
-	// add bottom
-	if (scale_neg > CMP_EPSILON) {
-		float y = depth * -0.5;
+				float x = sin(r * Math_TAU);
+				float z = cos(r * Math_TAU);
 
 
-		thisrow = point;
-		points.push_back(Vector3(0.0, y, 0.0));
-		normals.push_back(Vector3(0.0, -1.0, 0.0));
-		ADD_TANGENT(1.0, 0.0, 0.0, 1.0)
-		uvs.push_back(Vector2(0.75, 0.75));
-		point++;
+				float u = ((x + 1.0) * 0.25);
+				float v = 0.5 + ((z + 1.0) * 0.25);
 
 
-		bone_indices.push_back(sections);
-		bone_indices.push_back(0);
-		bone_indices.push_back(0);
-		bone_indices.push_back(0);
+				Vector3 p = Vector3(x * rm, y, z * rm);
+				points.push_back(p);
+				normals.push_back(Vector3(0.0, 1.0, 0.0));
+				ADD_TANGENT(1.0, 0.0, 0.0, 1.0)
+				uvs.push_back(Vector2(u, v));
+				point++;
 
 
-		bone_weights.push_back(1.0);
-		bone_weights.push_back(0);
-		bone_weights.push_back(0);
-		bone_weights.push_back(0);
+				bone_indices.push_back(0);
+				bone_indices.push_back(0);
+				bone_indices.push_back(0);
+				bone_indices.push_back(0);
 
 
-		float rm = radius * scale_neg;
+				bone_weights.push_back(1.0);
+				bone_weights.push_back(0);
+				bone_weights.push_back(0);
+				bone_weights.push_back(0);
 
 
-		for (int i = 0; i <= radial_steps; i++) {
-			float r = i;
-			r /= radial_steps;
+				if (i > 0) {
+					indices.push_back(thisrow);
+					indices.push_back(point - 1);
+					indices.push_back(point - 2);
+				}
+			}
+		}
+	}
 
 
-			float x = sin(r * Math_TAU);
-			float z = cos(r * Math_TAU);
+	if (cap_bottom) {
+		float scale_neg = 1.0;
+		if (curve.is_valid() && curve->get_point_count() > 0) {
+			scale_neg = curve->sample_baked(1.0);
+		}
 
 
-			float u = 0.5 + ((x + 1.0) * 0.25);
-			float v = 1.0 - ((z + 1.0) * 0.25);
+		if (scale_neg > CMP_EPSILON) {
+			// add bottom
+			float y = depth * -0.5;
 
 
-			Vector3 p = Vector3(x * rm, y, z * rm);
-			points.push_back(p);
+			thisrow = point;
+			points.push_back(Vector3(0.0, y, 0.0));
 			normals.push_back(Vector3(0.0, -1.0, 0.0));
 			normals.push_back(Vector3(0.0, -1.0, 0.0));
 			ADD_TANGENT(1.0, 0.0, 0.0, 1.0)
 			ADD_TANGENT(1.0, 0.0, 0.0, 1.0)
-			uvs.push_back(Vector2(u, v));
+			uvs.push_back(Vector2(0.75, 0.75));
 			point++;
 			point++;
 
 
 			bone_indices.push_back(sections);
 			bone_indices.push_back(sections);
@@ -2402,10 +2394,40 @@ void TubeTrailMesh::_create_mesh_array(Array &p_arr) const {
 			bone_weights.push_back(0);
 			bone_weights.push_back(0);
 			bone_weights.push_back(0);
 			bone_weights.push_back(0);
 
 
-			if (i > 0) {
-				indices.push_back(thisrow);
-				indices.push_back(point - 2);
-				indices.push_back(point - 1);
+			float rm = radius * scale_neg;
+
+			for (int i = 0; i <= radial_steps; i++) {
+				float r = i;
+				r /= radial_steps;
+
+				float x = sin(r * Math_TAU);
+				float z = cos(r * Math_TAU);
+
+				float u = 0.5 + ((x + 1.0) * 0.25);
+				float v = 1.0 - ((z + 1.0) * 0.25);
+
+				Vector3 p = Vector3(x * rm, y, z * rm);
+				points.push_back(p);
+				normals.push_back(Vector3(0.0, -1.0, 0.0));
+				ADD_TANGENT(1.0, 0.0, 0.0, 1.0)
+				uvs.push_back(Vector2(u, v));
+				point++;
+
+				bone_indices.push_back(sections);
+				bone_indices.push_back(0);
+				bone_indices.push_back(0);
+				bone_indices.push_back(0);
+
+				bone_weights.push_back(1.0);
+				bone_weights.push_back(0);
+				bone_weights.push_back(0);
+				bone_weights.push_back(0);
+
+				if (i > 0) {
+					indices.push_back(thisrow);
+					indices.push_back(point - 2);
+					indices.push_back(point - 1);
+				}
 			}
 			}
 		}
 		}
 	}
 	}
@@ -2435,6 +2457,12 @@ void TubeTrailMesh::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_section_rings", "section_rings"), &TubeTrailMesh::set_section_rings);
 	ClassDB::bind_method(D_METHOD("set_section_rings", "section_rings"), &TubeTrailMesh::set_section_rings);
 	ClassDB::bind_method(D_METHOD("get_section_rings"), &TubeTrailMesh::get_section_rings);
 	ClassDB::bind_method(D_METHOD("get_section_rings"), &TubeTrailMesh::get_section_rings);
 
 
+	ClassDB::bind_method(D_METHOD("set_cap_top", "cap_top"), &TubeTrailMesh::set_cap_top);
+	ClassDB::bind_method(D_METHOD("is_cap_top"), &TubeTrailMesh::is_cap_top);
+
+	ClassDB::bind_method(D_METHOD("set_cap_bottom", "cap_bottom"), &TubeTrailMesh::set_cap_bottom);
+	ClassDB::bind_method(D_METHOD("is_cap_bottom"), &TubeTrailMesh::is_cap_bottom);
+
 	ClassDB::bind_method(D_METHOD("set_curve", "curve"), &TubeTrailMesh::set_curve);
 	ClassDB::bind_method(D_METHOD("set_curve", "curve"), &TubeTrailMesh::set_curve);
 	ClassDB::bind_method(D_METHOD("get_curve"), &TubeTrailMesh::get_curve);
 	ClassDB::bind_method(D_METHOD("get_curve"), &TubeTrailMesh::get_curve);
 
 
@@ -2447,13 +2475,16 @@ void TubeTrailMesh::_bind_methods() {
 
 
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "section_rings", PROPERTY_HINT_RANGE, "1,128,1"), "set_section_rings", "get_section_rings");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "section_rings", PROPERTY_HINT_RANGE, "1,128,1"), "set_section_rings", "get_section_rings");
 
 
+	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cap_top"), "set_cap_top", "is_cap_top");
+	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cap_bottom"), "set_cap_bottom", "is_cap_bottom");
+
 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve", "get_curve");
 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve", "get_curve");
 }
 }
 
 
 TubeTrailMesh::TubeTrailMesh() {
 TubeTrailMesh::TubeTrailMesh() {
 }
 }
 
 
-// TUBE TRAIL
+// RIBBON TRAIL
 
 
 void RibbonTrailMesh::set_shape(Shape p_shape) {
 void RibbonTrailMesh::set_shape(Shape p_shape) {
 	shape = p_shape;
 	shape = p_shape;

+ 8 - 0
scene/resources/primitive_meshes.h

@@ -431,6 +431,8 @@ private:
 	int sections = 5;
 	int sections = 5;
 	float section_length = 0.2;
 	float section_length = 0.2;
 	int section_rings = 3;
 	int section_rings = 3;
+	bool cap_top = true;
+	bool cap_bottom = true;
 
 
 	Ref<Curve> curve;
 	Ref<Curve> curve;
 
 
@@ -456,6 +458,12 @@ public:
 	void set_section_rings(const int p_section_rings);
 	void set_section_rings(const int p_section_rings);
 	int get_section_rings() const;
 	int get_section_rings() const;
 
 
+	void set_cap_top(bool p_cap_top);
+	bool is_cap_top() const;
+
+	void set_cap_bottom(bool p_cap_bottom);
+	bool is_cap_bottom() const;
+
 	void set_curve(const Ref<Curve> &p_curve);
 	void set_curve(const Ref<Curve> &p_curve);
 	Ref<Curve> get_curve() const;
 	Ref<Curve> get_curve() const;