summaryrefslogtreecommitdiff
path: root/torus_kernel.cu
blob: 068859415dee07370175bb5d2f50814d5c5c2296 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#include <cuda_runtime.h>
#include <math.h>

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

extern "C" {
    void updateTorusVerticesCUDA(float* vertices, int numVertices, float time, float majorRadius, float minorRadius);
    void updateTorusColorsCUDA(float* colors, int numVertices, float time);
    int initCUDA();
    void cleanupCUDA();
}

// CUDA kernel for updating torus vertex positions
__global__ void torusVertexKernel(float* vertices, int numVertices, float time, float majorRadius, float minorRadius) {
    int idx = blockIdx.x * blockDim.x + threadIdx.x;
    
    if (idx < numVertices) {
        // Calculate vertex index for position data (6 floats per vertex: x,y,z,r,g,b)
        int vertexOffset = idx * 6;
        
        // Generate torus parameters
        int segments = (int)sqrt((float)numVertices);
        int rings = segments;
        
        int u = idx % segments;
        int v = idx / segments;
        
        if (v >= rings) return;
        
        float theta = 2.0f * M_PI * u / segments;
        float phi = 2.0f * M_PI * v / rings;
        
        // Add rotation animation
        theta += time * 0.5f;
        phi += time * 0.3f;
        
        // Calculate torus coordinates
        float cosTheta = cosf(theta);
        float sinTheta = sinf(theta);
        float cosPhi = cosf(phi);
        float sinPhi = sinf(phi);
        
        // Torus parametric equations
        float x = (majorRadius + minorRadius * cosPhi) * cosTheta;
        float y = (majorRadius + minorRadius * cosPhi) * sinTheta;
        float z = minorRadius * sinPhi;
        
        // Update vertex positions
        vertices[vertexOffset + 0] = x;
        vertices[vertexOffset + 1] = y;
        vertices[vertexOffset + 2] = z;
    }
}

// CUDA kernel for updating torus vertex colors with dynamic effects
__global__ void torusColorKernel(float* vertices, int numVertices, float time) {
    int idx = blockIdx.x * blockDim.x + threadIdx.x;
    
    if (idx < numVertices) {
        // Calculate vertex index for color data (6 floats per vertex: x,y,z,r,g,b)
        int vertexOffset = idx * 6;
        
        // Get vertex position
        float x = vertices[vertexOffset + 0];
        float y = vertices[vertexOffset + 1];
        float z = vertices[vertexOffset + 2];
        
        // Calculate distance from center for color effect
        float distance = sqrtf(x*x + y*y + z*z);
        
        // Create pulsating color effect based on distance and time
        float pulse = sinf(time * 2.0f + distance * 0.5f) * 0.5f + 0.5f;
        float wave = sinf(time + idx * 0.1f) * 0.3f + 0.7f;
        
        // Generate RGB colors
        float r = pulse * wave;
        float g = sinf(time * 1.5f + distance * 0.3f) * 0.4f + 0.6f;
        float b = cosf(time * 0.8f + distance * 0.7f) * 0.5f + 0.5f;
        
        // Update vertex colors
        vertices[vertexOffset + 3] = r;
        vertices[vertexOffset + 4] = g;
        vertices[vertexOffset + 5] = b;
    }
}

// Host function to update torus vertices
void updateTorusVerticesCUDA(float* vertices, int numVertices, float time, float majorRadius, float minorRadius) {
    float* d_vertices;
    size_t size = numVertices * 6 * sizeof(float); // 6 floats per vertex (x,y,z,r,g,b)
    
    // Allocate GPU memory
    cudaMalloc(&d_vertices, size);
    
    // Copy data to GPU
    cudaMemcpy(d_vertices, vertices, size, cudaMemcpyHostToDevice);
    
    // Launch kernel
    int threadsPerBlock = 256;
    int blocksPerGrid = (numVertices + threadsPerBlock - 1) / threadsPerBlock;
    
    torusVertexKernel<<<blocksPerGrid, threadsPerBlock>>>(d_vertices, numVertices, time, majorRadius, minorRadius);
    
    // Wait for kernel to complete
    cudaDeviceSynchronize();
    
    // Copy result back to host
    cudaMemcpy(vertices, d_vertices, size, cudaMemcpyDeviceToHost);
    
    // Free GPU memory
    cudaFree(d_vertices);
}

// Host function to update torus colors
void updateTorusColorsCUDA(float* vertices, int numVertices, float time) {
    float* d_vertices;
    size_t size = numVertices * 6 * sizeof(float); // 6 floats per vertex (x,y,z,r,g,b)
    
    // Allocate GPU memory
    cudaMalloc(&d_vertices, size);
    
    // Copy data to GPU
    cudaMemcpy(d_vertices, vertices, size, cudaMemcpyHostToDevice);
    
    // Launch kernel
    int threadsPerBlock = 256;
    int blocksPerGrid = (numVertices + threadsPerBlock - 1) / threadsPerBlock;
    
    torusColorKernel<<<blocksPerGrid, threadsPerBlock>>>(d_vertices, numVertices, time);
    
    // Wait for kernel to complete
    cudaDeviceSynchronize();
    
    // Copy result back to host
    cudaMemcpy(vertices, d_vertices, size, cudaMemcpyDeviceToHost);
    
    // Free GPU memory
    cudaFree(d_vertices);
}

// Initialize CUDA
int initCUDA() {
    int deviceCount;
    cudaError_t error = cudaGetDeviceCount(&deviceCount);
    
    if (error != cudaSuccess) {
        return 0; // CUDA not available
    }
    
    if (deviceCount == 0) {
        return 0; // No CUDA devices
    }
    
    // Set device 0 as default
    cudaSetDevice(0);
    return 1; // Success
}

// Cleanup CUDA resources
void cleanupCUDA() {
    cudaDeviceReset();
}