public static TriangleData processTriangle(int[] index, Vector3f[] v, Vector2f[] t) {
    Vector3f edge1 = new Vector3f();
    Vector3f edge2 = new Vector3f();
    Vector2f edge1uv = new Vector2f();
    Vector2f edge2uv = new Vector2f();

    Vector3f tangent = new Vector3f();
    Vector3f binormal = new Vector3f();
    Vector3f normal = new Vector3f();

    t[1].subtract(t[0], edge1uv);
    t[2].subtract(t[0], edge2uv);
    float det = edge1uv.x * edge2uv.y - edge1uv.y * edge2uv.x;

    boolean normalize = false;
    if (Math.abs(det) < ZERO_TOLERANCE) {
      //			log.log(Level.WARNING, "Colinear uv coordinates for triangle " + "[{0}, {1}, {2}]; tex0 =
      // [{3}, {4}], " + "tex1 = [{5}, {6}], tex2 = [{7}, {8}]",
      //					new Object[] { index[0], index[1], index[2], t[0].x, t[0].y, t[1].x, t[1].y, t[2].x,
      // t[2].y });
      det = 1;
      normalize = true;
    }

    v[1].subtract(v[0], edge1);
    v[2].subtract(v[0], edge2);

    tangent.set(edge1);
    tangent.normalizeLocal();
    binormal.set(edge2);
    binormal.normalizeLocal();

    if (Math.abs(Math.abs(tangent.dot(binormal)) - 1) < ZERO_TOLERANCE) {
      //			log.log(Level.WARNING, "Vertices are on the same line " + "for triangle [{0}, {1},
      // {2}].", new Object[] { index[0], index[1], index[2] });
    }

    float factor = 1 / det;
    tangent.x = (edge2uv.y * edge1.x - edge1uv.y * edge2.x) * factor;
    tangent.y = (edge2uv.y * edge1.y - edge1uv.y * edge2.y) * factor;
    tangent.z = (edge2uv.y * edge1.z - edge1uv.y * edge2.z) * factor;
    if (normalize) {
      tangent.normalizeLocal();
    }

    binormal.x = (edge1uv.x * edge2.x - edge2uv.x * edge1.x) * factor;
    binormal.y = (edge1uv.x * edge2.y - edge2uv.x * edge1.y) * factor;
    binormal.z = (edge1uv.x * edge2.z - edge2uv.x * edge1.z) * factor;
    if (normalize) {
      binormal.normalizeLocal();
    }

    tangent.cross(binormal, normal);
    normal.normalizeLocal();

    return new TriangleData(tangent, binormal, normal);
  }
  public EffectCenter(Simulator sim) {
    this.sim = sim;
    AssetManager assetManager = sim.getAssetManager();

    WeatherSettings weatherSettings =
        Simulator.getDrivingTask().getScenarioLoader().getWeatherSettings();
    snowingPercentage =
        Math.max(
            weatherSettings.getSnowingPercentage(),
            -1); // use -1 to suppress construction of SnowParticleEmitter
    rainingPercentage =
        Math.max(
            weatherSettings.getRainingPercentage(),
            -1); // use -1 to suppress construction of RainParticleEmitter
    fogPercentage =
        Math.max(
            weatherSettings.getFogPercentage(), -1); // use -1 to suppress construction of FogFilter
    isSnowing = (snowingPercentage >= 0);
    isRaining = (rainingPercentage >= 0);
    isFog = (fogPercentage >= 0);
    isBloom = !Simulator.oculusRiftAttached; // switch off bloom filter when Oculus Rift is used
    isShadow = true;

    if (isSnowing) {
      // init snow
      snowParticleEmitter = new SnowParticleEmitter(assetManager, snowingPercentage);
      sim.getSceneNode().attachChild(snowParticleEmitter);
    }

    if (isRaining) {
      // init rain
      rainParticleEmitter = new RainParticleEmitter(assetManager, rainingPercentage);
      sim.getSceneNode().attachChild(rainParticleEmitter);
    }

    if (isFog || isBloom) {
      for (ViewPort viewPort : CameraFactory.getViewPortList()) {
        FilterPostProcessor processor = new FilterPostProcessor(assetManager);

        int numSamples = sim.getContext().getSettings().getSamples();
        if (numSamples > 0) processor.setNumSamples(numSamples);

        if (isFog) {
          FogFilter fogFilter = new FogFilter();
          fogFilter.setFogColor(new ColorRGBA(0.9f, 0.9f, 0.9f, 1.0f));
          fogFilter.setFogDistance(155);
          fogFilter.setFogDensity(2.0f * (fogPercentage / 100f));
          fogFilterList.add(fogFilter);
          processor.addFilter(fogFilter);
        }

        if (isBloom) {
          // ensure any object is set to glow, e.g. car chassis:
          // chassis.getMaterial().setColor("GlowColor", ColorRGBA.Orange);

          BloomFilter bloom = new BloomFilter(GlowMode.Objects);
          processor.addFilter(bloom);
        }

        viewPort.addProcessor(processor);
      }
    }

    if (isShadow) { // TODO
      DirectionalLight sun = new DirectionalLight();
      Vector3f sunLightDirection = new Vector3f(-0.2f, -0.9f, 0.2f); // TODO get from DT files
      sun.setDirection(sunLightDirection.normalizeLocal());

      ArrayList<ViewPort> viewPortList = CameraFactory.getViewPortList();

      if (sim.getNumberOfScreens() > 1) {
        int shadowMapSize = 4096;
        if (viewPortList.size() > 1) shadowMapSize = 1024;

        for (ViewPort viewPort : viewPortList) {
          DirectionalLightShadowRenderer dlsr =
              new DirectionalLightShadowRenderer(assetManager, shadowMapSize, 1);
          dlsr.setLight(sun);
          dlsr.setEdgeFilteringMode(EdgeFilteringMode.PCFPOISSON);
          viewPort.addProcessor(dlsr);
        }

        shadowMapSize = 1024;
        DirectionalLightShadowRenderer dlsrBack =
            new DirectionalLightShadowRenderer(assetManager, shadowMapSize, 1);
        dlsrBack.setLight(sun);
        CameraFactory.getBackViewPort().addProcessor(dlsrBack);

        DirectionalLightShadowRenderer dlsrLeft =
            new DirectionalLightShadowRenderer(assetManager, shadowMapSize, 1);
        dlsrLeft.setLight(sun);
        CameraFactory.getLeftBackViewPort().addProcessor(dlsrLeft);

        DirectionalLightShadowRenderer dlsrRight =
            new DirectionalLightShadowRenderer(assetManager, shadowMapSize, 1);
        dlsrRight.setLight(sun);
        CameraFactory.getRightBackViewPort().addProcessor(dlsrRight);
      } else {
        // does not work with more than one screen
        for (ViewPort viewPort : viewPortList) {
          DirectionalLightShadowFilter dlsf =
              new DirectionalLightShadowFilter(assetManager, 1024, 3);
          dlsf.setLight(sun);
          dlsf.setLambda(1f);
          dlsf.setShadowIntensity(0.3f);
          dlsf.setEdgeFilteringMode(EdgeFilteringMode.PCFPOISSON);
          dlsf.setEnabled(true);

          FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
          fpp.addFilter(dlsf);

          viewPort.addProcessor(fpp);
        }
      }
    }
  }
Пример #3
0
 private Vector3f getAimDirection() {
   Vector2f mouse = inputManager.getCursorPosition();
   Vector3f playerPos = player.getLocalTranslation();
   Vector3f dif = new Vector3f(mouse.x - playerPos.x, mouse.y - playerPos.y, 0);
   return dif.normalizeLocal();
 }
  private static Mesh genTangentLines(Mesh mesh, float scale) {
    FloatBuffer vertexBuffer = (FloatBuffer) mesh.getBuffer(Type.Position).getData();
    FloatBuffer normalBuffer = (FloatBuffer) mesh.getBuffer(Type.Normal).getData();
    FloatBuffer tangentBuffer = (FloatBuffer) mesh.getBuffer(Type.Tangent).getData();

    FloatBuffer binormalBuffer = null;
    if (mesh.getBuffer(Type.Binormal) != null) {
      binormalBuffer = (FloatBuffer) mesh.getBuffer(Type.Binormal).getData();
    }

    ColorRGBA originColor = ColorRGBA.White;
    ColorRGBA tangentColor = ColorRGBA.Red;
    ColorRGBA binormalColor = ColorRGBA.Green;
    ColorRGBA normalColor = ColorRGBA.Blue;

    Mesh lineMesh = new Mesh();
    lineMesh.setMode(Mesh.Mode.Lines);

    Vector3f origin = new Vector3f();
    Vector3f point = new Vector3f();
    Vector3f tangent = new Vector3f();
    Vector3f normal = new Vector3f();

    IntBuffer lineIndex = BufferUtils.createIntBuffer(vertexBuffer.limit() / 3 * 6);
    FloatBuffer lineVertex = BufferUtils.createFloatBuffer(vertexBuffer.limit() * 4);
    FloatBuffer lineColor = BufferUtils.createFloatBuffer(vertexBuffer.limit() / 3 * 4 * 4);

    boolean hasParity = mesh.getBuffer(Type.Tangent).getNumComponents() == 4;
    float tangentW = 1;

    for (int i = 0; i < vertexBuffer.limit() / 3; i++) {
      populateFromBuffer(origin, vertexBuffer, i);
      populateFromBuffer(normal, normalBuffer, i);

      if (hasParity) {
        tangent.x = tangentBuffer.get(i * 4);
        tangent.y = tangentBuffer.get(i * 4 + 1);
        tangent.z = tangentBuffer.get(i * 4 + 2);
        tangentW = tangentBuffer.get(i * 4 + 3);
      } else {
        populateFromBuffer(tangent, tangentBuffer, i);
      }

      int index = i * 4;

      int id = i * 6;
      lineIndex.put(id, index);
      lineIndex.put(id + 1, index + 1);
      lineIndex.put(id + 2, index);
      lineIndex.put(id + 3, index + 2);
      lineIndex.put(id + 4, index);
      lineIndex.put(id + 5, index + 3);

      setInBuffer(origin, lineVertex, index);
      setInBuffer(originColor, lineColor, index);

      point.set(tangent);
      point.multLocal(scale);
      point.addLocal(origin);
      setInBuffer(point, lineVertex, index + 1);
      setInBuffer(tangentColor, lineColor, index + 1);

      // wvBinormal = cross(wvNormal, wvTangent) * -inTangent.w

      if (binormalBuffer == null) {
        normal.cross(tangent, point);
        point.multLocal(-tangentW);
        point.normalizeLocal();
      } else {
        populateFromBuffer(point, binormalBuffer, i);
      }

      point.multLocal(scale);
      point.addLocal(origin);
      setInBuffer(point, lineVertex, index + 2);
      setInBuffer(binormalColor, lineColor, index + 2);

      point.set(normal);
      point.multLocal(scale);
      point.addLocal(origin);
      setInBuffer(point, lineVertex, index + 3);
      setInBuffer(normalColor, lineColor, index + 3);
    }

    lineMesh.setBuffer(Type.Index, 1, lineIndex);
    lineMesh.setBuffer(Type.Position, 3, lineVertex);
    lineMesh.setBuffer(Type.Color, 4, lineColor);

    lineMesh.setStatic();
    // lineMesh.setInterleaved();
    return lineMesh;
  }
  private static void processTriangleData(
      Mesh mesh, List<VertexData> vertices, boolean approxTangent, boolean splitMirrored) {
    ArrayList<VertexInfo> vertexMap = linkVertices(mesh, splitMirrored);

    FloatBuffer tangents = BufferUtils.createFloatBuffer(vertices.size() * 4);

    ColorRGBA[] cols = null;
    if (debug) {
      cols = new ColorRGBA[vertices.size()];
    }

    Vector3f tangent = new Vector3f();
    Vector3f binormal = new Vector3f();
    // Vector3f normal = new Vector3f();
    Vector3f givenNormal = new Vector3f();

    Vector3f tangentUnit = new Vector3f();
    Vector3f binormalUnit = new Vector3f();

    for (int k = 0; k < vertexMap.size(); k++) {
      float wCoord = -1;

      VertexInfo vertexInfo = vertexMap.get(k);

      givenNormal.set(vertexInfo.normal);
      givenNormal.normalizeLocal();

      TriangleData firstTriangle = vertices.get(vertexInfo.indices.get(0)).triangles.get(0);

      // check tangent and binormal consistency
      tangent.set(firstTriangle.tangent);
      tangent.normalizeLocal();
      binormal.set(firstTriangle.binormal);
      binormal.normalizeLocal();

      for (int i : vertexInfo.indices) {
        ArrayList<TriangleData> triangles = vertices.get(i).triangles;

        for (int j = 0; j < triangles.size(); j++) {
          TriangleData triangleData = triangles.get(j);

          tangentUnit.set(triangleData.tangent);
          tangentUnit.normalizeLocal();
          if (tangent.dot(tangentUnit) < toleranceDot) {
            // log.log(Level.WARNING,
            // "Angle between tangents exceeds tolerance "
            // + "for vertex {0}.", i);
            break;
          }

          if (!approxTangent) {
            binormalUnit.set(triangleData.binormal);
            binormalUnit.normalizeLocal();
            if (binormal.dot(binormalUnit) < toleranceDot) {
              // log.log(Level.WARNING,
              // "Angle between binormals exceeds tolerance "
              // + "for vertex {0}.", i);
              break;
            }
          }
        }
      }

      // find average tangent
      tangent.set(0, 0, 0);
      binormal.set(0, 0, 0);

      int triangleCount = 0;
      for (int i : vertexInfo.indices) {
        ArrayList<TriangleData> triangles = vertices.get(i).triangles;
        triangleCount += triangles.size();
        if (debug) {
          cols[i] = ColorRGBA.White;
        }

        for (int j = 0; j < triangles.size(); j++) {
          TriangleData triangleData = triangles.get(j);
          tangent.addLocal(triangleData.tangent);
          binormal.addLocal(triangleData.binormal);
        }
      }

      int blameVertex = vertexInfo.indices.get(0);

      if (tangent.length() < ZERO_TOLERANCE) {
        log.log(Level.WARNING, "Shared tangent is zero for vertex {0}.", blameVertex);
        // attempt to fix from binormal
        if (binormal.length() >= ZERO_TOLERANCE) {
          binormal.cross(givenNormal, tangent);
          tangent.normalizeLocal();
        } // if all fails use the tangent from the first triangle
        else {
          tangent.set(firstTriangle.tangent);
        }
      } else {
        tangent.divideLocal(triangleCount);
      }

      tangentUnit.set(tangent);
      tangentUnit.normalizeLocal();
      if (Math.abs(Math.abs(tangentUnit.dot(givenNormal)) - 1) < ZERO_TOLERANCE) {
        log.log(Level.WARNING, "Normal and tangent are parallel for vertex {0}.", blameVertex);
      }

      if (!approxTangent) {
        if (binormal.length() < ZERO_TOLERANCE) {
          log.log(Level.WARNING, "Shared binormal is zero for vertex {0}.", blameVertex);
          // attempt to fix from tangent
          if (tangent.length() >= ZERO_TOLERANCE) {
            givenNormal.cross(tangent, binormal);
            binormal.normalizeLocal();
          } // if all fails use the binormal from the first triangle
          else {
            binormal.set(firstTriangle.binormal);
          }
        } else {
          binormal.divideLocal(triangleCount);
        }

        binormalUnit.set(binormal);
        binormalUnit.normalizeLocal();
        if (Math.abs(Math.abs(binormalUnit.dot(givenNormal)) - 1) < ZERO_TOLERANCE) {
          log.log(Level.WARNING, "Normal and binormal are parallel for vertex {0}.", blameVertex);
        }

        if (Math.abs(Math.abs(binormalUnit.dot(tangentUnit)) - 1) < ZERO_TOLERANCE) {
          log.log(Level.WARNING, "Tangent and binormal are parallel for vertex {0}.", blameVertex);
        }
      }

      Vector3f finalTangent = new Vector3f();
      Vector3f tmp = new Vector3f();
      for (int i : vertexInfo.indices) {
        if (approxTangent) {
          // Gram-Schmidt orthogonalize
          finalTangent
              .set(tangent)
              .subtractLocal(tmp.set(givenNormal).multLocal(givenNormal.dot(tangent)));
          finalTangent.normalizeLocal();

          wCoord = tmp.set(givenNormal).crossLocal(tangent).dot(binormal) < 0f ? -1f : 1f;

          tangents.put((i * 4), finalTangent.x);
          tangents.put((i * 4) + 1, finalTangent.y);
          tangents.put((i * 4) + 2, finalTangent.z);
          tangents.put((i * 4) + 3, wCoord);
        } else {
          tangents.put((i * 4), tangent.x);
          tangents.put((i * 4) + 1, tangent.y);
          tangents.put((i * 4) + 2, tangent.z);
          tangents.put((i * 4) + 3, wCoord);

          // setInBuffer(binormal, binormals, i);
        }
      }
    }
    tangents.limit(tangents.capacity());
    // If the model already had a tangent buffer, replace it with the regenerated one
    mesh.clearBuffer(Type.Tangent);
    mesh.setBuffer(Type.Tangent, 4, tangents);

    if (mesh.isAnimated()) {
      mesh.clearBuffer(Type.BindPoseNormal);
      mesh.clearBuffer(Type.BindPosePosition);
      mesh.clearBuffer(Type.BindPoseTangent);
      mesh.generateBindPose(true);
    }

    if (debug) {
      writeColorBuffer(vertices, cols, mesh);
    }
    mesh.updateBound();
    mesh.updateCounts();
  }