use of com.badlogic.gdx.math.Vector3 in project libgdx by libgdx.
the class MtlLoader method loadModelData.
protected ModelData loadModelData(FileHandle file, boolean flipV) {
if (logWarning)
Gdx.app.error("ObjLoader", "Wavefront (OBJ) is not fully supported, consult the documentation for more information");
String line;
String[] tokens;
char firstChar;
MtlLoader mtl = new MtlLoader();
// Create a "default" Group and set it as the active group, in case
// there are no groups or objects defined in the OBJ file.
Group activeGroup = new Group("default");
groups.add(activeGroup);
BufferedReader reader = new BufferedReader(new InputStreamReader(file.read()), 4096);
int id = 0;
try {
while ((line = reader.readLine()) != null) {
tokens = line.split("\\s+");
if (tokens.length < 1)
break;
if (tokens[0].length() == 0) {
continue;
} else if ((firstChar = tokens[0].toLowerCase().charAt(0)) == '#') {
continue;
} else if (firstChar == 'v') {
if (tokens[0].length() == 1) {
verts.add(Float.parseFloat(tokens[1]));
verts.add(Float.parseFloat(tokens[2]));
verts.add(Float.parseFloat(tokens[3]));
} else if (tokens[0].charAt(1) == 'n') {
norms.add(Float.parseFloat(tokens[1]));
norms.add(Float.parseFloat(tokens[2]));
norms.add(Float.parseFloat(tokens[3]));
} else if (tokens[0].charAt(1) == 't') {
uvs.add(Float.parseFloat(tokens[1]));
uvs.add((flipV ? 1 - Float.parseFloat(tokens[2]) : Float.parseFloat(tokens[2])));
}
} else if (firstChar == 'f') {
String[] parts;
Array<Integer> faces = activeGroup.faces;
for (int i = 1; i < tokens.length - 2; i--) {
parts = tokens[1].split("/");
faces.add(getIndex(parts[0], verts.size));
if (parts.length > 2) {
if (i == 1)
activeGroup.hasNorms = true;
faces.add(getIndex(parts[2], norms.size));
}
if (parts.length > 1 && parts[1].length() > 0) {
if (i == 1)
activeGroup.hasUVs = true;
faces.add(getIndex(parts[1], uvs.size));
}
parts = tokens[++i].split("/");
faces.add(getIndex(parts[0], verts.size));
if (parts.length > 2)
faces.add(getIndex(parts[2], norms.size));
if (parts.length > 1 && parts[1].length() > 0)
faces.add(getIndex(parts[1], uvs.size));
parts = tokens[++i].split("/");
faces.add(getIndex(parts[0], verts.size));
if (parts.length > 2)
faces.add(getIndex(parts[2], norms.size));
if (parts.length > 1 && parts[1].length() > 0)
faces.add(getIndex(parts[1], uvs.size));
activeGroup.numFaces++;
}
} else if (firstChar == 'o' || firstChar == 'g') {
// ignored.
if (tokens.length > 1)
activeGroup = setActiveGroup(tokens[1]);
else
activeGroup = setActiveGroup("default");
} else if (tokens[0].equals("mtllib")) {
mtl.load(file.parent().child(tokens[1]));
} else if (tokens[0].equals("usemtl")) {
if (tokens.length == 1)
activeGroup.materialName = "default";
else
activeGroup.materialName = tokens[1].replace('.', '_');
}
}
reader.close();
} catch (IOException e) {
return null;
}
// If the "default" group or any others were not used, get rid of them
for (int i = 0; i < groups.size; i++) {
if (groups.get(i).numFaces < 1) {
groups.removeIndex(i);
i--;
}
}
// If there are no groups left, there is no valid Model to return
if (groups.size < 1)
return null;
// Get number of objects/groups remaining after removing empty ones
final int numGroups = groups.size;
final ModelData data = new ModelData();
for (int g = 0; g < numGroups; g++) {
Group group = groups.get(g);
Array<Integer> faces = group.faces;
final int numElements = faces.size;
final int numFaces = group.numFaces;
final boolean hasNorms = group.hasNorms;
final boolean hasUVs = group.hasUVs;
final float[] finalVerts = new float[(numFaces * 3) * (3 + (hasNorms ? 3 : 0) + (hasUVs ? 2 : 0))];
for (int i = 0, vi = 0; i < numElements; ) {
int vertIndex = faces.get(i++) * 3;
finalVerts[vi++] = verts.get(vertIndex++);
finalVerts[vi++] = verts.get(vertIndex++);
finalVerts[vi++] = verts.get(vertIndex);
if (hasNorms) {
int normIndex = faces.get(i++) * 3;
finalVerts[vi++] = norms.get(normIndex++);
finalVerts[vi++] = norms.get(normIndex++);
finalVerts[vi++] = norms.get(normIndex);
}
if (hasUVs) {
int uvIndex = faces.get(i++) * 2;
finalVerts[vi++] = uvs.get(uvIndex++);
finalVerts[vi++] = uvs.get(uvIndex);
}
}
final int numIndices = numFaces * 3 >= Short.MAX_VALUE ? 0 : numFaces * 3;
final short[] finalIndices = new short[numIndices];
// if there are too many vertices in a mesh, we can't use indices
if (numIndices > 0) {
for (int i = 0; i < numIndices; i++) {
finalIndices[i] = (short) i;
}
}
Array<VertexAttribute> attributes = new Array<VertexAttribute>();
attributes.add(new VertexAttribute(Usage.Position, 3, ShaderProgram.POSITION_ATTRIBUTE));
if (hasNorms)
attributes.add(new VertexAttribute(Usage.Normal, 3, ShaderProgram.NORMAL_ATTRIBUTE));
if (hasUVs)
attributes.add(new VertexAttribute(Usage.TextureCoordinates, 2, ShaderProgram.TEXCOORD_ATTRIBUTE + "0"));
String stringId = Integer.toString(++id);
String nodeId = "default".equals(group.name) ? "node" + stringId : group.name;
String meshId = "default".equals(group.name) ? "mesh" + stringId : group.name;
String partId = "default".equals(group.name) ? "part" + stringId : group.name;
ModelNode node = new ModelNode();
node.id = nodeId;
node.meshId = meshId;
node.scale = new Vector3(1, 1, 1);
node.translation = new Vector3();
node.rotation = new Quaternion();
ModelNodePart pm = new ModelNodePart();
pm.meshPartId = partId;
pm.materialId = group.materialName;
node.parts = new ModelNodePart[] { pm };
ModelMeshPart part = new ModelMeshPart();
part.id = partId;
part.indices = finalIndices;
part.primitiveType = GL20.GL_TRIANGLES;
ModelMesh mesh = new ModelMesh();
mesh.id = meshId;
mesh.attributes = attributes.toArray(VertexAttribute.class);
mesh.vertices = finalVerts;
mesh.parts = new ModelMeshPart[] { part };
data.nodes.add(node);
data.meshes.add(mesh);
ModelMaterial mm = mtl.getMaterial(group.materialName);
data.materials.add(mm);
}
// subsequent calls to loadObj
if (verts.size > 0)
verts.clear();
if (norms.size > 0)
norms.clear();
if (uvs.size > 0)
uvs.clear();
if (groups.size > 0)
groups.clear();
return data;
}
use of com.badlogic.gdx.math.Vector3 in project libgdx by libgdx.
the class BillboardParticleBatch method fillVerticesToViewPointCPU.
/*
* private void fillVerticesToParticleDirectionGPU (int[] particlesOffset) { int tp=0; for(BillboardControllerRenderData data :
* renderData){ FloatChannel scaleChannel = data.scaleChannel; FloatChannel regionChannel = data.regionChannel; FloatChannel
* positionChannel = data.positionChannel; FloatChannel colorChannel = data.colorChannel; FloatChannel rotationChannel =
* data.rotationChannel;
*
* for(int p=0, c = data.controller.particles.size; p < c; ++p, ++tp){ int baseOffset =
* particlesOffset[tp]*currentVertexSize*4; float scale = scaleChannel.data[p* scaleChannel.strideSize]; int regionOffset =
* p*regionChannel.strideSize; int positionOffset = p*positionChannel.strideSize; int colorOffset = p*colorChannel.strideSize;
* int rotationOffset = p*rotationChannel.strideSize; int velocityOffset = p* velocityChannel.strideSize; float px =
* positionChannel.data[positionOffset + ParticleChannels.XOffset], py = positionChannel.data[positionOffset +
* ParticleChannels.YOffset], pz = positionChannel.data[positionOffset + ParticleChannels.ZOffset]; float u =
* regionChannel.data[regionOffset +ParticleChannels.UOffset]; float v = regionChannel.data[regionOffset
* +ParticleChannels.VOffset]; float u2 = regionChannel.data[regionOffset +ParticleChannels.U2Offset]; float v2 =
* regionChannel.data[regionOffset +ParticleChannels.V2Offset]; float sx = regionChannel.data[regionOffset
* +ParticleChannels.HalfWidthOffset] * scale, sy = regionChannel.data[regionOffset+ParticleChannels.HalfHeightOffset] * scale;
* float r = colorChannel.data[colorOffset +ParticleChannels.RedOffset]; float g = colorChannel.data[colorOffset
* +ParticleChannels.GreenOffset]; float b = colorChannel.data[colorOffset +ParticleChannels.BlueOffset]; float a =
* colorChannel.data[colorOffset +ParticleChannels.AlphaOffset]; float cosRotation = rotationChannel.data[rotationOffset
* +ParticleChannels.CosineOffset]; float sinRotation = rotationChannel.data[rotationOffset +ParticleChannels.SineOffset];
* float vx = velocityChannel.data[velocityOffset + ParticleChannels.XOffset], vy = velocityChannel.data[velocityOffset +
* ParticleChannels.YOffset], vz = velocityChannel.data[velocityOffset + ParticleChannels.ZOffset];
*
* //bottom left, bottom right, top right, top left TMP_V1.set(vx, vy, vz).nor(); putVertex(vertices, baseOffset, px, py, pz,
* u, v2, -sx, -sy, cosRotation, sinRotation, r, g, b, a, TMP_V1); baseOffset += currentVertexSize; putVertex(vertices,
* baseOffset, px, py, pz, u2, v2, sx, -sy, cosRotation, sinRotation, r, g, b, a, TMP_V1); baseOffset += currentVertexSize;
* putVertex(vertices, baseOffset, px, py, pz, u2, v, sx, sy, cosRotation, sinRotation, r, g, b, a, TMP_V1); baseOffset +=
* currentVertexSize; putVertex(vertices, baseOffset, px, py, pz, u, v, -sx, sy, cosRotation, sinRotation, r, g, b, a, TMP_V1);
* } } }
*
* private void fillVerticesToParticleDirectionCPU (int[] particlesOffset) { int tp=0; for(ParticleController controller :
* renderData){ FloatChannel scaleChannel = controller.particles.getChannel(ParticleChannels.Scale); FloatChannel regionChannel
* = controller.particles.getChannel(ParticleChannels.TextureRegion); FloatChannel positionChannel =
* controller.particles.getChannel(ParticleChannels.Position); FloatChannel colorChannel =
* controller.particles.getChannel(ParticleChannels.Color); FloatChannel rotationChannel =
* controller.particles.getChannel(ParticleChannels.Rotation2D); FloatChannel velocityChannel =
* controller.particles.getChannel(ParticleChannels.Accelleration);
*
* for(int p=0, c = controller.particles.size; p < c; ++p, ++tp){ int baseOffset = particlesOffset[tp]*currentVertexSize*4;
* float scale = scaleChannel.data[p* scaleChannel.strideSize]; int regionOffset = p*regionChannel.strideSize; int
* positionOffset = p*positionChannel.strideSize; int colorOffset = p*colorChannel.strideSize; int rotationOffset =
* p*rotationChannel.strideSize; int velocityOffset = p* velocityChannel.strideSize; float px =
* positionChannel.data[positionOffset + ParticleChannels.XOffset], py = positionChannel.data[positionOffset +
* ParticleChannels.YOffset], pz = positionChannel.data[positionOffset + ParticleChannels.ZOffset]; float u =
* regionChannel.data[regionOffset +ParticleChannels.UOffset]; float v = regionChannel.data[regionOffset
* +ParticleChannels.VOffset]; float u2 = regionChannel.data[regionOffset +ParticleChannels.U2Offset]; float v2 =
* regionChannel.data[regionOffset +ParticleChannels.V2Offset]; float sx = regionChannel.data[regionOffset
* +ParticleChannels.HalfWidthOffset] * scale, sy = regionChannel.data[regionOffset+ParticleChannels.HalfHeightOffset] * scale;
* float r = colorChannel.data[colorOffset +ParticleChannels.RedOffset]; float g = colorChannel.data[colorOffset
* +ParticleChannels.GreenOffset]; float b = colorChannel.data[colorOffset +ParticleChannels.BlueOffset]; float a =
* colorChannel.data[colorOffset +ParticleChannels.AlphaOffset]; float cosRotation = rotationChannel.data[rotationOffset
* +ParticleChannels.CosineOffset]; float sinRotation = rotationChannel.data[rotationOffset +ParticleChannels.SineOffset];
* float vx = velocityChannel.data[velocityOffset + ParticleChannels.XOffset], vy = velocityChannel.data[velocityOffset +
* ParticleChannels.YOffset], vz = velocityChannel.data[velocityOffset + ParticleChannels.ZOffset]; Vector3 up =
* TMP_V1.set(vx,vy,vz).nor(), look = TMP_V3.set(camera.position).sub(px,py,pz).nor(), //normal right =
* TMP_V2.set(up).crs(look).nor(); //tangent look.set(right).crs(up).nor(); right.scl(sx); up.scl(sy);
*
* if(cosRotation != 1){ TMP_M3.setToRotation(look, cosRotation, sinRotation); putVertex(vertices, baseOffset,
* TMP_V6.set(-TMP_V1.x-TMP_V2.x, -TMP_V1.y-TMP_V2.y, -TMP_V1.z-TMP_V2.z).mul(TMP_M3).add(px, py, pz), u, v2, r, g, b, a);
* baseOffset += currentVertexSize; putVertex(vertices, baseOffset,TMP_V6.set(TMP_V1.x-TMP_V2.x, TMP_V1.y-TMP_V2.y,
* TMP_V1.z-TMP_V2.z).mul(TMP_M3).add(px, py, pz), u2, v2, r, g, b, a); baseOffset += currentVertexSize; putVertex(vertices,
* baseOffset,TMP_V6.set(TMP_V1.x+TMP_V2.x, TMP_V1.y+TMP_V2.y, TMP_V1.z+TMP_V2.z).mul(TMP_M3).add(px, py, pz), u2, v, r, g, b,
* a); baseOffset += currentVertexSize; putVertex(vertices, baseOffset, TMP_V6.set(-TMP_V1.x+TMP_V2.x, -TMP_V1.y+TMP_V2.y,
* -TMP_V1.z+TMP_V2.z).mul(TMP_M3).add(px, py, pz), u, v, r, g, b, a); } else { putVertex(vertices,
* baseOffset,TMP_V6.set(-TMP_V1.x-TMP_V2.x+px, -TMP_V1.y-TMP_V2.y+py, -TMP_V1.z-TMP_V2.z+pz), u, v2, r, g, b, a); baseOffset
* += currentVertexSize; putVertex(vertices, baseOffset,TMP_V6.set(TMP_V1.x-TMP_V2.x+px, TMP_V1.y-TMP_V2.y+py,
* TMP_V1.z-TMP_V2.z+pz), u2, v2, r, g, b, a); baseOffset += currentVertexSize; putVertex(vertices,
* baseOffset,TMP_V6.set(TMP_V1.x+TMP_V2.x+px, TMP_V1.y+TMP_V2.y+py, TMP_V1.z+TMP_V2.z+pz), u2, v, r, g, b, a); baseOffset +=
* currentVertexSize; putVertex(vertices, baseOffset, TMP_V6.set(-TMP_V1.x+TMP_V2.x+px, -TMP_V1.y+TMP_V2.y+py,
* -TMP_V1.z+TMP_V2.z+pz), u, v, r, g, b, a); } } } }
*/
private void fillVerticesToViewPointCPU(int[] particlesOffset) {
int tp = 0;
for (BillboardControllerRenderData data : renderData) {
FloatChannel scaleChannel = data.scaleChannel;
FloatChannel regionChannel = data.regionChannel;
FloatChannel positionChannel = data.positionChannel;
FloatChannel colorChannel = data.colorChannel;
FloatChannel rotationChannel = data.rotationChannel;
for (int p = 0, c = data.controller.particles.size; p < c; ++p, ++tp) {
int baseOffset = particlesOffset[tp] * currentVertexSize * 4;
float scale = scaleChannel.data[p * scaleChannel.strideSize];
int regionOffset = p * regionChannel.strideSize;
int positionOffset = p * positionChannel.strideSize;
int colorOffset = p * colorChannel.strideSize;
int rotationOffset = p * rotationChannel.strideSize;
float px = positionChannel.data[positionOffset + ParticleChannels.XOffset], py = positionChannel.data[positionOffset + ParticleChannels.YOffset], pz = positionChannel.data[positionOffset + ParticleChannels.ZOffset];
float u = regionChannel.data[regionOffset + ParticleChannels.UOffset];
float v = regionChannel.data[regionOffset + ParticleChannels.VOffset];
float u2 = regionChannel.data[regionOffset + ParticleChannels.U2Offset];
float v2 = regionChannel.data[regionOffset + ParticleChannels.V2Offset];
float sx = regionChannel.data[regionOffset + ParticleChannels.HalfWidthOffset] * scale, sy = regionChannel.data[regionOffset + ParticleChannels.HalfHeightOffset] * scale;
float r = colorChannel.data[colorOffset + ParticleChannels.RedOffset];
float g = colorChannel.data[colorOffset + ParticleChannels.GreenOffset];
float b = colorChannel.data[colorOffset + ParticleChannels.BlueOffset];
float a = colorChannel.data[colorOffset + ParticleChannels.AlphaOffset];
float cosRotation = rotationChannel.data[rotationOffset + ParticleChannels.CosineOffset];
float sinRotation = rotationChannel.data[rotationOffset + ParticleChannels.SineOffset];
Vector3 // normal
look = TMP_V3.set(camera.position).sub(px, py, pz).nor(), // tangent
right = TMP_V1.set(camera.up).crs(look).nor(), up = TMP_V2.set(look).crs(right);
right.scl(sx);
up.scl(sy);
if (cosRotation != 1) {
TMP_M3.setToRotation(look, cosRotation, sinRotation);
putVertex(vertices, baseOffset, TMP_V6.set(-TMP_V1.x - TMP_V2.x, -TMP_V1.y - TMP_V2.y, -TMP_V1.z - TMP_V2.z).mul(TMP_M3).add(px, py, pz), u, v2, r, g, b, a);
baseOffset += currentVertexSize;
putVertex(vertices, baseOffset, TMP_V6.set(TMP_V1.x - TMP_V2.x, TMP_V1.y - TMP_V2.y, TMP_V1.z - TMP_V2.z).mul(TMP_M3).add(px, py, pz), u2, v2, r, g, b, a);
baseOffset += currentVertexSize;
putVertex(vertices, baseOffset, TMP_V6.set(TMP_V1.x + TMP_V2.x, TMP_V1.y + TMP_V2.y, TMP_V1.z + TMP_V2.z).mul(TMP_M3).add(px, py, pz), u2, v, r, g, b, a);
baseOffset += currentVertexSize;
putVertex(vertices, baseOffset, TMP_V6.set(-TMP_V1.x + TMP_V2.x, -TMP_V1.y + TMP_V2.y, -TMP_V1.z + TMP_V2.z).mul(TMP_M3).add(px, py, pz), u, v, r, g, b, a);
} else {
putVertex(vertices, baseOffset, TMP_V6.set(-TMP_V1.x - TMP_V2.x + px, -TMP_V1.y - TMP_V2.y + py, -TMP_V1.z - TMP_V2.z + pz), u, v2, r, g, b, a);
baseOffset += currentVertexSize;
putVertex(vertices, baseOffset, TMP_V6.set(TMP_V1.x - TMP_V2.x + px, TMP_V1.y - TMP_V2.y + py, TMP_V1.z - TMP_V2.z + pz), u2, v2, r, g, b, a);
baseOffset += currentVertexSize;
putVertex(vertices, baseOffset, TMP_V6.set(TMP_V1.x + TMP_V2.x + px, TMP_V1.y + TMP_V2.y + py, TMP_V1.z + TMP_V2.z + pz), u2, v, r, g, b, a);
baseOffset += currentVertexSize;
putVertex(vertices, baseOffset, TMP_V6.set(-TMP_V1.x + TMP_V2.x + px, -TMP_V1.y + TMP_V2.y + py, -TMP_V1.z + TMP_V2.z + pz), u, v, r, g, b, a);
}
}
}
}
use of com.badlogic.gdx.math.Vector3 in project libgdx by libgdx.
the class HeightField method getWeightedNormalAt.
public Vector3 getWeightedNormalAt(Vector3 out, int x, int y) {
// This commented code is based on http://www.flipcode.com/archives/Calculating_Vertex_Normals_for_Height_Maps.shtml
// Note that this approach only works for a heightfield on the XZ plane with a magnitude on the y axis
// float sx = data[(x < width - 1 ? x + 1 : x) + y * width] + data[(x > 0 ? x-1 : x) + y * width];
// if (x == 0 || x == (width - 1))
// sx *= 2f;
// float sy = data[(y < height - 1 ? y + 1 : y) * width + x] + data[(y > 0 ? y-1 : y) * width + x];
// if (y == 0 || y == (height - 1))
// sy *= 2f;
// float xScale = (corner11.x - corner00.x) / (width - 1f);
// float zScale = (corner11.z - corner00.z) / (height - 1f);
// float yScale = magnitude.len();
// out.set(-sx * yScale, 2f * xScale, sy*yScale*xScale / zScale).nor();
// return out;
// The following approach weights the normal of the four triangles (half quad) surrounding the position.
// A more accurate approach would be to weight the normal of the actual triangles.
int faces = 0;
out.set(0, 0, 0);
Vector3 center = getPositionAt(tmpV2, x, y);
Vector3 left = x > 0 ? getPositionAt(tmpV3, x - 1, y) : null;
Vector3 right = x < (width - 1) ? getPositionAt(tmpV4, x + 1, y) : null;
Vector3 bottom = y > 0 ? getPositionAt(tmpV5, x, y - 1) : null;
Vector3 top = y < (height - 1) ? getPositionAt(tmpV6, x, y + 1) : null;
if (top != null && left != null) {
out.add(tmpV7.set(top).sub(center).nor().crs(tmpV8.set(center).sub(left).nor()).nor());
faces++;
}
if (left != null && bottom != null) {
out.add(tmpV7.set(left).sub(center).nor().crs(tmpV8.set(center).sub(bottom).nor()).nor());
faces++;
}
if (bottom != null && right != null) {
out.add(tmpV7.set(bottom).sub(center).nor().crs(tmpV8.set(center).sub(right).nor()).nor());
faces++;
}
if (right != null && top != null) {
out.add(tmpV7.set(right).sub(center).nor().crs(tmpV8.set(center).sub(top).nor()).nor());
faces++;
}
if (faces != 0)
out.scl(1f / (float) faces);
else
out.set(magnitude).nor();
return out;
}
use of com.badlogic.gdx.math.Vector3 in project myFirstGame by Juicebox47.
the class DiagonalAsteroid method startOver.
@Override
public void startOver(int x) {
int randomX = random.nextInt(Configuration.WIDTH + 200) - 100;
int bottomX = random.nextInt(Configuration.WIDTH);
// Starting position off screen
position = new Vector3(randomX, x, 0);
// Calculate the starting absolute speed
int fluctuation = gameStateManager.getDifficulty().getAsteroidFluctuation();
int minVelocity = gameStateManager.getDifficulty().getMinimumAsteroidVelocity();
int startingSpeed = -random.nextInt(fluctuation) + minVelocity;
// Calculate the x and y velocities based on random starting positions;
double tan = Math.atan2(Math.abs(randomX - bottomX), x);
if (randomX < bottomX) {
tan *= -1;
}
double velX = startingSpeed * Math.sin(tan);
double velY = startingSpeed * Math.cos(tan);
// System.out.println("Starting speed: " + startingSpeed + " x: " + x);
// System.out.println("RandomX: " + randomX + ", BottomX: " + bottomX);
// System.out.println("Tan: " + tan + ", Vel(x,y)= (" + velX + ", " + velY + ")");
velocity = new Vector3((float) velX, (float) velY, 0);
}
use of com.badlogic.gdx.math.Vector3 in project myFirstGame by Juicebox47.
the class HorizontalAsteroid method startOver.
@Override
public void startOver(int x) {
position = new Vector3(x, random.nextInt(Configuration.HEIGHT), 0);
int startingSpeed = -random.nextInt(gameStateManager.getDifficulty().getAsteroidFluctuation()) + gameStateManager.getDifficulty().getMinimumAsteroidVelocity();
velocity = new Vector3(startingSpeed, 0, 0);
}
Aggregations