Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - AGP

Pages: [1] 2 3 ... 16
1
Support / GLB
« on: November 14, 2023, 09:39:01 am »
Egon, I've been stuck for six months on the very last step of importing a GLB model. When I try to animate the (otherwise perfect) model, it gets all messed up. I'm assuming the skeletal calculations are accurate, so could you please verify that this Keyframe class is accurately converting between the Glb coordinate system and jpct's?

Code: [Select]
class Keyframe {
    private double time;
    private Matrix transform;

    public Keyframe(double time, Matrix transform) {
        this.time = time;

        // Normalize the rotation component of the transform
        Quaternion rotation = new Quaternion(transform); // Extracts the rotational component
        rotation.normalize();
        Matrix rotationMatrix = rotation.toMatrix();

        // Adjust the transform to the jPCT coordinate system
        this.transform = adjustToJpctCoordinateSystem(rotationMatrix);

        // Extract and reset translation
        SimpleVector translation = extractTranslation(transform);
        resetTranslation(transform);

        // Extract, check, and apply uniform scale
        SimpleVector scale = extractScale(transform);
        if (!isUniformScale(scale)) {
            scale = new SimpleVector(1f, 1f, 1f); // (1, 1, 1) Use uniform scale if it's not uniform
        }
        Utilities.setScale(this.transform, scale);

        // Combine rotation and scale, reapply translation
        this.transform = combineTransforms(translation, this.transform, scale);
    }
    // Method to adjust a transformation matrix to jPCT's coordinate system
    private Matrix adjustToJpctCoordinateSystem(Matrix transform) {
        Matrix adjustedMatrix = new Matrix(transform);

        // Flip the Y-axis
        adjustedMatrix.set(1, 0, -adjustedMatrix.get(1, 0));
        adjustedMatrix.set(1, 1, -adjustedMatrix.get(1, 1));
        adjustedMatrix.set(1, 2, -adjustedMatrix.get(1, 2));
        // If there's translation on Y-axis, flip it as well
        adjustedMatrix.set(1, 3, -adjustedMatrix.get(1, 3));

        // Flip the Z-axis
        adjustedMatrix.set(2, 0, -adjustedMatrix.get(2, 0));
        adjustedMatrix.set(2, 1, -adjustedMatrix.get(2, 1));
        adjustedMatrix.set(2, 2, -adjustedMatrix.get(2, 2));
        // If there's translation on Z-axis, flip it as well
        adjustedMatrix.set(2, 3, -adjustedMatrix.get(2, 3));

        return adjustedMatrix;
    }
    public double getTime() {
       return time;
    }
    // Extract the translation component from a transformation matrix
    private SimpleVector extractTranslation(Matrix transform) {
        return new SimpleVector(transform.get(3, 0), transform.get(3, 1), transform.get(3, 2));
    }
    public Matrix getTransform() {
       return transform;
    }
    // Reset the translation component of a transformation matrix to zero
    private void resetTranslation(Matrix transform) {
        transform.set(3, 0, 0);
        transform.set(3, 1, 0);
        transform.set(3, 2, 0);
    }
    // Helper method to extract scale from a transformation matrix
    private SimpleVector extractScale(Matrix transform) {
       // Assuming the scale is represented by the length of the axis vectors in the matrix
       SimpleVector scaleX = new SimpleVector(transform.get(0, 0), transform.get(1, 0), transform.get(2, 0));
       SimpleVector scaleY = new SimpleVector(transform.get(0, 1), transform.get(1, 1), transform.get(2, 1));
       SimpleVector scaleZ = new SimpleVector(transform.get(0, 2), transform.get(1, 2), transform.get(2, 2));

       return new SimpleVector(scaleX.length(), scaleY.length(), scaleZ.length());
    }
    // Combine the translation, rotation, and scale into a single transformation matrix
    private Matrix combineTransforms(SimpleVector translation, Matrix rotation, SimpleVector scale) {
        Matrix scaleMatrix = new Matrix();
        scaleMatrix.setIdentity();
        Utilities.setScale(scaleMatrix, scale);

        Matrix combined = new Matrix();
        combined.setIdentity();
        combined.matMul(rotation);
        combined.matMul(scaleMatrix);
        combined.translate(translation);

        return combined;
    }

    // Helper method to check if the scale is uniform
    private boolean isUniformScale(SimpleVector scale) {
       // Check if all components are the same within a small epsilon to account for floating-point precision
       final float epsilon = 0.0001f;
       return Math.abs(scale.x - scale.y) < epsilon && Math.abs(scale.y - scale.z) < epsilon;
    }

    // Method to apply scale to a transformation matrix
    private void applyScaleToTransform(Matrix transform, SimpleVector scale) {
       // Reset the scale component of the matrix to 1
       for (int i = 0; i < 3; i++) {
          float length = new SimpleVector(transform.get(0, i), transform.get(1, i), transform.get(2, i)).length();
          if (length != 0) { // Avoid division by zero
              transform.set(0, i, transform.get(0, i) / length);
              transform.set(1, i, transform.get(1, i) / length);
              transform.set(2, i, transform.get(2, i) / length);
          }
       }

       // Create a scale matrix
       Matrix scaleMatrix = new Matrix();
       scaleMatrix.setIdentity(); // Start with an identity matrix
       scaleMatrix.set(0, 0, scale.x);
       scaleMatrix.set(1, 1, scale.y);
       scaleMatrix.set(2, 2, scale.z);

       // Apply scale by multiplying the existing transform with the scale matrix
       transform.matMul(scaleMatrix);
    }
}

2
Support / Sorting
« on: August 25, 2023, 09:21:05 pm »
This is more of a programming question than a jpct question. But since it's for sorting the bones I'm importing off of GLB in jpct, this is as good a place as any to ask it. So I'm writing a 2d skeleton viewer. Each bone knows its parent, and that's about all the information I have on them. Since I know it's a bipedal skeleton generated with Mixamo, I know the skeleton's shape. All I need is to sort the bones and draw them out. I'm doing this to verify that the parent/child relationship is accurate. What's the best way to run through the 2d List<Bone> and produce a sorted array? Now that I asked the question I realize that it's not a linear list, it's a tree. Any ideas?

3
Support / Programming Question (Bitwise OR)
« on: December 28, 2020, 09:08:48 pm »
Does it make any difference to bitwise OR 4278190080u and -16777216 (for alpha values) if the result will nevertheless be an unsigned int (I apologize in advance for the C#)?

4
Bones / BonesIO Question
« on: July 10, 2020, 06:56:38 am »
How is it that when you load your SkinClipSequences from a bones file instead of each SkinClip having identical Skeletons they each share the same instance of a Skeleton?

6
Support / Cpct?
« on: September 16, 2019, 06:45:59 pm »
Now that even Excelsior Jet has been made extinct, how would you feel about making a c# version of jpct? At least the OpenGL bits would be better.

7
Support / Mouse-Walking on a Simple Plane
« on: October 23, 2018, 06:59:02 am »
I've made three dozen attempts. I have had success on a plane with multiple polygons, but I'd like to make it work on a large plane with only two triangles. My best (unsuccesful) attempt:

Code: [Select]
     public void mouseClicked(MouseEvent e) {
        moveByMouse(e.getX(), e.getY());
     }
     private void moveByMouse(int mouseX, int mouseY) {//WALKBYMOUSE; CALLED ONCE TO SETUP THE WALK DIRECTION
SimpleVector ray = Interact2D.reproject2D3DWS(camera, buffer, mouseX, mouseY);
if (ray != null) {
     SimpleVector norm = ray.normalize();

     float f = theWorld.calcMinDistance(camera.getPosition(), norm, 1000);
     if (1==1/*f != Object3D.COLLISION_NONE*/) {
SimpleVector offset = new SimpleVector(norm);
norm.scalarMul(f);
norm = norm.calcSub(offset);
origin = hero.getRoot().getTransformedCenter();
SimpleVector destination = new SimpleVector(norm);
destination.x += camera.getPosition().x;
destination.z += camera.getPosition().z;
destination.y = origin.y; // Make y the same as for the hero to avoid moving up/down.
hero.getRoot().setRotationMatrix(destination.calcSub(origin).getRotationMatrix());
this.destination = new SimpleVector(destination);
     }
}
go = true;
     }

8
Support / Orthographic Camera
« on: September 26, 2018, 05:35:15 am »
Is it at all possible to extend the Camera instance to create an orthographic camera?

9
Bones / getBindPose() is Late
« on: July 07, 2018, 08:32:52 pm »
Can I forcefully update it in order to have an item keep up with my character's hand?

10
Support / Asymmetrical Scaling
« on: June 21, 2018, 06:24:00 am »
I'm trying to create a flickering glow. To that end, I wrote the following thickening method in a vertex controller. The problem happens when the base object, from which the glow object is created, is rotated because the glow appears to be modified in worldspace as opposed to in objectspace. What should I do to calculate the x/z distortion in objectspace?

Code: [Select]
     public void thicken(final float deltaTime) {
SimpleVector[] vertices = this.getSourceMesh();
SimpleVector[] destination = this.getDestinationMesh();
for (int i = 0; i < vertices.length; i++) {
     SimpleVector v = vertices[i];
     v.x *= (1f+deltaTime);
     v.z *= (1f+deltaTime);
     destination[i] = v;
}
this.updateMesh();
     }

11
...of keyframes? You should put that in the docs.

For now, I'm going to assume that it is. ; )

12
Projects / 3ds Max OBJ Animation
« on: June 04, 2018, 06:43:14 pm »
I called this MergeAndSerialize because it first exports each frame of your character's animation as an OBJ (I did not write the included MaxScript), then it creates a single serialized file with a jpct animation. Hope it helps someone else: https://www.dropbox.com/s/1aumqalafjmietb/MergeAndSerialize.rar?dl=0

13
Support / Merging OBJ Frames
« on: May 30, 2018, 11:49:33 am »
I'm about to post a little project for anyone unable to export either Ogre or MD2-animated versions of their models but are able to export OBJ or 3ds. I found a little maxscript that automates the exporting of the frames, and I'm writing the jpct end of it. Problem is I keep getting a size difference of 1 between frame 1 and all the rest ("ERROR: The sizes of the Animation's Meshes (26938) and the object's Mesh (26937) don't match!").

Code: [Select]
/**
Written by AGP (BR) on May, 2018
*/
import java.io.*;
import com.threed.jpct.*;

public class MergeAndSerialize {
     public static void main(String[] args) {
Logger.setLogLevel(Logger.LL_ERRORS_AND_WARNINGS);
float SCALE = 3.6f;
String animationName = "Idle";
if (args == null || args.length < 1) {
     System.err.println("USAGE: java MergeAndSerialize [baseFileName] where the file name needs no extension.\nFOR OBJs ONLY.");
     return;
}
String fileName = args[0].trim();
FilenameFilter filter = new FilenameFilter() {
     public boolean accept(File dir, String name) {
return (name.startsWith(fileName) && name.toLowerCase().endsWith(".obj"));
     }
};
String[] frames = new File("./").list(filter);
Object3D model = Object3D.mergeAll(Loader.loadOBJ(frames[0], frames[0].substring(0, frames[0].lastIndexOf("."))+".mtl", SCALE));
Animation animation = new Animation(frames.length);
animation.createSubSequence(animationName);
System.out.println("\n\n\nFrames length: "+frames.length);
model.build();
for (int i = 1; i < frames.length; i++) {
System.out.println("I: "+i);
     Object3D frame = Object3D.mergeAll(Loader.loadOBJ(frames[i], frames[i].substring(0, frames[i].lastIndexOf("."))+".mtl", SCALE));
     frame.build();
     Mesh mesh = frame.getMesh();
     animation.addKeyFrame(mesh);
}
model.setAnimationSequence(animation);
try {
     new DeSerializer().serialize(model, new java.io.FileOutputStream(fileName.substring(0, fileName.lastIndexOf("."))+".serialized"), false);
}
catch (java.io.IOException ex) {System.err.println("Trouble saving file: "+ex.getMessage());}
java.awt.Toolkit.getDefaultToolkit().beep();
     }
}

14
Bones / Parsing SkinClipSequence
« on: May 04, 2018, 10:51:28 pm »
Since EasyOgreExporter exports all clips into a single animation, I'm forced to write a parser. How, then, might I split a SkinClipSequence of one SkinClip into a SkinClipSequence of two or more?

15
Support / Now this looks like a Java 10 Thing
« on: April 29, 2018, 11:45:19 pm »
I was working a while ago on this fire particle system. I don't remember the rendering getting clipped like this.

Code: [Select]
this.setSize(buffer.getOutputWidth(), buffer.getOutputHeight());
this.add(canvas, BorderLayout.CENTER);
this.setVisible(true);
...
     buffer.clear(Color.blue);
     flameManager.update(deltaTime);
     smokeManager.update(deltaTime);
     skyBox.render(theWorld, buffer);
     if (!doShadows()) {
theWorld.renderScene(buffer);
theWorld.draw(buffer);
     }
     buffer.update();
     buffer.displayGLOnly();
     canvas.repaint();

https://www.dropbox.com/s/jpkrg93a6vi03db/ClippingThing.jpg?dl=0

Pages: [1] 2 3 ... 16