소스 검색

Added a unit test and fixed indentation.

stophe 8 년 전
부모
커밋
ebaad20f2f
2개의 변경된 파일269개의 추가작업 그리고 206개의 파일을 삭제
  1. 191 206
      jme3-core/src/main/java/com/jme3/scene/shape/Cylinder.java
  2. 78 0
      jme3-core/src/test/java/com/jme3/scene/ShapeGeometryTest.java

+ 191 - 206
jme3-core/src/main/java/com/jme3/scene/shape/Cylinder.java

@@ -125,9 +125,9 @@ public class Cylinder extends Mesh {
      * a suited distorted texture.
      *
      * @param axisSamples The number of vertices samples along the axis. It is equal to the number of segments + 1; so 
-	 * that, for instance, 4 samples mean the cylinder will be made of 3 segments.
+     * that, for instance, 4 samples mean the cylinder will be made of 3 segments.
      * @param radialSamples The number of triangle samples along the radius. For instance, 4 means that the sides of the
-	 * cylinder are made of 4 rectangles, and the top and bottom are made of 4 triangles.
+     * cylinder are made of 4 rectangles, and the top and bottom are made of 4 triangles.
      * @param radius
      *            The radius of the cylinder.
      * @param height
@@ -199,27 +199,27 @@ public class Cylinder extends Mesh {
      * Rebuilds the cylinder based on a new set of parameters.
      *
      * @param axisSamples The number of vertices samples along the axis. It is equal to the number of segments + 1; so 
-	 * that, for instance, 4 samples mean the cylinder will be made of 3 segments.
+     * that, for instance, 4 samples mean the cylinder will be made of 3 segments.
      * @param radialSamples The number of triangle samples along the radius. For instance, 4 means that the sides of the
-	 * cylinder are made of 4 rectangles, and the top and bottom are made of 4 triangles.
+     * cylinder are made of 4 rectangles, and the top and bottom are made of 4 triangles.
      * @param topRadius the radius of the top of the cylinder.
-	 * @param bottomRadius the radius of the bottom of the cylinder.
+     * @param bottomRadius the radius of the bottom of the cylinder.
      * @param height the cylinder's height.
      * @param closed should the cylinder have top and bottom surfaces.
      * @param inverted is the cylinder is meant to be viewed from the inside.
      */
     public void updateGeometry(int axisSamples, int radialSamples,
-            float topRadius, float bottomRadius, float height, boolean closed, boolean inverted)
-	{
-		// Ensure there's at least two axis samples and 3 radial samples, and positive dimensions.
-		if( axisSamples < 2
-			|| radialSamples < 3
-			|| topRadius <= 0
-			|| bottomRadius <= 0
-			|| height <= 0 )
-			throw new IllegalArgumentException("Cylinders must have at least 2 axis samples and 3 radial samples, and positive dimensions.");
-		
-		this.axisSamples = axisSamples;
+            float topRadius, float bottomRadius, float height, boolean closed, boolean inverted) {
+        // Ensure there's at least two axis samples and 3 radial samples, and positive dimensions.
+        if( axisSamples < 2
+            || radialSamples < 3
+            || topRadius <= 0
+            || bottomRadius <= 0
+            || height <= 0 ) {
+            throw new IllegalArgumentException("Cylinders must have at least 2 axis samples and 3 radial samples, and positive dimensions.");
+        }
+        
+        this.axisSamples = axisSamples;
         this.radialSamples = radialSamples;
         this.radius = bottomRadius;
         this.radius2 = topRadius;
@@ -229,209 +229,194 @@ public class Cylinder extends Mesh {
 
         // Vertices : One per radial sample plus one duplicate for texture closing around the sides.
         int verticesCount = axisSamples * (radialSamples +1);
-		// Triangles: Two per side rectangle, which is the product of numbers of samples.
-		int trianglesCount = axisSamples * radialSamples * 2 ;
-		if( closed )
-		{
-			// If there are caps, add two additional rims and two summits.
-			verticesCount += 2 + 2 * (radialSamples +1);
-			// Add one triangle per radial sample, twice, to form the caps.
-			trianglesCount += 2 * radialSamples ;
-		}
-
-		// Compute the points along a unit circle:
-		float[][] circlePoints = new float[radialSamples+1][2];
-		for (int circlePoint = 0; circlePoint < radialSamples; circlePoint++)
-		{
+        // Triangles: Two per side rectangle, which is the product of numbers of samples.
+        int trianglesCount = axisSamples * radialSamples * 2 ;
+        if( closed ) {
+            // If there are caps, add two additional rims and two summits.
+            verticesCount += 2 + 2 * (radialSamples +1);
+            // Add one triangle per radial sample, twice, to form the caps.
+            trianglesCount += 2 * radialSamples ;
+        }
+
+        // Compute the points along a unit circle:
+        float[][] circlePoints = new float[radialSamples+1][2];
+        for (int circlePoint = 0; circlePoint < radialSamples; circlePoint++) {
             float angle = FastMath.TWO_PI / radialSamples * circlePoint;
             circlePoints[circlePoint][0] = FastMath.cos(angle);
             circlePoints[circlePoint][1] = FastMath.sin(angle);
         }
-		// Add an additional point for closing the texture around the side of the cylinder.
-		circlePoints[radialSamples][0] = circlePoints[0][0];
+        // Add an additional point for closing the texture around the side of the cylinder.
+        circlePoints[radialSamples][0] = circlePoints[0][0];
         circlePoints[radialSamples][1] = circlePoints[0][1];
-		
+        
         // Calculate normals.
-		// 
-		// A---------B
-		//  \        |
-		//   \       |
-		//    \      |
-		//     D-----C
-		//
-		// Let be B and C the top and bottom points of the axis, and A and D the top and bottom edges.
-		// The normal in A and D is simply orthogonal to AD, which means we can get it once per sample.
-		//
-		Vector3f[] circleNormals = new Vector3f[radialSamples+1];
-		for (int circlePoint = 0; circlePoint < radialSamples+1; circlePoint++)
-		{
+        // 
+        // A---------B
+        //  \        |
+        //   \       |
+        //    \      |
+        //     D-----C
+        //
+        // Let be B and C the top and bottom points of the axis, and A and D the top and bottom edges.
+        // The normal in A and D is simply orthogonal to AD, which means we can get it once per sample.
+        //
+        Vector3f[] circleNormals = new Vector3f[radialSamples+1];
+        for (int circlePoint = 0; circlePoint < radialSamples+1; circlePoint++) {
             // The normal is the orthogonal to the side, which can be got without trigonometry.
-			// The edge direction is oriented so that it goes up by Height, and out by the radius difference; let's use
-			// those values in reverse order.
-			Vector3f normal = new Vector3f(height * circlePoints[circlePoint][0], height * circlePoints[circlePoint][1], bottomRadius - topRadius );
-			circleNormals[circlePoint] = normal.normalizeLocal();
+            // The edge direction is oriented so that it goes up by Height, and out by the radius difference; let's use
+            // those values in reverse order.
+            Vector3f normal = new Vector3f(height * circlePoints[circlePoint][0], height * circlePoints[circlePoint][1], bottomRadius - topRadius );
+            circleNormals[circlePoint] = normal.normalizeLocal();
         }
 
-		float[] vertices = new float[verticesCount * 3];
-		float[] normals = new float[verticesCount * 3];
-		float[] textureCoords = new float[verticesCount * 2];
-		int currentIndex = 0;
-		
-		// Add a circle of points for each axis sample.
-		for(int axisSample = 0; axisSample < axisSamples; axisSample++ )
-		{
-			float currentHeight = -height / 2 + height * axisSample / (axisSamples-1);
-			float currentRadius = bottomRadius + (topRadius - bottomRadius) * axisSample / (axisSamples-1);
-			
-			for (int circlePoint = 0; circlePoint < radialSamples + 1; circlePoint++)
-			{
-				// Position, by multipliying the position on a unit circle with the current radius.
-				vertices[currentIndex*3] = circlePoints[circlePoint][0] * currentRadius;
-				vertices[currentIndex*3 +1] = circlePoints[circlePoint][1] * currentRadius;
-				vertices[currentIndex*3 +2] = currentHeight;
-				
-				// Normal
-				Vector3f currentNormal = circleNormals[circlePoint];
-				normals[currentIndex*3] = currentNormal.x;
-				normals[currentIndex*3+1] = currentNormal.y;
-				normals[currentIndex*3+2] = currentNormal.z;
-						
-				// Texture
-				// The X is the angular position of the point.
-				textureCoords[currentIndex *2] = (float) circlePoint / radialSamples;
-				// Depending on whether there is a cap, the Y is either the height scaled to [0,1], or the radii of 
-				// the cap count as well.
-				if (closed)
-					textureCoords[currentIndex *2 +1] = (bottomRadius + height / 2 + currentHeight) / (bottomRadius + height + topRadius);
-				else
-					textureCoords[currentIndex *2 +1] = height / 2 + currentHeight;
-				
-				currentIndex++;
-			}
-		}
-		
-		// If closed, add duplicate rims on top and bottom, with normals facing up and down.
-		if (closed)
-		{
-			// Bottom
-			for (int circlePoint = 0; circlePoint < radialSamples + 1; circlePoint++)
-			{
-				vertices[currentIndex*3] = circlePoints[circlePoint][0] * bottomRadius;
-				vertices[currentIndex*3 +1] = circlePoints[circlePoint][1] * bottomRadius;
-				vertices[currentIndex*3 +2] = -height/2;
-
-				normals[currentIndex*3] = 0;
-				normals[currentIndex*3+1] = 0;
-				normals[currentIndex*3+2] = -1;
-
-				textureCoords[currentIndex *2] = (float) circlePoint / radialSamples;
-				textureCoords[currentIndex *2 +1] = bottomRadius / (bottomRadius + height + topRadius);
-
-				currentIndex++;
-			}
-			// Top
-			for (int circlePoint = 0; circlePoint < radialSamples + 1; circlePoint++)
-			{
-				vertices[currentIndex*3] = circlePoints[circlePoint][0] * topRadius;
-				vertices[currentIndex*3 +1] = circlePoints[circlePoint][1] * topRadius;
-				vertices[currentIndex*3 +2] = height/2;
-
-				normals[currentIndex*3] = 0;
-				normals[currentIndex*3+1] = 0;
-				normals[currentIndex*3+2] = 1;
-
-				textureCoords[currentIndex *2] = (float) circlePoint / radialSamples;
-				textureCoords[currentIndex *2 +1] = (bottomRadius + height) / (bottomRadius + height + topRadius);
-
-				currentIndex++;
-			}
-			
-			// Add the centers of the caps.
-			vertices[currentIndex*3] = 0;
-			vertices[currentIndex*3 +1] = 0;
-			vertices[currentIndex*3 +2] = -height/2;
-			
-			normals[currentIndex*3] = 0;
-			normals[currentIndex*3+1] = 0;
-			normals[currentIndex*3+2] = -1;
-			
-			textureCoords[currentIndex *2] = 0.5f;
-			textureCoords[currentIndex *2+1] = 0f;
-			
-			currentIndex++;
-			
-			vertices[currentIndex*3] = 0;
-			vertices[currentIndex*3 +1] = 0;
-			vertices[currentIndex*3 +2] = height/2;
-			
-			normals[currentIndex*3] = 0;
-			normals[currentIndex*3+1] = 0;
-			normals[currentIndex*3+2] = 1;
-			
-			textureCoords[currentIndex *2] = 0.5f;
-			textureCoords[currentIndex *2+1] = 1f;
+        float[] vertices = new float[verticesCount * 3];
+        float[] normals = new float[verticesCount * 3];
+        float[] textureCoords = new float[verticesCount * 2];
+        int currentIndex = 0;
+        
+        // Add a circle of points for each axis sample.
+        for(int axisSample = 0; axisSample < axisSamples; axisSample++ ) {
+            float currentHeight = -height / 2 + height * axisSample / (axisSamples-1);
+            float currentRadius = bottomRadius + (topRadius - bottomRadius) * axisSample / (axisSamples-1);
+            
+            for (int circlePoint = 0; circlePoint < radialSamples + 1; circlePoint++) {
+                // Position, by multipliying the position on a unit circle with the current radius.
+                vertices[currentIndex*3] = circlePoints[circlePoint][0] * currentRadius;
+                vertices[currentIndex*3 +1] = circlePoints[circlePoint][1] * currentRadius;
+                vertices[currentIndex*3 +2] = currentHeight;
+                
+                // Normal
+                Vector3f currentNormal = circleNormals[circlePoint];
+                normals[currentIndex*3] = currentNormal.x;
+                normals[currentIndex*3+1] = currentNormal.y;
+                normals[currentIndex*3+2] = currentNormal.z;
+                        
+                // Texture
+                // The X is the angular position of the point.
+                textureCoords[currentIndex *2] = (float) circlePoint / radialSamples;
+                // Depending on whether there is a cap, the Y is either the height scaled to [0,1], or the radii of 
+                // the cap count as well.
+                if (closed)
+                    textureCoords[currentIndex *2 +1] = (bottomRadius + height / 2 + currentHeight) / (bottomRadius + height + topRadius);
+                else
+                    textureCoords[currentIndex *2 +1] = height / 2 + currentHeight;
+                
+                currentIndex++;
+            }
+        }
+        
+        // If closed, add duplicate rims on top and bottom, with normals facing up and down.
+        if (closed) {
+            // Bottom
+            for (int circlePoint = 0; circlePoint < radialSamples + 1; circlePoint++) {
+                vertices[currentIndex*3] = circlePoints[circlePoint][0] * bottomRadius;
+                vertices[currentIndex*3 +1] = circlePoints[circlePoint][1] * bottomRadius;
+                vertices[currentIndex*3 +2] = -height/2;
+
+                normals[currentIndex*3] = 0;
+                normals[currentIndex*3+1] = 0;
+                normals[currentIndex*3+2] = -1;
+
+                textureCoords[currentIndex *2] = (float) circlePoint / radialSamples;
+                textureCoords[currentIndex *2 +1] = bottomRadius / (bottomRadius + height + topRadius);
+
+                currentIndex++;
+            }
+            // Top
+            for (int circlePoint = 0; circlePoint < radialSamples + 1; circlePoint++) {
+                vertices[currentIndex*3] = circlePoints[circlePoint][0] * topRadius;
+                vertices[currentIndex*3 +1] = circlePoints[circlePoint][1] * topRadius;
+                vertices[currentIndex*3 +2] = height/2;
+
+                normals[currentIndex*3] = 0;
+                normals[currentIndex*3+1] = 0;
+                normals[currentIndex*3+2] = 1;
+
+                textureCoords[currentIndex *2] = (float) circlePoint / radialSamples;
+                textureCoords[currentIndex *2 +1] = (bottomRadius + height) / (bottomRadius + height + topRadius);
+
+                currentIndex++;
+            }
+            
+            // Add the centers of the caps.
+            vertices[currentIndex*3] = 0;
+            vertices[currentIndex*3 +1] = 0;
+            vertices[currentIndex*3 +2] = -height/2;
+            
+            normals[currentIndex*3] = 0;
+            normals[currentIndex*3+1] = 0;
+            normals[currentIndex*3+2] = -1;
+            
+            textureCoords[currentIndex *2] = 0.5f;
+            textureCoords[currentIndex *2+1] = 0f;
+            
+            currentIndex++;
+            
+            vertices[currentIndex*3] = 0;
+            vertices[currentIndex*3 +1] = 0;
+            vertices[currentIndex*3 +2] = height/2;
+            
+            normals[currentIndex*3] = 0;
+            normals[currentIndex*3+1] = 0;
+            normals[currentIndex*3+2] = 1;
+            
+            textureCoords[currentIndex *2] = 0.5f;
+            textureCoords[currentIndex *2+1] = 1f;
         }
 
-		// Add the triangles indexes.
+        // Add the triangles indexes.
         short[] indices = new short[trianglesCount * 3];
-		currentIndex = 0;
-		for (short axisSample = 0; axisSample < axisSamples - 1; axisSample++)
-		{
-			for (int circlePoint = 0; circlePoint < radialSamples; circlePoint++)
-			{
-				indices[currentIndex++] = (short) (axisSample * (radialSamples + 1) + circlePoint);
-				indices[currentIndex++] =  (short) (axisSample * (radialSamples + 1) + circlePoint + 1);
-				indices[currentIndex++] =  (short) ((axisSample + 1) * (radialSamples + 1) + circlePoint);
-
-				indices[currentIndex++] =  (short) ((axisSample + 1) * (radialSamples + 1) + circlePoint);
-				indices[currentIndex++] =  (short) (axisSample * (radialSamples + 1) + circlePoint + 1);
-				indices[currentIndex++] =  (short) ((axisSample + 1) * (radialSamples + 1) + circlePoint + 1);
-			}
-		}
-		// Add caps if needed.
-		if(closed)
-		{
-			short bottomCapIndex = (short) (verticesCount - 2);
-			short topCapIndex = (short) (verticesCount - 1);
-			
-			int bottomRowOffset = (axisSamples) * (radialSamples +1 );
-			int topRowOffset = (axisSamples+1) * (radialSamples +1 );
-			
-			for (int circlePoint = 0; circlePoint < radialSamples; circlePoint++)
-			{
-				indices[currentIndex++] =  (short) (bottomRowOffset + circlePoint +1);
-				indices[currentIndex++] = (short) (bottomRowOffset + circlePoint);
-				indices[currentIndex++] =  bottomCapIndex;
-
-				
-				indices[currentIndex++] = (short) (topRowOffset + circlePoint);
-				indices[currentIndex++] =  (short) (topRowOffset + circlePoint +1);
-				indices[currentIndex++] =  topCapIndex;
-			}
-		}
-
-		// If inverted, the triangles and normals are all reverted.
-		if (inverted)
-		{
-			for (int i = 0; i < indices.length / 2; i++)
-			{
-				short temp = indices[i];
-				indices[i] = indices[indices.length - 1 - i];
-				indices[indices.length - 1 - i] = temp;
-			}
-			
-			for(int i = 0; i< normals.length; i++)
-			{
-				normals[i] = -normals[i];
-			}
-		}
-		
-		// Fill in the buffers.
-		setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
-		setBuffer(Type.Normal, 3, BufferUtils.createFloatBuffer(normals));
-		setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(textureCoords));
+        currentIndex = 0;
+        for (short axisSample = 0; axisSample < axisSamples - 1; axisSample++) {
+            for (int circlePoint = 0; circlePoint < radialSamples; circlePoint++) {
+                indices[currentIndex++] = (short) (axisSample * (radialSamples + 1) + circlePoint);
+                indices[currentIndex++] =  (short) (axisSample * (radialSamples + 1) + circlePoint + 1);
+                indices[currentIndex++] =  (short) ((axisSample + 1) * (radialSamples + 1) + circlePoint);
+
+                indices[currentIndex++] =  (short) ((axisSample + 1) * (radialSamples + 1) + circlePoint);
+                indices[currentIndex++] =  (short) (axisSample * (radialSamples + 1) + circlePoint + 1);
+                indices[currentIndex++] =  (short) ((axisSample + 1) * (radialSamples + 1) + circlePoint + 1);
+            }
+        }
+        // Add caps if needed.
+        if(closed) {
+            short bottomCapIndex = (short) (verticesCount - 2);
+            short topCapIndex = (short) (verticesCount - 1);
+            
+            int bottomRowOffset = (axisSamples) * (radialSamples +1 );
+            int topRowOffset = (axisSamples+1) * (radialSamples +1 );
+            
+            for (int circlePoint = 0; circlePoint < radialSamples; circlePoint++) {
+                indices[currentIndex++] =  (short) (bottomRowOffset + circlePoint +1);
+                indices[currentIndex++] = (short) (bottomRowOffset + circlePoint);
+                indices[currentIndex++] =  bottomCapIndex;
+
+                
+                indices[currentIndex++] = (short) (topRowOffset + circlePoint);
+                indices[currentIndex++] =  (short) (topRowOffset + circlePoint +1);
+                indices[currentIndex++] =  topCapIndex;
+            }
+        }
+
+        // If inverted, the triangles and normals are all reverted.
+        if (inverted) {
+            for (int i = 0; i < indices.length / 2; i++) {
+                short temp = indices[i];
+                indices[i] = indices[indices.length - 1 - i];
+                indices[indices.length - 1 - i] = temp;
+            }
+            
+            for(int i = 0; i< normals.length; i++) {
+                normals[i] = -normals[i];
+            }
+        }
+        
+        // Fill in the buffers.
+        setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
+        setBuffer(Type.Normal, 3, BufferUtils.createFloatBuffer(normals));
+        setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(textureCoords));
         setBuffer(Type.Index, 3, BufferUtils.createShortBuffer(indices));
-		
+        
         updateBound();
         setStatic();
     }

+ 78 - 0
jme3-core/src/test/java/com/jme3/scene/ShapeGeometryTest.java

@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2009-2017 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.scene;
+
+import com.jme3.collision.CollisionResults;
+import com.jme3.math.FastMath;
+import com.jme3.math.Ray;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.shape.Cylinder;
+import java.util.Random;
+import org.junit.Test;
+
+/**
+ * Ensures that geometries behave correctly, by casting rays and ensure they don't break.
+ *
+ * @author Christophe Carpentier
+ */
+public class ShapeGeometryTest {
+
+    protected static final int NUMBER_OF_TRIES = 1000;
+    
+    @Test
+    public void testCylinders() {
+        Random random = new Random();
+        
+        // Create a cylinder, cast a random ray, and ensure everything goes well.
+        Node scene = new Node("Scene Node");
+
+        for (int i = 0; i < NUMBER_OF_TRIES; i++) {
+            scene.detachAllChildren();
+
+            Cylinder cylinder = new Cylinder(2, 8, 1, 1, true);
+            Geometry geometry = new Geometry("cylinder", cylinder);
+            geometry.rotate(FastMath.HALF_PI, 0, 0);
+            scene.attachChild(geometry);
+
+            // Cast a random ray, and count successes and IndexOutOfBoundsExceptions.
+            Vector3f randomPoint = new Vector3f(random.nextFloat(), random.nextFloat(), random.nextFloat());
+            Vector3f randomDirection = new Vector3f(random.nextFloat(), random.nextFloat(), random.nextFloat());
+            randomDirection.normalizeLocal();
+
+            Ray ray = new Ray(randomPoint, randomDirection);
+            CollisionResults collisionResults = new CollisionResults();
+
+            // If the geometry is invalid, this should throw various exceptions.
+            scene.collideWith(ray, collisionResults);
+        }
+    }
+}