private AbstractShape createComponent(int id, Vector3D pos) {
    MTEllipse comp = new MTEllipse(app, new Vector3D(pos), 50, 50, 50);
    comp.setNoFill(false);
    float r = ToolsMath.getRandom(20, 255);
    float g = ToolsMath.getRandom(20, 255);
    float b = ToolsMath.getRandom(20, 255);
    comp.setFillColor(new MTColor(r, g, b, 200));
    comp.setNoStroke(false);
    comp.setStrokeWeight(1);
    comp.setStrokeColor(new MTColor(r, g, b, 200));
    comp.unregisterAllInputProcessors(); // Dont process input/gestures on this component

    MTTextArea text = new MTTextArea(app, font);
    text.appendText(Integer.toString(id));
    text.setFillColor(new MTColor(0, 0, 0, 0));
    text.setStrokeColor(new MTColor(0, 0, 0, 0));
    text.unregisterAllInputProcessors();
    comp.addChild(text);
    text.setPositionRelativeToParent(comp.getCenterPointLocal());
    return comp;
  }
  /** builds the vertices based on the radius, center and radial and zSamples. */
  private void setGeometryData(PApplet pa) {
    // allocate vertices
    //        setVertexCount((zSamples - 2) * (radialSamples + 1) + 2);
    //        setVertexBuffer(ToolsBuffers.createVector3Buffer(vertBuff,
    //                getVertexCount()));

    int vertexCount = (zSamples - 2) * (radialSamples + 1) + 2;
    FloatBuffer vertexBuff = ToolsBuffers.createFloatBuffer(3 * vertexCount);

    // allocate normals if requested
    //        setNormalBuffer(ToolsBuffers.createVector3Buffer(normBuff,
    //                getVertexCount()));
    FloatBuffer normBuff = ToolsBuffers.createFloatBuffer(3 * vertexCount);

    // allocate texture coordinates
    //        setTextureCoords(new TexCoords(ToolsBuffers.createVector2Buffer(getVertexCount())));
    FloatBuffer texBuff = ToolsBuffers.createFloatBuffer(2 * vertexCount);

    // generate geometry
    float fInvRS = 1.0f / radialSamples;
    float fZFactor = 2.0f / (zSamples - 1);

    // Generate points on the unit circle to be used in computing the mesh
    // points on a sphere slice.
    float[] afSin = new float[(radialSamples + 1)];
    float[] afCos = new float[(radialSamples + 1)];
    for (int iR = 0; iR < radialSamples; iR++) {
      float fAngle = ToolsMath.TWO_PI * fInvRS * iR;
      afCos[iR] = ToolsMath.cos(fAngle);
      afSin[iR] = ToolsMath.sin(fAngle);
    }
    afSin[radialSamples] = afSin[0];
    afCos[radialSamples] = afCos[0];

    // generate the sphere itself
    int i = 0;
    for (int iZ = 1; iZ < (zSamples - 1); iZ++) {
      float fAFraction = ToolsMath.HALF_PI * (-1.0f + fZFactor * iZ); // in (-pi/2, pi/2)
      float fZFraction;
      if (useEvenSlices) fZFraction = -1.0f + fZFactor * iZ; // in (-1, 1)
      else fZFraction = ToolsMath.sin(fAFraction); // in (-1,1)

      float fZ = radius * fZFraction;

      // compute center of slice
      Vector3D kSliceCenter = tempVb.setValues(center);
      kSliceCenter.z += fZ;

      // compute radius of slice
      float fSliceRadius = ToolsMath.sqrt(ToolsMath.abs(radius * radius - fZ * fZ));

      // compute slice vertices with duplication at end point
      Vector3D kNormal;
      int iSave = i;
      for (int iR = 0; iR < radialSamples; iR++) {
        float fRadialFraction = iR * fInvRS; // in [0,1)
        tempVc.setXYZ(afCos[iR], afSin[iR], 0);
        Vector3D kRadial = tempVc;
        tempVa = kRadial.getScaled(fSliceRadius);

        vertexBuff
            .put(kSliceCenter.x + tempVa.x)
            .put(kSliceCenter.y + tempVa.y)
            .put(kSliceCenter.z + tempVa.z);

        ToolsBuffers.populateFromBuffer(tempVa, vertexBuff, i);
        kNormal = tempVa.subtractLocal(center);
        kNormal.normalizeLocal();
        if (true) // later we may allow interior texture vs. exterior
        normBuff.put(kNormal.x).put(kNormal.y).put(kNormal.z);
        else normBuff.put(-kNormal.x).put(-kNormal.y).put(-kNormal.z);

        if (textureMode == TextureMode.Original)
          texBuff.put(fRadialFraction).put(0.5f * (fZFraction + 1.0f));
        else if (textureMode == TextureMode.Projected)
          texBuff
              .put(fRadialFraction)
              .put(ToolsMath.INV_PI * (ToolsMath.HALF_PI + ToolsMath.asin(fZFraction)));
        else if (textureMode == TextureMode.Polar) {
          float r = (ToolsMath.HALF_PI - ToolsMath.abs(fAFraction)) / ToolsMath.PI;
          float u = r * afCos[iR] + 0.5f;
          float v = r * afSin[iR] + 0.5f;
          texBuff.put(u).put(v);
        }

        i++;
      }

      copyInternalVector3(vertexBuff, iSave, i);
      copyInternalVector3(normBuff, iSave, i);

      if (textureMode == TextureMode.Original) texBuff.put(1.0f).put(0.5f * (fZFraction + 1.0f));
      else if (textureMode == TextureMode.Projected)
        texBuff.put(1.0f).put(ToolsMath.INV_PI * (ToolsMath.HALF_PI + ToolsMath.asin(fZFraction)));
      else if (textureMode == TextureMode.Polar) {
        float r = (ToolsMath.HALF_PI - ToolsMath.abs(fAFraction)) / ToolsMath.PI;
        texBuff.put(r + 0.5f).put(0.5f);
      }

      i++;
    }

    // south pole
    vertexBuff.position(i * 3);
    vertexBuff.put(center.x).put(center.y).put(center.z - radius);

    normBuff.position(i * 3);
    if (true) normBuff.put(0).put(0).put(-1); // allow for inner
    // texture orientation
    // later.
    else normBuff.put(0).put(0).put(1);

    texBuff.position(i * 2);

    if (textureMode == TextureMode.Polar) {
      texBuff.put(0.5f).put(0.5f);
    } else {
      texBuff.put(0.5f).put(0.0f);
    }

    i++;

    // north pole
    vertexBuff.put(center.x).put(center.y).put(center.z + radius);

    if (true) normBuff.put(0).put(0).put(1);
    else normBuff.put(0).put(0).put(-1);

    if (textureMode == TextureMode.Polar) {
      texBuff.put(0.5f).put(0.5f);
    } else {
      texBuff.put(0.5f).put(1.0f);
    }

    Vertex[] verts = ToolsBuffers.getVertexArray(vertexBuff);
    Vector3D[] norms = ToolsBuffers.getVector3DArray(normBuff);

    // Set texcoords to vertices
    float[] tex = ToolsBuffers.getFloatArray(texBuff);
    for (int j = 0; j < tex.length / 2; j++) {
      float u = tex[j * 2];
      float v = tex[j * 2 + 1];
      verts[j].setTexCoordU(u);
      verts[j].setTexCoordV(v);
    }

    // get indices
    short[] indices = this.getIndexData();

    GeometryInfo geomInfo = new GeometryInfo(pa, verts, norms, indices);
    this.setGeometryInfo(geomInfo);
  }
Exemple #3
0
  public AirHockeyScene(AbstractMTApplication mtApplication, String name) {
    super(mtApplication, name);
    this.app = mtApplication;
    //		this.setClearColor(new MTColor(120,150,150));
    //		this.setClearColor(new MTColor(190, 190, 170, 255));
    this.setClearColor(new MTColor(0, 0, 0, 255));
    //		this.setClearColor(new MTColor(40, 40, 40, 255));
    this.registerGlobalInputProcessor(new CursorTracer(app, this));

    this.scorePlayer1 = 0;
    this.scorePlayer2 = 0;

    float worldOffset = 10; // Make Physics world slightly bigger than screen borders
    // Physics world dimensions
    AABB worldAABB =
        new AABB(
            new Vec2(-worldOffset, -worldOffset),
            new Vec2((app.width) / scale + worldOffset, (app.height) / scale + worldOffset));
    Vec2 gravity = new Vec2(0, 0);
    boolean sleep = true;
    // Create the pyhsics world
    this.world = new World(worldAABB, gravity, sleep);

    // Update the positions of the components according the the physics simulation each frame
    this.registerPreDrawAction(
        new UpdatePhysicsAction(world, timeStep, constraintIterations, scale));

    physicsContainer = new MTComponent(app);
    // Scale the physics container. Physics calculations work best when the dimensions are small
    // (about 0.1 - 10 units)
    // So we make the display of the container bigger and add in turn make our physics object
    // smaller
    physicsContainer.scale(scale, scale, 1, Vector3D.ZERO_VECTOR);
    this.getCanvas().addChild(physicsContainer);

    // Create borders around the screen
    this.createScreenBorders(physicsContainer);

    // Create gamefield marks
    MTLine line =
        new MTLine(
            mtApplication,
            mtApplication.width / 2f / scale,
            0,
            mtApplication.width / 2f / scale,
            mtApplication.height / scale);
    line.setPickable(false);
    //		line.setStrokeColor(new MTColor(0,0,0));
    line.setStrokeColor(new MTColor(150, 150, 150));
    line.setStrokeWeight(0.5f);
    physicsContainer.addChild(line);

    MTEllipse centerCircle =
        new MTEllipse(
            mtApplication,
            new Vector3D(mtApplication.width / 2f / scale, mtApplication.height / 2f / scale),
            80 / scale,
            80 / scale);
    centerCircle.setPickable(false);
    centerCircle.setNoFill(true);
    //		centerCircle.setStrokeColor(new MTColor(0,0,0));
    centerCircle.setStrokeColor(new MTColor(150, 150, 150));
    centerCircle.setStrokeWeight(0.5f);
    physicsContainer.addChild(centerCircle);

    MTEllipse centerCircleInner =
        new MTEllipse(
            mtApplication,
            new Vector3D(mtApplication.width / 2f / scale, mtApplication.height / 2f / scale),
            10 / scale,
            10 / scale);
    centerCircleInner.setPickable(false);
    centerCircleInner.setFillColor(new MTColor(160, 160, 160));
    //		centerCircleInner.setStrokeColor(new MTColor(150,150,150));
    //		centerCircleInner.setStrokeColor(new MTColor(0,0,0));
    centerCircleInner.setStrokeColor(new MTColor(150, 150, 150));
    centerCircleInner.setStrokeWeight(0.5f);
    physicsContainer.addChild(centerCircleInner);

    // Create the paddles
    PImage paddleTex = mtApplication.loadImage(imagesPath + "paddle.png");
    redCircle =
        new Paddle(
            app,
            new Vector3D(mtApplication.width - 60, mtApplication.height / 2f),
            50,
            world,
            1.0f,
            0.3f,
            0.4f,
            scale);
    redCircle.setTexture(paddleTex);
    redCircle.setFillColor(new MTColor(255, 50, 50));
    redCircle.setNoStroke(true);
    redCircle.setName("red");
    redCircle.setPickable(false);
    physicsContainer.addChild(redCircle);

    blueCircle =
        new Paddle(
            app, new Vector3D(80, mtApplication.height / 2f), 50, world, 1.0f, 0.3f, 0.4f, scale);
    blueCircle.setTexture(paddleTex);
    blueCircle.setFillColor(new MTColor(50, 50, 255));
    blueCircle.setNoStroke(true);
    blueCircle.setName("blue");
    blueCircle.setPickable(false);
    physicsContainer.addChild(blueCircle);

    // Create the ball
    ball =
        new HockeyBall(
            app,
            new Vector3D(mtApplication.width / 2f, mtApplication.height / 2f),
            38,
            world,
            0.5f,
            0.005f,
            0.70f,
            scale);
    //		MTColor ballCol = new MTColor(0,255,0);
    //		ball.setFillColor(ballCol);
    PImage ballTex = mtApplication.loadImage(imagesPath + "puk.png");
    ball.setTexture(ballTex);
    //		ball.setFillColor(new MTColor(160,160,160,255));
    ball.setFillColor(new MTColor(255, 255, 255, 255));
    ball.setNoStroke(true);
    ball.setName("ball");
    physicsContainer.addChild(ball);
    ball.getBody()
        .applyImpulse(
            new Vec2(ToolsMath.getRandom(-8f, 8), ToolsMath.getRandom(-8, 8)),
            ball.getBody().getWorldCenter());

    // Create the GOALS
    HockeyGoal goal1 =
        new HockeyGoal(
            new Vector3D(0, mtApplication.height / 2f),
            50,
            mtApplication.height / 4f,
            mtApplication,
            world,
            0.0f,
            0.1f,
            0.0f,
            scale);
    goal1.setName("goal1");
    goal1.setFillColor(new MTColor(0, 0, 255));
    goal1.setStrokeColor(new MTColor(0, 0, 255));
    physicsContainer.addChild(goal1);

    HockeyGoal goal2 =
        new HockeyGoal(
            new Vector3D(mtApplication.width, mtApplication.height / 2f),
            50,
            mtApplication.height / 4f,
            mtApplication,
            world,
            0.0f,
            0.1f,
            0.0f,
            scale);
    goal2.setName("goal2");
    goal2.setFillColor(new MTColor(255, 0, 0));
    goal2.setStrokeColor(new MTColor(255, 0, 0));
    physicsContainer.addChild(goal2);

    // Make two components for both game field sides to drag the puks upon
    MTRectangle leftSide =
        new MTRectangle(
            app,
            PhysicsHelper.scaleDown(0, scale),
            PhysicsHelper.scaleDown(0, scale),
            PhysicsHelper.scaleDown(app.width / 2f, scale),
            PhysicsHelper.scaleDown(app.height, scale));
    leftSide.setName("left side");
    leftSide.setNoFill(true); // Make it invisible -> only used for dragging
    leftSide.setNoStroke(true);
    leftSide.unregisterAllInputProcessors();
    leftSide.removeAllGestureEventListeners(DragProcessor.class);
    leftSide.registerInputProcessor(new DragProcessor(app));
    leftSide.addGestureListener(DragProcessor.class, new GameFieldHalfDragListener(blueCircle));
    physicsContainer.addChild(0, leftSide);
    MTRectangle rightSide =
        new MTRectangle(
            app,
            PhysicsHelper.scaleDown(app.width / 2f, scale),
            PhysicsHelper.scaleDown(0, scale),
            PhysicsHelper.scaleDown(app.width, scale),
            PhysicsHelper.scaleDown(app.height, scale));
    rightSide.setName("right Side");
    rightSide.setNoFill(true); // Make it invisible -> only used for dragging
    rightSide.setNoStroke(true);
    rightSide.unregisterAllInputProcessors();
    rightSide.removeAllGestureEventListeners(DragProcessor.class);
    rightSide.registerInputProcessor(new DragProcessor(app));
    rightSide.addGestureListener(DragProcessor.class, new GameFieldHalfDragListener(redCircle));
    physicsContainer.addChild(0, rightSide);

    // Display Score UI
    MTComponent uiLayer = new MTComponent(mtApplication, new MTCamera(mtApplication));
    uiLayer.setDepthBufferDisabled(true);
    getCanvas().addChild(uiLayer);
    IFont font = FontManager.getInstance().createFont(mtApplication, "arial", 50, MTColor.WHITE);

    t1 = new MTTextArea(mtApplication, font);
    t1.setPickable(false);
    t1.setNoFill(true);
    t1.setNoStroke(true);
    t1.setPositionGlobal(new Vector3D(5, 30, 0));
    uiLayer.addChild(t1);

    t2 = new MTTextArea(mtApplication, font);
    t2.setPickable(false);
    t2.setNoFill(true);
    t2.setNoStroke(true);
    t2.setPositionGlobal(new Vector3D(mtApplication.width - 65, 30, 0));
    uiLayer.addChild(t2);
    this.updateScores();

    // Set up check for collisions between objects
    this.addWorldContactListener(world);

    /*
    		//Sound
    		if (enableSound){
    			minim = new Minim(mtApplication);
    			wallHit = minim.loadSnippet(MT4jSettings.getInstance().getDataFolderPath() + "sound" + File.separator + "paddleBallHit.wav");
    //			paddleBallClash = minim.loadSample(MT4jSettings.getInstance().getDataFolderPath() + "sound" + File.separator + "paddleBallHit.wav", 2048);
    //			goalHit = minim.loadSnippet(MT4jSettings.getInstance().getDataFolderPath() + "sound" + File.separator + "goal.wav");
    //			goalHit.play();
    			paddleHit = minim.loadSnippet(MT4jSettings.getInstance().getDataFolderPath() + "sound" + File.separator + "wallHit.wav");
    		}
    		*/
  }
  /** Private method, handle a new fiducial */
  private void started() {
    AbstractShape roundingcircle =
        new MTEllipse(app, new Vector3D(event.getPosition()), 180, 180, 100);
    roundingcircle.setNoFill(false);
    float r = ToolsMath.getRandom(20, 255);
    float g = ToolsMath.getRandom(20, 255);
    float b = ToolsMath.getRandom(20, 255);
    roundingcircle.setFillColor(new MTColor(r, g, b, 200));
    roundingcircle.setNoStroke(false);
    roundingcircle.setStrokeWeight(1);
    roundingcircle.setStrokeColor(new MTColor(r, g, b, 200));
    roundingcircle.unregisterAllInputProcessors();

    AbstractShape component = new MTEllipse(app, new Vector3D(event.getPosition()), 20, 20, 20);
    component.setNoFill(false);
    float r1 = ToolsMath.getRandom(20, 255);
    float g1 = ToolsMath.getRandom(20, 255);
    float b1 = ToolsMath.getRandom(20, 255);
    component.setFillColor(new MTColor(r1, g1, b1, 200));
    component.setNoStroke(false);
    component.setStrokeWeight(1);
    component.setStrokeColor(new MTColor(r1, g1, b1, 200));
    component.unregisterAllInputProcessors(); // Dont process input/gestures on this component

    roundingcircle.addChild(component);

    MTColor white = new MTColor(255, 255, 255);

    IFont fontArial = FontManager.getInstance().createFont(app, "arial.ttf", 50, white);

    MTTextArea text = new MTTextArea(app, fontArial);
    text.setFillColor(new MTColor(0, 0, 0, 0));
    text.setStrokeColor(new MTColor(0, 0, 0, 0));
    text.unregisterAllInputProcessors();
    roundingcircle.addChild(text);
    text.setPositionRelativeToParent(
        new Vector3D(event.getPosition().x, event.getPosition().y - 120));

    roundingcircle.setUserData("angle", event.getAngle());

    MTKeyboard keys = KeyboardPool.getInstance(app).getKeyboard();
    roundingcircle.addChild(keys);
    keys.setPositionRelativeToParent(
        new Vector3D(event.getPosition().x, event.getPosition().y + 150));
    keys.setUserData("fiducialID", EventID);

    text.setExpandDirection(ExpandDirection.UP);
    text.unregisterAllInputProcessors();
    /*
     * Need to find a way to keep the text centred at all times.
     */
    // text.setEnableCaret(true);

    keys.addTextInputListener(text);
    keys.addInputListener(text);

    FiducialRegistry.getInstance().putFiducialCompoent(EventID, roundingcircle);

    String searchTerm = "Doctor Who";
    TwitterSearch twsearch = new TwitterSearch();
    twsearch.search(searchTerm);

    canvas.addChild(roundingcircle);
  }